NHANWEB

Thiết kế theme WP – phần 10: Làm việc với widget(tiếp)

phần trước chúng ta đã tìm hiểu Widget là gì và làm thể nào để đưa các widget vào giao diện thiết kế của mình. Phần bài hôm nay sẽ là phần chuyên sâu hơn, bởi chúng ta sẽ học cách làm thế nào thiết kế một widget riêng cho mình.

Để bắt đầu phần này, trước tiên tôi xin giới thiêu sơ qua với mọi người một lớp (class) widget của WordPress.

Trong WordPress, các widget được xây dựng dựa trên sự kế thừa(inherit) lớp cha của nó. Lớp cha này chính là những xác lập mặc định của widget mà WordPress đã xây dựng sẵn cho bạn. Một khi bạn kế thừa từ lớp cha, các thuộc tính của lớp cha sẽ được di truyền sang lớp con. Điều này nếu bạn nào học lập trình hướng đối tượng sẽ dễ dàng hình dung ra, còn những bạn mới làm quen với các khái niệm lập trình hướng đối tượng sẽ cảm thấy bỡ ngỡ. Tuy nhiên, tôi chỉ nói cho các bạn biết là như vậy thôi vì tôi không muốn đi quá sâu vào mảng kiến thức lập trình.

Như đã nói ở trên, khi thiết kế một widget, chúng ta sẽ thừa kế lớp cha widget của nó đã được định nghĩa đầy đủ. Việc cần làm là xác định object widget cần xây dựng thừa kế từ lớp cha widget đã được WordPress xây dựng sẵn và xây dựng thêm các thuộc tính riêng mà bạn mong muốn. Object widget cần xây dựng được viết dưới dạng class như sau.

[php] class Widget_name extends WP_Widget
{
function Widget_name(){

}

/* Displays the Widget in the front-end */
function widget($args, $instance){

}

/*Saves the settings. */
function update($new_instance, $old_instance){

}

/*Creates the form for the widget in the back-end. */
function form($instance){

}

}// end Widget_name class

function registerWidget_nameInit() {
register_widget(‘Widget_name’);
}

add_action(‘widgets_init’, ‘registerWidget_nameInit’);
[/php]

Hãy nhìn đoạn mã mà tôi đã cung cấp cho các bạn ở bên trên.

Chúng ta có 1 class tên là Widget_name, một hàm registerWidget_nameInit và một hành động gọi hàm registerWidget_nameInit khi hook widgets_init hoạt động.

Class Widget_name mà tôi thiết kế ở trên bao gồm 4 action tương ứng với 4 function được khai báo bên trong:

– Hàm registerWidget_nameInit(), tôi xây dựng để khai báo với anh chàng WordPress rằng tôi sẽ xử dụng cái class Widget_name như một Widget.

Xong, vậy là tôi đã giới thiệu sơ qua cho các bạn cấu trúc Widget rồi. Giờ chúng ta sẽ bắt tay viết một widget đơn giản.

Viết một widget đơn giản: Giới thiêu Admin.

Tôi suy nghĩ và lựa chọn mãi mà chưa biết viết plugin nào có lợi cho người dùng để vừa làm ví dụ, vừa vác về xài luôn được :D Thôi tôi chọn đại cái widget Giới thiệu Admin (about me) để biết nhé. Theo đó tôi đặt tên cho widget của tôi là nhanweb_Aboutme. Để tránh việc trùng tên với các function và class mà có thể các plugin khác sẽ đặt. Tốt nhất khi viết code hoặc function bạn nên đặt tên bằng cách chèn thêm một tiếp đầu ngữ (prefix) giống như tôi để tránh trùng nhé !

Tôi lấy đoạn mã trên đặt vào functions.php của giao diện như sau:

[php] class nhanweb_Aboutme extends WP_Widget
{
function nhanweb_Aboutme(){

}

/* Displays the Widget in the front-end */
function widget($args, $instance){

}

/*Saves the settings. */
function update($new_instance, $old_instance){

}

/*Creates the form for the widget in the back-end. */
function form($instance){

}

}// end Widget_name class

function registernhanweb_AboutmeInit() {
register_widget(‘nhanweb_Aboutme’);
}

add_action(‘widgets_init’, ‘registernhanweb_AboutmeInit’);
[/php]

Bắt đầu viết các sự kiện cho class nhanweb_Aboutme mà tôi đã giải thích với mọi người thôi :)

Viết hàm Contructor

Hàm này được tôi viết như sau:

[php] function nhanweb_Aboutme(){
$widget_ops = array(‘description’ => ‘Hiện thông tin giới thiệu tác giả’);
$control_ops = array(‘width’ => 400, ‘height’ => 300);
parent::WP_Widget(false,$name=’NhanWeb About me’,$widget_ops,$control_ops);
}
[/php]

Bạn chú ý là các giá trị $widget_ops$control_ops bạn không được đổi keyword của mảng nếu bạn không nắm rõ về nó vì nó được thừa kế từ lớp cha WP_Widget như chúng ta đã khai báo ở đầu class:
[php] class nhanweb_Aboutme extends WP_Widget
[/php]

