Trang chủ WordpressWordpress Development Hướng dẫn tự tạo Widget

Hướng dẫn tự tạo Widget

bởi Thạch Phạm
27 bình luận 7647 views
Khuyến mãi hosting

https://www.youtube.com/watch?v=trG0y5AIE04&feature=youtu.be

Widget trong WordPress ai cũng hiểu nó là một block nội dung được đặt trong một khu vực được chỉ định, khu vực này ta thường gọi là Widget Area hoặc Sidebar. Ngoài các widget có sẵn như Recent Posts, Recent Comments,…thì nếu muốn có thêm widget bạn phải cài plugin hoặc một số theme cũng cho bạn thêm vài widget tùy chọn.

Vậy làm thế nào để hiểu quy trình tạo một widget ra sao? Ở bài này mình sẽ phân tích kỹ lưỡng cách tạo một widget là như thế nào, nhưng dĩ nhiên là bạn cần có sẵn kiến thức PHP ví dụ như bạn nên hiểu Class và đối tượng trong PHP là thế nào.

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

<?php
/*
Plugin Name: Test Widget
Plugin URI: https://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.

/*
 * 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_Widget mặ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.

/**
 * 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:

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:

//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

//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

//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.

//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:

	/**
	 * 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ó

$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à

	/**
	 * 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ó:

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.

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:

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

Sau đó ta viết như sau:

		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à:

	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.

</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>

Lời kết

Như vậy là bạn đã biết qua cách tạo một widget là như thế nào rồi đúng không nào? Thoạt nhìn code có thể bạn nghĩ nó khó nhưng thật ra nó chẳng có gì khó cả và mình tin là bạn có thể tự làm được sau khi đọc kỹ bài của mình.

Nếu có gì thắc mắc, hãy comment phía dưới nhé.

Tham khảo: Cách tạo widget nhanh với scbFramework – WordPressKite

27 bình luận

Có thể bạn quan tâm

0 0 vote
Article Rating
guest
27 Comments
mới nhất
cũ nhất đánh giá nhiều
Inline Feedbacks
View all comments
Thi Ba

Vui lòng cho hỏi một plugin nào có thể giúp hiển thị BẤT CỨ file nào hoặc Folder nào của WordPress dưới dạng Tree View tại Front End homepage. Xin cám ơn.

[…] như làm việc với các code tạo widget hay tạo shortcode, để tạo một custom post type bạn có thể viết vào file […]

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

[…] 1 số widget cần thiết. Nếu muốn tùy chỉnh 1 widget riêng, bạn có thể tham khảo cách tạo widget của Thach […]

[…] như làm việc với các code tạo widget hay tạo shortcode, để tạo một custom post type bạn có thể viết vào file […]

[…] như làm việc với các code tạo widget hay tạo shortcode, để tạo một custom post type bạn có thể viết vào file […]

[…] Hướng dẫn tạo widget trong 6 bước […]

[…] Nếu bạn cần tạo widget trong WordPress thì sẽ cần tạo một lớp khác kế thừa lại lớp này. Rất may là mình đã có bài hướng dẫn kèm video rất chi tiết tại đây. […]

Ngoc

A ơi e mún tạo 2 mục wiget nằm bên phải của trang, bài viết phổ biến vs bài viết được xem nhìu nhất thì phải làm như bên trên lun hả a. E dùng themes reviewpro của Junke nó k hỗ trợ mấy cái wiget ấy, e chỉ có thể tạo bằng page nhưng khi xem bằng đt thì lại rất xấu. E newbier nên nhìn mấy đoạn code này cũng k hỉu lắm 🙁

Toàn nhập môn Wordpress

mình có tạo thêm phần upload hình ảnh cho widget mà không biết đúng không. Mình viết như sau:
trong hàm
function form($instance){
$defaults = array( // hàm mặc định nếu người dùng không nhập gì
‘title’ => ‘TP Widget’,
‘content’ => ‘Hãy nhập thông tin’,
‘hinh’=> ‘hình ảnh’,
);
echo (‘Hình ảnh get_field_name(‘hinh’).'” value=”‘.$hinh.'”>’);
}

trong hàm function update($new_instance, $old_instance){
$instance = $old_instance;
$instance[‘hinh’] = $new_instance[‘hinh’];
return $instance;
}
không biết có sai hay thiếu phần nào không mà nó không cập nhật file mình vừa upload

Toàn nhập môn Wordpress

mình muốn tạo code thêm hình cho widget thì mình phải làm sao bạn Thạch Phạm.?
Mình viết trong
function form($instance){
echo (‘Hình ảnh get_field_name(‘hinh’).'” value=”‘.$hinh.'”>’);
}
trong hàm
function update($new_instance, $old_instance){
$instance[‘hinh’] = $new_instance[‘hinh’];
}

nhưng nó không cập nhật file hình mình vừa upload, Không biết mình còn thiếu hàm kiểm tra file hình hay gì nữa không mà nó không cho cập nhật. :((

thi công vườn đứng

anh ơi, anh có thể cho em hỏi là cách nào để tạo 5 sao cho trang chủ và chuyên mục không ạ, em đã cài kk rate rồi nhưng chỉ thấy ở bài viết thường có đánh giá còn chuyên mục và trang chủ k thấy đâu

Phuong Tran

Thạch Phạm ơi, cho mình hỏi có cách nào làm backgroud cho widget không nhỉ

Lucas

bạn ơi, mình sử dụng hositing hỗ trợ wordpress của godaddy nên mình ko có cpanel, không thể truy cập vào file để coding. giờ mình muốn có 1 twitter hiển thị những tweet của mình để chèn vào sidebar thì có cách nào ko hả bạn. nếu như trong blogspot thì mình có thể chèn code váo trong widget html 1 cách dễ dàng nhưng trong wordpress thì mình chịu.

tiệp

Chào anh ! em đang làm widget up ảnh mà ko biết up ảnh lên và gọi ra thế nào 🙁 mong anh giúp đỡ em 🙁

loc huynh

Hi anh ThachPham,

Bài viết của anh rất hay và bổ ích, nhưng mà em có tí góp ý về giao diện đó là thanh “Chia sẽ MXH” của anh nó to quá, làm áng nội dung khá nhiều, đặc biệt là lúc đọc trên Phone thì… 🙁

Anh có thể thu nhỏ thanh đó được ko? Hoặc đặt nó ở bên Sidebar có vẻ cũng hợp lý 😀

Lâm Hiền

Chào thầy Thạch Pham, em muốn tạo 1 widget với chức năng tìm kiếm các user thôi thì phải làm như thế nào ạ? Rất mong thầy hướng dẫn ạ.

Tam

Oh Great. Thanks bác đã chia sẻ
Vừa gọi thử vào functions.php chạy được luôn. Mình thêm thêm field description cũng chạy luôn

$default = array(
‘title’ => ‘Tiêu đề widget’,
‘description’ => ”
);
………….
$description = apply_filters( ‘widget_description’, $instance[‘description’] );

Lệ Linh

Trong bước 4, dòng parent::form( $instance ); sẽ làm cho widget hiện ghi chú:

There are no options for this widget.

Trong bước 5, dòng parent::update( $new_instance, $old_instance ); không cần thiết.

Nguyễn Văn Hải

Chào thầy Thạch phạm. Em làm web này theo hướng dẫn của thầy: hoangyenfashion.com nhưng có 2 vấn đề em bí: 1- Em muốn tạo vùng widget đặt ở bên phải của header (bên trái là logo hoangyenfashion). Mục đích là em thêm SĐT và email ở vùng này. nói chung là dể chèn HTML vào. 2 – Ở phần “SẢN PHẨM LIÊN QUAN” em mốn nó hiển thị 4 cột thì nó lại chỉ hiển thị 3 cột. Rất ngại khi hỏi thầy vì biết thầy rất bận. nên em đã liên hê với AZDIGI nhờ họ làm nhưng… Xem thêm »

Văn Rin

Chào TP. Mình muốn hỏi code của widget có sẳn như Achives thì nó được viết ở đâu?
Mình đang cần giải quyết vấn đề hiển thị ra từng ngày và thứ. (Mặc định chỉ hiển thị tháng)

Văn Rin

cho nó hiển thị thêm cái thứ phía sau của ngày tháng năm thì nên làm như thế nào a nhỉ, e làm = widget

Tran Thuy

Hi anh! các widget trên trang của em hiện tại các title đang để thẻ h1 em muốn thay đổi thành thẻ h2 hoặc h3 thì em chỉnh sửa theo đường dẫn nào ạ. thanks anh ạ

27
0
Would love your thoughts, please comment.x
()
x