Các bước tự lập trình Widget cho WordPress

Các bước tự lập trình Widget cho WordPress

Widget trong WordPress là thành phần rất quan trọng trong website sử dụng WordPress. Nó thường được sử dụng để hiển thị các thành phần ở sidebar, footer. Tôi đã có bài viết hướng dẫn cách tạo phân vùng Widget WordPress. Tuy nhiên, đây chỉ là cách tạo khu vực hiển thị Widget.

Bạn vẫn phải sử dụng các Widget có sẵn của WordPress, hoặc các Widget được sinh ra khi bạn cài các plugin.

Trong một số trường hợp, các Widget có sẵn không đáp ứng được yêu cầu của dự án. Lúc này bạn cần phải tự lập trình riêng Widget để đáp ứng yêu cầu.

Trong bài viết này, tôi sẽ hướng dẫn bạn các bước tự lập trình Widget cho WordPress.

Các đoạn code của Widget tôi sẽ viết ở 1 file riêng, sau đó require_once vào file functions.php của theme bạn đang dùng.

Giả sử tôi muốn viết Widget “Hiển thị bài viết ngẫu nhiên“, tôi sẽ tạo file random_posts_widget.php

Sau đó, bạn chèn đoạn code sau vào đầu file functions.php

require_once 'random_posts_widget.php';

Bắt đầu viết Widget cho WordPress

Để lập trình Widget cho WordPress, chúng ta cần viết class kế thừa từ classs WP_Widget

Cấu trúc của 1 widget sẽ có 4 phương thức sau:

  • widget: Giúp hiển thị nội dung Widget
  • form: Form option trong trang admin
  • update: Lưu giá trị option khi cập nhật
  • __construct: Khai báo các giá trị mặc định. Ví dụ: id widget, tên widget,…

Phương thức __construct

<?php
function __construct() {
        parent::__construct(
            'my-text',  // ID của Widget
            'My Text',   // Tên của Widget
            array( 'description'  =>  'Mô tả Widget')
        );
    }
 ?>

Trong phương thức này bạn sẽ cập nhật id và tên Widget bạn cần tạo. Phần mô tả Widget bạn có thể nhập hoặc không nhập.

Phương thức form

Phương thức này sẽ tạo ra form option trong khu vực quản trị. Như các Widget mặc định của WordPress.

<?php 
function form( $instance ) {
 		
 	$default = array(
 		'title' => 'Bài viết ngẫu nhiên',
 		'post_number' => 5
 	);

 	$instance = wp_parse_args( (array) $instance, $default );

        $title = $instance['title'];
        $post_number = $instance['post_number'];

        ?>
        <p>
        <label for="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>">Tiêu đề</label>
            <input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'title' ) ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>">
        </p>
        <p>
            <label for="<?php echo esc_attr( $this->get_field_id( 'post_number' ) ); ?>">Số lượng bài viết</label>
            <input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'post_number' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'post_number' ) ); ?>" type="number" value="<?php echo esc_attr( $post_number ); ?>">
        </p>
        <?php 
}
?>

Trong đoạn code trên, tôi tạo 2 field: Tiêu đề, số lượng bài viết tương ứng với name của từng field là titlepost_number

Tôi có khai báo mảng $default để lưu trữ giá trị mặc định của các field. Bạn có thể không cần khai báo cũng được. Nếu bạn không khai báo thì bỏ dòng $instance = wp_parse_args( (array) $instance, $default );

Phương thức update

Phương thức giúp lưu trữ các giá trị của phương thức form. Cùng tham khảo code sau:

<?php
function update( $new_instance, $old_instance ) {
        $instance = $old_instance;
        $instance['title'] = strip_tags($new_instance['title']);
        $instance['post_number'] = strip_tags($new_instance['post_number']);
        return $instance;
}
?>

Phương thức này đơn giản, chỉ cần gán dữ liệu cũ bằng dữ liệu mới là được.

Phương thức widget

Đây là phương thức quan trọng nhất của Widget, nó có tác dụng hiển thị nội dung Widget cho người dùng.

<?php
function widget( $args, $instance ) {
        extract($args);
        
        $title = apply_filters( 'widget_title', $instance['title'] );
        
        $post_number = $instance['post_number'];

        echo $before_widget;

        echo $before_title.$title.$after_title;

        $post_query=new WP_Query(array(
            "post_type"=>"post",
            "posts_per_page"=>$post_number,
            "orderby"=>'rand',
        ));

        if ($post_query->have_posts()):
            ?>
            <div class="bg-dark" style="margin-bottom: 15px;">
                <div class="wrap-content-sidebar bg-white">

                    <div class="contennt-article-sidebar">
                        <?php
                            while ($post_query->have_posts()):
                                $post_query->the_post();
                                if ($post_query->current_post<=2):
                        ?>
                        <div class="media custom-media">
                            <div class="media-left">
                                <a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>">
                                    <?php the_post_thumbnail('thumbnail', array('class'=>'media-object')); ?>
                                </a>
                            </div> <!-- END /. media-left -->
                            <div class="media-body">
                                <h3 class="media-heading"><a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>"><?php the_title(); ?></a></h3>
                            </div> <!-- END /. media-body -->
                        </div> <!-- END /.media .custom-media -->
                            <?php else: ?>

                        <h3 class="h5"><a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>"><?php the_title(); ?></a></h3>
                        <hr/>

                        <?php endif; endwhile; wp_reset_query(); ?>

                    </div> <!-- END /.contennt-article-sidebar -->

                </div> <!-- END /.wrap-content-sidebar -->
            </div> <!-- END /.bg-dark -->
           </div>
            <?php
        endif;
        echo $after_widget;
    }
 ?>