Sau khi viết xong hàm này tôi đã có một widget trong admin. Nhưng nếu kéo và thảy widget vài vị trí cần thể hiện tôi chẳng có một lựa chọn nào cho nó cả.

Widget sau khi viết xong constructor

Viết hàm form để tùy chọn cho Admin

Để bổ sung các lựa chọn cho Widget, tôi sẽ viết tiếp một form nhập liệu thông qua hàm form() như sau:

[php] function form($instance){
//Defaults
$instance = wp_parse_args( (array) $instance, array(‘title’=>’Về tôi’, ‘imagePath’=>’Ảnh’, ‘aboutText’=>’Giới thiệu’) );

$title = htmlspecialchars($instance[‘title’]);
$imagePath = htmlspecialchars($instance[‘imagePath’]);
$aboutText = htmlspecialchars($instance[‘aboutText’]);

# Title
echo ‘<p><label for="’ . $this->get_field_id(‘title’) . ‘">’ . ‘Tiêu đề:’ . ‘</label><input class="widefat" id="’ . $this->get_field_id(‘title’) . ‘" name="’ . $this->get_field_name(‘title’) . ‘" type="text" value="’ . $title . ‘" /></p>’;
# Image
echo ‘<p><label for="’ . $this->get_field_id(‘imagePath’) . ‘">’ . ‘Ảnh:’ . ‘</label><textarea cols="20" rows="2" class="widefat" id="’ . $this->get_field_id(‘imagePath’) . ‘" name="’ . $this->get_field_name(‘imagePath’) . ‘" >’. $imagePath .’</textarea></p>’;
# About Text
echo ‘<p><label for="’ . $this->get_field_id(‘aboutText’) . ‘">’ . ‘Giới thiệu:’ . ‘</label><textarea cols="20" rows="5" class="widefat" id="’ . $this->get_field_id(‘aboutText’) . ‘" name="’ . $this->get_field_name(‘aboutText’) . ‘" >’. $aboutText .’</textarea></p>’;
}
[/php]

Đoạn mã
[php] $instance = wp_parse_args( (array) $instance, array(‘title’=>”, ‘imagePath’=>”, ‘aboutText’=>”) );
[/php]

Sẽ thiết lập các giá trị mặc định nếu như các thông tin không được bổ sung. Đoạn mã phía dưới nó sẽ hiện form nhập liệu như hình:

Form nhập liệu cho widget

Viết hàm update để cập nhật dữ liệu

Sau khi nhập liệu đầy đủ, chúng ta tiến hành lưu các dữ liệu đã nhập để sử dụng khi thể hiện. Hàm update() được viết như sau:

[php] /*Saves the settings. */
function update($new_instance, $old_instance){
$instance = $old_instance;
$instance[‘title’] = stripslashes($new_instance[‘title’]);
$instance[‘imagePath’] = stripslashes($new_instance[‘imagePath’]);
$instance[‘aboutText’] = stripslashes($new_instance[‘aboutText’]);
return $instance;
}
[/php]

Bạn thấy đoạn code trên không ! Khi bạn nhấn nút Save, WordPress sẽ hiểu là các giá trị nhập vào là các giá trị $new_instance, các giá trị cũ sẽ là $old_instance. Với 2 giá trị này bạn sẽ xử lý tùy ý và trả về cái cuối cùng là $instance dạng mảng (array) để wordpress tự động gọi lưu trữ. Xem chừng việc lưu dữ liệu của Widget rất dễ dàng :)

Viết hàm widget

Chúng ta đã tiến hành khai báo, tạo form nhập liệu và lưu dữ liệu rồi, giờ công việc cuối cùng là thể hiện cái Widget chúng ta đã thiết kế ra ngoài thế nào thôi. Đây là đoạn mã tôi viết cho hàm widget():

[php] function widget($args, $instance){
extract($args);
$title = apply_filters(‘widget_title’, empty($instance[‘title’]) ? ‘Về tôi’ : $instance[‘title’]);
$imagePath = empty($instance[‘imagePath’]) ? ” : $instance[‘imagePath’];
$aboutText = empty($instance[‘aboutText’]) ? ” : $instance[‘aboutText’];
echo $before_widget;
if ( $title )
echo $before_title . $title . $after_title;
?>
<div class="clearfix">
<img src="<?php echo $imagePath; ?>" id="about-image" alt="about us image" />
<p><?php echo($aboutText)?></p>
</div>
<?php
echo $after_widget;
}
[/php]

Bạn chú ý: các biến $before_widget, $before_title, $after_title,$after_widget cần được đặt vào để có thể khai báo thêm các thông số cần thiết sau này.

Vậy là xong, cùng ngắm nhìn thành quả nào:

Kết quả cuối cùng

Bonus: toàn bộ mã nguồn

