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