Trong đoạn code trên, bạn để ý có các biến $title, $before_title, $after_title, $before_widget, $after_widget

Đó là các thành phần của Widget mà tôi đã nói ở bài tạo phân vùng Widget. Khi gọi các biến này ra, nó sẽ hiển thị HTML mà đã khai báo trong hàm register_sidebar()

Biến $title chúng ta sẽ gọi qua filter widget_title

Tổng hợp các phương thức

<?php
class Random_post_widget extends WP_Widget{
    function __construct() {
        parent::__construct(
            'my-text',  // ID của Widget
            'My Text',   // Tên của Widget
            array( 'description'  =>  'Mô tả Widget')
        );
    }

    function form( $instance ) {

        $default = array(
            'title' => 'Bài viết ngẫu nhiên',
            'post_number' => 5
        );

        $instance = wp_parse_args( (array) $instance, $default );

        $title = $instance['title'];
        $post_number = $instance['post_number'];

        ?>
        <p>
            <label for="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>">Tiêu đề</label>
            <input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'title' ) ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>">
        </p>
        <p>
            <label for="<?php echo esc_attr( $this->get_field_id( 'post_number' ) ); ?>">Số lượng bài viết</label>
            <input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'post_number' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'post_number' ) ); ?>" type="number" value="<?php echo esc_attr( $post_number ); ?>">
        </p>
        <?php
    }

    function update( $new_instance, $old_instance ) {
        $instance = $old_instance;
        $instance['title'] = strip_tags($new_instance['title']);
        $instance['post_number'] = strip_tags($new_instance['post_number']);
        return $instance;
    }

    function widget( $args, $instance ) {
        extract($args);

        $title = apply_filters( 'widget_title', $instance['title'] );

        $post_number = $instance['post_number'];

        echo $before_widget;

        echo $before_title.$instance['title'].$after_title;

        $post_query=new WP_Query(array(
            "post_type"=>"post",
            "posts_per_page"=>$post_number,
            "orderby"=>'rand',
        ));

        if ($post_query->have_posts()):
            ?>
            <div class="bg-dark" style="margin-bottom: 15px;">
                <div class="wrap-content-sidebar bg-white">

                    <div class="contennt-article-sidebar">
                        <?php
                        while ($post_query->have_posts()):
                            $post_query->the_post();
                            if ($post_query->current_post<=2):
                                ?>
                                <div class="media custom-media">
                                    <div class="media-left">
                                        <a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>">
                                            <?php the_post_thumbnail('thumbnail', array('class'=>'media-object')); ?>
                                        </a>
                                    </div> <!-- END /. media-left -->
                                    <div class="media-body">
                                        <h3 class="media-heading"><a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>"><?php the_title(); ?></a></h3>
                                    </div> <!-- END /. media-body -->
                                </div> <!-- END /.media .custom-media -->
                            <?php else: ?>

                                <h3 class="h5"><a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>"><?php the_title(); ?></a></h3>
                                <hr/>

                            <?php endif; endwhile; wp_reset_query(); ?>

                    </div> <!-- END /.contennt-article-sidebar -->

                </div> <!-- END /.wrap-content-sidebar -->
            </div> <!-- END /.bg-dark -->
            </div>
            <?php
        endif;
        echo $after_widget;
    }
}

add_action( 'widgets_init', function() {
    register_widget( 'Random_post_widget' );
});
 ?>

Ở đoạn code trên, tôi có tạo ra 1 class Random_post_widget kế thừa từ class WP_Widget

Cuối cùng, tôi cần phải đăng ký class vừa tạo vào hook widgets_init thông qua hàm register_widget()

Kết luận

Trên đây, tôi có hướng dẫn bạn các bước lập trình Widget cho WordPress. Từ bài viết này, tôi hy vọng bạn có thể tự lập trình được Widget của riêng mình. Còn Widget có nhiều tính năng hay không dựa vào kỹ năng của các bạn.

[Total: 2   Average: 5/5]

Hoàng An

Tôi không phải là 1 chuyên gia lập trình, cũng không phải là 1 chuyên gia SEO. Với niềm đam mê với CNTT, tôi có thể biến ý tưởng thành sản phẩm và thích chia sẻ kiến thức cho người khác. Nếu có duyên, mời bạn đến với khoá học của tôi

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *