WordPress自訂模組(widget)及顯示版位


作者: | 2013/06/19 15:08:02 | 留言


WordPress 自訂模組
會想寫這篇是因為很久沒有寫到模組(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
	}
}

WordPress自訂模組
其中儲存值都是透過$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,它的流水號不會歸零,會一直累加下去。


標籤:,

分類:,

本文作者是Audi Lu

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。

*

*

*

這個網站採用 Akismet 服務減少垃圾留言。進一步瞭解 Akismet 如何處理網站訪客的留言資料