Uncategorized — May 30, 2016 at 4:07 am

Tự tạo widget – cách sử dụng widget hiệu quả

by

Khái niệm về cách tạo widget

Xem trước: Widgets API – WordPress Codex

Trong WordPress đã có sẵn một class tên là WP_Widget, trong class này có những method (phương thức), nghĩa là bạn phải viết các phương thức này theo chuẩn của nó, không được thiếu mà cũng không có thừa và phải viết đúng tên phương thức.

Trong class WP_Widget có tổng cộng 3 phương thức bắt buộc, bao gồm:

__construct: Phương thức khởi tạo này sẽ có nhiệm vụ khai báo tên widget, mô tả widget.

form: Phương thức này sẽ hỗ trợ bạn tạo các form nhập liệu bên trong một widget, xem hình dưới.

Mẫu form trong widget
Mẫu form trong widget

update: Phương thức này sẽ hỗ trợ bạn lưu dữ liệu mà người dùng đã nhập vào các form mà bạn đã tạo bằng phương thức form.

widget: Phương thức này sẽ giúp bạn gọi dữ liệu và hiển thị ra ngoài website khi bạn gắn cái widget này lên.

Ngoài ra, trong class này bạn cũng phải khai báo một phương thức nào đó do bạn tùy chọn để thiết lập tên và mô tả của widget. Một số thì dùng phương thức __construct() và một số thì tự tạo một phương thức khác. Ở đây mình chọn cách tự tạo phương thức vì nó dễ nhìn và dẽ hiểu hơn.

Chuẩn bị

Bạn có thể thực hành bài này bằng cách viết code vào file functions.php trong theme, nhưng tốt hơn hết là bạn tạo một plugin đi. Tạo một file với tên nào đó ở thư mục wp-content/plugins và viết đoạn này ở đầu file

01
02
03
04
05
06
07
08
09
<?php
/*
Plugin Name: Test Widget
Plugin URI: http://thachpham.com
Description: Thực hành tạo widget item.
Author: Thach Pham
Version: 1.0
Author URI: http://google.com
*/

Khỏi cần nói cũng biết, các code thực hành trong bài này bạn viết vào bên dưới dòng trên nhé.

6 bước tạo widget item

Bước 1. Khởi tạo widget

Đầu tiên, để khởi tạo một widget thì ta có 4 đoạn sau để khởi tạo.

01
02
03
04
05
06
07
/*
 * Khởi tạo widget item
 */
add_action( 'widgets_init', 'create_thachpham_widget' );
function create_thachpham_widget() {
        register_widget('Thachpham_Widget');
}

Trong đó, Thachpham_Widget là class mà chút nữa chúng ta sẽ tạo.

Bước 2. Tạo class và cấu trúc các phương thức

Như mình đã nói, bây giờ chúng ta sẽ tạo một class mang tên Thachpham_Widget kế thừa cái class WP_Widgetmặc định, trong đó sẽ có 3 phương thức bắt buộc là form, update, widget và kèm theo một phương thức để đặt tên cho widget. Ta có như sau.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/**
 * Tạo class Thachpham_Widget
 */
class Thachpham_Widget extends WP_Widget {
        /**
         * Thiết lập widget: đặt tên, base ID
         */
        function __construct() {
        }
        /**
         * Tạo form option cho widget
         */
        function form( $instance ) {
        }
        /**
         * save widget form
         */
        function update( $new_instance, $old_instance ) {
        }
        /**
         * Show widget
         */
        function widget( $args, $instance ) {
        }
}

Mình đã có comment rõ ràng trong đó rồi nhé.

Bây giờ bạn thử lưu lại xem và có thấy phần Appearance -> Widget của mình xuất hiện thêm một cục không ghi tên như hình dưới không, nếu có thì bạn đã làm đúng.

create_widget_form_basic

Bước 3: Đặt tên cho widget (__construct)

Ở bước này, chúng ta sẽ làm việc trong phương thức __construct() nhé. Bây giờ ta sẽ tạo cho nó một cái mảng bao gồm các giá trị như sau:

01
02
03
04
05
06
07
08
09
10
function __construct() {
    parent::__construct (
      'thachpham_widget', // id của widget
      'ThachPham Widget', // tên của widget
      array(
          'description' => 'Mô tả của widget' // mô tả
      )
    );
}

Trong đó, các thông tin mình đã có ghi chú thích vào trong đó rồi nhé.

Bây giờ chúng ta gắn cái biến này vào đoạn sau.