Để dễ dàng và trực quan. Mình post lại toàn bộ đoạn mã đã viết và thêm vào functions.php đã nói đến ở bài này và cả bài trước (toàn bộ nội dung đã hướng dẫn liên quan đến widget). Bạn nào cần thì copy về nhé.

[php] <?php
/**
* Register widgetized areas, including two sidebars and widget-ready columns in the footer.
*
* To override nhanweb_widget() in a child theme, remove the action hook and add your own
* function tied to the init hook.
*
* @uses register_sidebar
*/
function nhanweb_widget() {
// Dang ky widget cho Admin
register_sidebar( array(
‘name’ => __( ‘Widget cột phải’, ‘nhanweb’ ),
‘id’ => ‘right-widget-area’,
‘description’ => __( ‘Vị trí widget cột bên phải’, ‘nhanweb’ ),
‘before_widget’ => ‘<li id="%1$s" class="widget-container %2$s">’,
‘after_widget’ => ‘</li>’,
‘before_title’ => ‘<h3 class="widget-title">’,
‘after_title’ => ‘</h3>’,
) );

register_sidebar( array(
‘name’ => __( ‘Widget Footer’, ‘nhanweb’ ),
‘id’ => ‘footer-widget-area’,
‘description’ => __( ‘Vị trí widget ở cuối thang’, ‘nhanweb’ ),
‘before_widget’ => ‘<li id="%1$s" class="widget-container %2$s">’,
‘after_widget’ => ‘</li>’,
‘before_title’ => ‘<h3 class="widget-title">’,
‘after_title’ => ‘</h3>’,
) );
}
/** Register sidebars by running nhanweb_widget() on the widgets_init hook. */
add_action( ‘widgets_init’, ‘nhanweb_widget’ );

class nhanweb_Aboutme extends WP_Widget
{
function nhanweb_Aboutme(){
$widget_ops = array(‘description’ => ‘Hiện thông tin giới thiệu tác giả’);
$control_ops = array(‘width’ => 400, ‘height’ => 300);
parent::WP_Widget(false,$name=’NhanWeb About me’,$widget_ops,$control_ops);
}
/*Creates the form for the widget in the back-end. */
function form($instance){
//Defaults
$instance = wp_parse_args( (array) $instance, array(‘title’=>”, ‘imagePath’=>”, ‘aboutText’=>”) );

$title = htmlspecialchars($instance[‘title’]);
$imagePath = htmlspecialchars($instance[‘imagePath’]);
$aboutText = htmlspecialchars($instance[‘aboutText’]);

# Title
echo ‘<p><label for="’ . $this->get_field_id(‘title’) . ‘">’ . ‘Tiêu đề:’ . ‘</label><input class="widefat" id="’ . $this->get_field_id(‘title’) . ‘" name="’ . $this->get_field_name(‘title’) . ‘" type="text" value="’ . $title . ‘" /></p>’;
# Image
echo ‘<p><label for="’ . $this->get_field_id(‘imagePath’) . ‘">’ . ‘Ảnh:’ . ‘</label><textarea cols="20" rows="2" class="widefat" id="’ . $this->get_field_id(‘imagePath’) . ‘" name="’ . $this->get_field_name(‘imagePath’) . ‘" >’. $imagePath .’</textarea></p>’;
# About Text
echo ‘<p><label for="’ . $this->get_field_id(‘aboutText’) . ‘">’ . ‘Giới thiệu:’ . ‘</label><textarea cols="20" rows="5" class="widefat" id="’ . $this->get_field_id(‘aboutText’) . ‘" name="’ . $this->get_field_name(‘aboutText’) . ‘" >’. $aboutText .’</textarea></p>’;
}

/*Saves the settings. */
function update($new_instance, $old_instance){
$instance = $old_instance;
$instance[‘title’] = stripslashes($new_instance[‘title’]);
$instance[‘imagePath’] = stripslashes($new_instance[‘imagePath’]);
$instance[‘aboutText’] = stripslashes($new_instance[‘aboutText’]);

return $instance;
}

/* Displays the Widget in the front-end */
function widget($args, $instance){
extract($args);
$title = apply_filters(‘widget_title’, empty($instance[‘title’]) ? ‘Về tôi’ : $instance[‘title’]);
$imagePath = empty($instance[‘imagePath’]) ? ” : $instance[‘imagePath’];
$aboutText = empty($instance[‘aboutText’]) ? ” : $instance[‘aboutText’];

echo $before_widget;

if ( $title )
echo $before_title . $title . $after_title;
?>
<div class="clearfix">
<img src="<?php echo $imagePath; ?>" id="about-image" alt="about us image" />
<p><?php echo($aboutText)?></p>
</div>
<?php
echo $after_widget;
}

}// end Widget_name class

function registernhanweb_AboutmeInit() {
register_widget(‘nhanweb_Aboutme’);
}

add_action(‘widgets_init’, ‘registernhanweb_AboutmeInit’);
?>
[/php]

Chúc các bạn thành công và nhớ để lại comment nhé :)

Exit mobile version