会想写这篇是因为很久没有写到挂件(Widget)但临时需要写一个,接着想快速找个完整的范例却找不到,原因是大部份找到的相关教学,都是将Widget的定制和sidebar版位的建立分开介绍,但这两个东西要配在一起才会完整呀XD。
注册自定义挂件及建立类别
首先假设你想在后台的外观/挂件里建立一个自订的挂件,也就是该页面左大半边的一堆小玩意,让它可以被拉进各种侧栏版位(dynamic sidebar或称widget area),那你就必须先建立一个自定义的Widget类别,然后注册它。请开启主题的functions.php,放进如下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | // 注册自订的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 " |
$myname
“; 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 ); ?>
<?php } }
其中储存值都是透过$instance来存,我们的范例只用到一个myname,如果你需要储存很多资料,就会用到很多组。存档后就会发现后台出现了自定义的Widget咯。
注册自定义挂件版位(sidebar)
如果您的主题已经有适合放Widget的版位了,那当然就可以直接使用,不过如果您是想自定义新的版位,就要在functions.php再加上:
1 2 3 4 5 | function side_widgets_init() { register_sidebar(array( 'name' => '侧边栏挂件位置', 'id' => 'sidebar-sec', 'before_widget' => ' |
‘, ‘before_title’ => ‘
‘, ‘after_title’ => ‘
‘, )); } add_action( ‘widgets_init’, ‘side_widgets_init’ );
这样后台就会出现自定义版位了,如果要在前台秀出这个自定义版位,只要在前台主题文件中写下:
1 2 3 | 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前台外观时,顺便参照当时所处容器(版位)的相关设定。
1 2 3 4 5 6 7 | // 描述widget显示于前台时的外观 function widget( $args, $instance ) { // $args里可以拿到所在版位的相关信息,如before_widget、after_widget..等 extract( $args ); echo $before_widget; $myname = $instance['myname']; echo " |
$myname
“; 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可能就像这样:
1 2 3 4 5 6 7 | <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,它的流水号不会归零,会一直累加下去。
译自MRMU,朽木整编,未经许可禁止转载