Bây giờ lưu lại và vào Appearance -> Widget tìm cái tên widget mà bạn vừa tạo ra nào.

Title và Description của widget
Title và Description của widget

Bước 4: Tạo form cho widget (form)

Bất kỳ widget nào cũng nên có một form nhập liệu để khách nhập những tùy chọn hay giá trị nào đó vào đây, bạn có thể sử dụng dropdown, checkbox,…nhưng ở đây mình sẽ dùng input loại text cho đơn giản.

Trong bước này ta sẽ làm việc trong phương thức form() nhé. Phương thức này ta có một biến là $instance.

Đầu tiên ra khai báo một mảng như sau:

01
02
03
04
//Biến tạo các giá trị mặc định trong form
$default = array(
        'title' => 'Tên của bạn'
);

Mảng này có vai trò thiết lập các giá trị mặc định cho từng form. Ví dụ bạn có một form tên title thì giá trị mặc định của nó nếu người dùng chưa nhập vào là Tên của bạn, nếu bạn có nhiều form thì làm thêm nhiều giá trị trong mảng này.

Kế tiếp là viết thêm đoạn này

01
02
//Gộp các giá trị trong mảng $default vào biến $instance để nó trở thành các giá trị mặc định
$instance = wp_parse_args( (array) $instance, $default);

Đoạn này bạn hiểu đơn giản là nó sẽ lôi toàn bộ giá trị mảng của biến $default sang biến $instance.

Tiếp tục viết thêm một đoạn này

01
02
//Tạo biến riêng cho giá trị mặc định trong mảng $default
$title = esc_attr( $instance['title'] );

Đơn giản là ta đưa $instance['title'] vào một biến cho dễ nhớ, dễ viết. Trong đó, $title là biến sẽ chứa giá trị của tiêu đề lấy từ khóa title trong mảng $instance.

Và cuối cùng là đoạn quan trọng nhất, chúng ta sẽ tạo ra một cái trường nhập liệu và nó sẽ hiển thị giá trị là biến $title. Điều này có nghĩa là nếu như sau này chúng ta truyền giá trị mới cho $title thì nó cũng sẽ hiển thị ra.

01
02
//Hiển thị form trong option của widget
echo "Nhập tiêu đề <input class="widefat" type="text" name="'".$this->get_field_name('title')."' value='".$title."' />";

Bây giờ bạn lưu lại và mở widget ra sẽ thấy có một form và thuộc tính mặc định như sau:

create_widget_form_new

Bạn có thể thử bằng cách nhập một cái gì đó vào form rồi ấn Save lại thì thấy nó không được lưu lại mà toàn trả về giá trị mặc định. Đó là do chúng ta chưa viết code cho phương thức update.

Toàn bộ code trong bước này:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
/**
 * Tạo form option cho widget
 */
function form( $instance ) {
        parent::form( $instance );
        //Biến tạo các giá trị mặc định trong form
        $default = array(
                'title' => 'Tiêu đề widget'
        );
        //Gộp các giá trị trong mảng $default vào biến $instance để nó trở thành các giá trị mặc định
        $instance = wp_parse_args( (array) $instance, $default);
        //Tạo biến riêng cho giá trị mặc định trong mảng $default
        $title = esc_attr( $instance['title'] );
        //Hiển thị form trong option của widget
        echo "Nhập tiêu đề <input class="widefat" type="text" name="'".$this->get_field_name('title')."' value='".$title."' />";
}

Bước 5. Lưu giá trị khi nhập form (update)

Bước này ta sẽ làm việc với phương thức update(). Trong phương thức này ta có hai tham số chính là$new_instance được dùng để lưu những giá trị sau khi ấn nút Save và $old_instance là giá trị cũ trong cơ sở dữ liệu. Sau khi dữ liệu nhập vào được lưu thì ta sẽ return nó ra.

Ta có

01
02
03
$instance = $old_instance;
$instance['title'] = strip_tags($new_instance['title']);
return $instance;

Nghĩa là ở trên mình sẽ lưu lại các giá trị trong form nhập tiêu đề. Hàm strip_tags() được sử dụng để cho cái form không thực thi PHP và HTML.

Toàn bộ code sẽ là

01
02
03
04
05
06
07
08
09
10
11
/**
 * save widget form
 */
function update( $new_instance, $old_instance ) {
        parent::update( $new_instance, $old_instance );
        $instance = $old_instance;
        $instance['title'] = strip_tags($new_instance['title']);
        return $instance;
}

Bây giờ bạn thử viết gì vào form rồi lưu lại, các giá trị sẽ lưu lại.

