- Back to Home »
- lập trình , thiết kế theme wordpress »
- Thiết kế theme Wordpress bài 10: Làm việc với widget(tiếp theo)
Ở 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.
class Widget_name extends WP_WidgetHãy nhìn đoạn mã mà tôi đã cung cấp cho các bạn ở bên trên.
{
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');
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:
- Widget_name(): đây là hàm khởi tạo(còn gọi là hàm Constructor). Nó được gọi khi bạn tạo một đối tượng (object) với tên là tên class. Ví dụ, khi bạn tạo một object A, hàm contructor sẽ tự động được thực thi và làm một số công việc bạn mong muốn như khai báo ngày tháng năm sinh, khởi tạo các giá trị chiều cao, cân nặng gì đó…
- widget(): hàm này sẽ có nhiệm vụ thể hiện widget của bạn ra ngoài giao diện. Bạn muốn nó hiển thị cái gì thì khai báo ở đó.
- update(): hàm này tôi dùng cho backend để thực hiện việc lưu dữ liệu thiết lập cho widget của tôi. Ví dụ như tôi muốn lưu tiêu đề widget, số tin sẽ hiện, có hiện ngày tháng đăng tin hay ko…
- form(): hàm này sẽ tạo ra form ở phần widget trong backend cho tôi. Tôn muốn lưu cái gì tôi sẽ thể hiện ở form này.
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.
Để demo cho các bạn viết 1 widget đơn giản tôi chọn widget giới thiệu về Admin (about me). 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:
class nhanweb_Aboutme extends WP_WidgetBắ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
{
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');
Viết hàm Contructor
Hàm này được tôi viết như sau:
function nhanweb_Aboutme(){Bạn chú ý là các giá trị $widget_ops và $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:
$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);
}
class nhanweb_Aboutme extends WP_WidgetSau 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ả.
function form($instance){Đoạn mã
//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 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" 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" id="' . $this->get_field_id('aboutText') . '" name="' . $this->get_field_name('aboutText') . '" >'. $aboutText .'</textarea></p>';
}
$instance = wp_parse_args( (array) $instance, array('title'=>'', 'imagePath'=>'', 'aboutText'=>'') );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:
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:
/*Saves the settings. */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
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;
}
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():
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;
?>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, tận hưởng thành quả đi nha !
<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;
}
Bonus: toàn bộ mã nguồn
<?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">',
'after_widget' => '</li>',
'before_title' => '<h3>',
'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">',
'after_widget' => '</li>',
'before_title' => '<h3>',
'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 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" 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" 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;
?>Chúc các bạn thành công !
<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');
?>