WordPress自訂模組(widget)及顯示版位
| 2013/06/19 | 留言

會想寫這篇是因為很久沒有寫到模組(Widget)但臨時需要寫一個,接著想快速找個完整的範例卻找不到,原因是大部份找到的相關教學,都是將Widget的客製和sidebar版位的建立分開介紹,但這兩個東西明明就像咳精要配溫開水一樣,要配在一起才會完整呀XD。
註冊自訂模組及建立類別
首先假設你想在後台的外觀/模組裡建立一個自訂的模組,也就是該頁面左大半邊的一堆小玩意,讓它可以被拉進各種側欄版位(dynamic sidebar或稱widget area),那你就必須先建立一個自訂的Widget類別,然後註冊它。請開啟佈景的functions.php,放進如下程式碼:
// 註冊自訂的Widget-EX_Widget
function register_ex_widget() {
register_widget( 'EX_Widget' );
}
add_action( 'widgets_init', 'register_ex_widget' );
// 自訂的EX_Widget類別,要繼承WP_Widget
class EX_Widget extends WP_Widget {
// 一些初始化設定
function EX_Widget() {
$widget_ops = array( 'classname' => 'side_ex', 'description' => '還記得我嗎?大聲點我聽不見~');
$control_ops = array( 'width' => 300, 'height' => 350, 'id_base' => 'side_ex-widget' );
$this->WP_Widget( 'side_ex-widget', '我的名字', $widget_ops, $control_ops );
}
// 描述widget顯示於前台時的外觀
function widget( $args, $instance ) {
// $args裡可以拿到所在版位的相關資訊,如before_widget、after_widget..等
extract( $args );
echo $before_widget;
$myname = $instance['myname'];
echo "<h2>$myname</h2>";
echo $after_widget;
}
// 於後台更新Widget時會做的事
function update( $new_instance, $old_instance ) {
$instance = $old_instance;
// 簡單幫設定內容作一下Strip tags,擋掉html tag
$instance['myname'] = strip_tags( $new_instance['myname'] );
return $instance;
}
// Widget在後台模組頁的外觀
function form( $instance ) {
// 可以設定預設值
$defaults = array('myname'=>'熱血大叔');
$instance = wp_parse_args( (array) $instance, $defaults ); ?>
<p>
<label for="<?php echo $this->get_field_id( 'myname' ); ?>">設定要顯示的名字:</label>
<input type="text" name="<?php echo $this->get_field_name( 'myname' ); ?>" value="<?php echo $instance['myname']; ?>">
</p>
<?php
}
}

其中儲存值都是透過$instance來存,我們的範例只用到一個myname,如果你需要儲存很多資料,就會用到很多組。存檔後就會發現後台的模組出現了自訂的Widget囉。
註冊自訂模組版位(sidebar)
如果您的佈景已經有適合放Widget的版位了,那當然就可以直接使用,不過如果您是想自訂新的版位,就要在functions.php再加上:
function side_widgets_init() {
register_sidebar(array(
'name' => '側欄模組區',
'id' => 'sidebar-sec',
'before_widget' => '<div id="%1$s" class="%2$s sidebar_frm">',
'after_widget' => '</div>',
'before_title' => '<h4 class="widgettitle">',
'after_title' => '</h4>',
));
}
add_action( 'widgets_init', 'side_widgets_init' );
這樣後台就會出現自訂版位了,如果要在前台秀出這個自訂版位,只要在前台佈景檔中寫下:
if ( !function_exists('dynamic_sidebar')|| !dynamic_sidebar('sidebar-sec') ){
// 如果wp版本不支援顯示或者找不到你所設定的模組ID,就會執行這個區塊裡的程式...blah blah...
}
其中dynamic_sidebar(‘sidebar-sec’)是顯示出版位的程式碼,sidebar-sec是版位註冊時的id。這裡的if判斷只是安全性判斷,避免找不到該版位時會出現錯誤訊息。
OK,儲存後就可以在前台出現你所自訂的Widget了。所以說,register_sidebar或dynamic_sidebar裡所指的”sidebar”,並不是專指位在側邊欄的版位,你可以發佈創意將它安排在前台任何位置。:)
等一下!有個重點…
….等一下,難道你不覺得範例中register_sidebar()裡的before_widget設定怪怪的嗎?怎麼有 %1$s 和 %2$s 這種東西?
在此就要特別說明一下這個部份代表「”模組”與其放置的”版位”之間其實是有溝通管道的」。觀察一下自訂Widget類別裡的widget(),裡頭的$args參數可以協助我們在描繪Widget前台外觀時,順便參照當時所處容器(版位)的相關設定。
// 描述widget顯示於前台時的外觀
function widget( $args, $instance ) {
// $args裡可以拿到所在版位的相關資訊,如before_widget、after_widget..等
extract( $args );
echo $before_widget;
$myname = $instance['myname'];
echo "<h2>$myname</h2>";
echo $after_widget;
}
觀察一下上述範例,在widget()裡,會在顯示名字的前後包上before_widget和after_widget,其內容就是來自register_sidebar中的同名變數設定。而%1$s,就像printf的意思差不多,只是參數會由wp幫你放進去,主要是拿你在widget初始化時的id_base後接上流水號作為widget的id。
如果你重複拉進很多相同的Widget裡同一個版位,你就會在前台發現每一個Widget輸出時的ID都會接有流水號,如果前台要進行javascript操作時,你就會發現這是很必要的。
其二參數%2$s代表的是widget的classname,它是參照在widget初始化中的classname設定。有了這些溝通設定,我們就可以很有彈性的為自訂Widget標示上ID並且區分容器(版位)和Widget間的classname。
以我們的例子來看,假設我拉進兩個「我的名字」模組到「側欄模組區」這個版位,其輸出的HTML可能就像這樣:
<div id="side_ex-widget-1" class="side_ex sidebar_frm"><h2>Audi Lu</h2></div> <div id="side_ex-widget-2" class="side_ex sidebar_frm"><h2>mrmu</h2></div>
如果你刪除了其中的Widget,又新增了一個Widget,它的流水號不會歸零,會一直累加下去。
標籤:WordPress, WordPress開發
本文作者是Audi Lu