Bước 6. Xuất dữ liệu hiển thị ra ngoài

Ta đã tạo form, rồi lưu dữ liệu trong form vào. Vậy làm thế nào để có thể xuất nó hiển thị ra ngoài đây? Trong bước này ta sẽ làm việc với phương thức widget để hiển thị nó ra ngoài.

Trong phương thức này ta có 2 tham số là $args để khai báo các giá trị thuộc tính của một widget (title, các thẻ HTML,..) và $instance là giá trị mà khách đã nhập vào form trong widget.

Nếu bạn muốn sử dụng lại các thuộc tính bên trong widget thì tốt hơn hết bạn nên extract cái array trong widget ra thành từng biến riêng. Ta có:

01
extract( $args );

Sau đó, để hiển thị giá trị của một form thì ta chỉ cần echo $instance['form_name']. Như ví dụ này thì ta có$instance['title'].

Nhưng do cái form này là ta nhập tiêu đề của widget nên bạn nên thêm filter hook cho nó để đúng chuẩn trong WordPress.

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

Nhưng mà đợi đã, ta không thể viết chay như vậy, tại sao? Bởi vì trong Widget nó có những cái hook như hook vị trí trước widget (before widget), sau widget (after widget) và quan trọng là nếu bạn hiển thị cái tiêu đề widget như thế kia thì không được do ta thiếu hook $before_widget$after_widget, hai biến này là hook in ra thẻ heading để tiêu đề widget hiển thị đúng “phong cách”.

Như vậy, ta tạm đưa đoạn apply_filters() vào trong một biến:

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

Sau đó ta viết như sau:

01
02
03
04
05
06
07
08
09
10
11
12
echo $before_widget;
//In tiêu đề widget
echo $before_title.$title.$after_title;
// Nội dung trong widget
echo "ABC XYZ";
// Kết thúc nội dung trong widget
echo $after_widget;

Như vậy, khi in widget ra bạn bắt buộc phải echo thêm biến $before_widget$after_widget để bọc nội dung lại, không có nó không có hiển thị đâu nhé.

Và kết quả là:

create_widget_show

Toàn bộ code trong bước này là:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
function widget( $args, $instance ) {
        extract( $args );
        $title = apply_filters( 'widget_title', $instance['title'] );
        echo $before_widget;
        //In tiêu đề widget
        echo $before_title.$title.$after_title;
        // Nội dung trong widget
        echo "ABC XYZ";
        // Kết thúc nội dung trong widget
        echo $after_widget;
}

Quá dễ phải không nào.

Tải source code

Thực hành – Tạo widget hiển thị bài ngẫu nhiên

Bạn đã biết cách tạo một widget là như thế nào rồi, vậy thì tại sao lại không thực hành nó ngay? Ở đây mình sẽ thực hành cách tạo một widget hiển thị bài viết ngẫu nhiên với tùy chọn cho phép khách nhập số lượng bài cần hiển thị bằng việc ứng dụng khái niệm Loop và Query.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
</pre>
<pre>class Random_Post extends WP_Widget {
    function __construct() {
        parent::__construct(
            'random_post',
            'Bài ngẫu nhiên',
            array( 'description'  =>  'Widget hiển thị bài viết ngẫu nhiên' )
        );
    }
    function form( $instance ) {
        $default = array(
            'title' => 'Tiêu đề widget',
            'post_number' => 10
        );
        $instance = wp_parse_args( (array) $instance, $default );
        $title = esc_attr($instance['title']);
        $post_number = esc_attr($instance['post_number']);
        echo '<p>Nhập tiêu đề <input type="text" class="widefat" name="'.$this->get_field_name('title').'" value="'.$title.'"/></p>';
        echo '<p>Số lượng bài viết hiển thị <input type="number" class="widefat" name="'.$this->get_field_name('post_number').'" value="'.$post_number.'" placeholder="'.$post_number.'" max="30" /></p>';
    }
    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.$title.$after_title;
        $random_query = new WP_Query('posts_per_page='.$post_number.'&orderby=rand');
        if ($random_query->have_posts()):
            echo "<ol>";
            while( $random_query->have_posts() ) :
                $random_query->the_post(); ?>
                <li><a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>"><?php the_title(); ?></a></li>
            <?php endwhile;
            echo "</ol>";
        endif;
        echo $after_widget;
    }
}
add_action( 'widgets_init', 'create_randompost_widget' );
function create_randompost_widget() {
    register_widget('Random_Post');
}</pre>
<pre>

Leave a Comment

Your email address will not be published. Required fields are marked *