Skip to content

WordPress 2.8+ Multi-Widgets

In previous lesson we discussed how to create WordPress multi-widget. In the version 2.8 WordPress developers implemented new Widgets API that allows you to register widget in a few simple steps and it becomes multiple by default. We want to review these steps and to show how it works. But unfortunately this method works in WordPress 2.8+ and is not compatible with earlier WordPress versions.

First of all WordPress coders implemented Class model for Widgets. In order to create a widget you need to create new class and extend it from default one. Basic syntax is the following:

class My_Widget extends WP_Widget {
	function widget($args, $instance) {
		echo 'This is my first widget with Wordpress 2.8 Widgets API';
	}
}
register_widget('My_Widget');

This code will create multiple widget, which you can add as many times as you need.

To add some info about your plugin you should use class constructor. So let’s add title, description, id base and the class name:

	// constructor
	function My_Widget() {
		// use parent constructor to re-write standard class properties
		parent::WP_Widget('my_widget_base', 'My Widget title', array('description' => 'Very simple widget example', 'class' => 'my-widget-class'));	
	}

Next step is to add some fields to our widget, so we can pass through some data. This can be done with registering control and update function in the same class. For example we want to add title field to edit widgets caption on display.

	/** @see WP_Widget::update */
	function update($new_instance, $old_instance) {
		// fill current state with old data to be sure we not loose anything
		$instance = $old_instance;
		// for example we want title always have capitalized first letter
		$instance['title'] = strip_tags($new_instance['title']);
		// and now we return new values and wordpress do all work for you
		return $instance;
	}
 
	/** @see WP_Widget::form */
	function form($instance) {
		$default = 	array( 'title' => __('Just Widget') );
		$instance = wp_parse_args( (array) $instance, $default );
 
		$field_id = $this->get_field_id('title');
		$field_name = $this->get_field_name('title');
		echo "\r\n".'<p><label for="'.$field_id.'">'.__('Title').': <input type="text" class="widefat" id="'.$field_id.'" name="'.$field_name.'" value="'.attribute_escape( $instance['title'] ).'" /><label></p>';
	}

Let us explain the code above. First of all we need to take a look at “form” function which prints form fields inside widget box when you insert it into a sidebar. New widget class has two nice functions $this->get_field_id() and $this->get_field_name(). These functions will create unique ID and NAME attributes for input field based on your plugin ID-BASE. Remember that you should use this functions for all input fields you have. After that we can look at “update” function. You have 2 parameters: new values from POST array and old values saved in the database (empty if this is a new widget). All you have to do is prepare the array like

	'field1' => 'value',
	'field2' => 'value'

and return this array back. And that’s all! WordPress takes care about getting this data to database.
So if you have read our previous article (WordPress Multi Widgets) you can see that now WordPress makes all dirty work for you. You don’t need to care about unique names, catching them from post, comparing with old data. Everything is clear and simple – creating the form and pre-process values. No database operations and other routing.

The last step in widget creation is to get data when we want to show it. As you can see widget output function takes two parameters:
$args – the same as before – general parameters from sidebar and
$instance – array with values from the database. All is here already!

So let’s collect all of this together to create a widget with one Title field:

<?php
class JustWidget extends WP_Widget {
 
	/**
	 * constructor
	 */	 
	function JustWidget() {
		parent::WP_Widget('just_widget', 'Just Widget', array('description' => 'Wordpress 2.8+ Multi Widget Example by JustCoded.com.'));	
	}
 
	/**
	 * display widget
	 */	 
	function widget($args, $instance) {
		extract($args, EXTR_SKIP);
		echo $before_widget;
		$title = empty($instance['title']) ? '&nbsp;' : apply_filters('widget_title', $instance['title']);
		if ( !empty( $title ) ) { echo $before_title . $title . $after_title; };
		?>
		<p>Hello, i'm your multi-widget example. You can add me many many times :).</p>
		<p>Check out other articles at <a href="http://justcoded.com/" target="_blank">JustCoded</a>.</p>
		<?php 
		echo $after_widget;
	}
 
	/**
	 *	update/save function
	 */	 	
	function update($new_instance, $old_instance) {
		$instance = $old_instance;
		$instance['title'] = strip_tags($new_instance['title']);
		return $instance;
	}
 
	/**
	 *	admin control form
	 */	 	
	function form($instance) {
		$default = 	array( 'title' => __('Just Widget') );
		$instance = wp_parse_args( (array) $instance, $default );
 
		$field_id = $this->get_field_id('title');
		$field_name = $this->get_field_name('title');
		echo "\r\n".'<p><label for="'.$field_id.'">'.__('Title').': <input type="text" class="widefat" id="'.$field_id.'" name="'.$field_name.'" value="'.attribute_escape( $instance['title'] ).'" /><label></p>';
	}
}

You can download our plugin example here. Fill free to post your comments and to ask questions you may have about it. Good luck with your WordPressing!

10 Responses to “WordPress 2.8+ Multi-Widgets”

  1. Michael February 15th, 2010 at 2:07 am

    Thank you for your tutorial!

    I would like to enable the users to add fields in the general admin/setting/myplugin of the admin.
    Do I have to make this widget first into a plugin?
    Can you point me to a place where I can learn how to add dynamic input fields.

    Thanks again

  2. Steve February 17th, 2010 at 3:01 pm

    It doesn’t seem to work on Internet Explorer 8. I simply included your file at the end of a plugin I’ve got and the widget appears on the widgets page but its not draggable. This is under wordpress 2.9.2

  3. Steve February 24th, 2010 at 2:53 pm

    I found the problem. In the download version the ‘class’ => ‘my-widget-class’ is missing from the Parent:: line

    Also you need to add the class to the label tags :

    echo “\r\n”.”.__(‘Title’,'my-widget-class’)

    It only seems to be IE that has a problem if that isn’t there.

    Hope that helps.

  4. michalbroz March 28th, 2010 at 12:33 pm

    Great article. Except these mistakes:
    1)
    Its only PHP 4, but we may use PHP5 here. Its easy, simply use:
    function __construct(){
    parent::__construct();
    }
    instead of
    function My_Widget() {
    parent::WP_Widget();
    }

    2)
    function attribute_escape() – is deprecated in WP.

    3)
    labelname is not correct.
    Use this instead:
    labelname

  5. Writing a WordpressMU Widget June 14th, 2010 at 5:17 am

    [...] a bit more searching, I came across a nice tutorial explaining how to build a multiple-instance widget. I got that all put together, but found that things still didn’t work quite right because of [...]

  6. Dineshkumar June 28th, 2010 at 12:20 pm

    I am using select box to list the category names in my widget.For instance ,select box list 3 categories.I have added 2 widget in my sidebar.When i click widget edit in admin page it displays the categories as in order.I want select box to display what i chosen for that widget . Please help me to fix this….

  7. himanshu October 29th, 2010 at 7:14 am

    how to change the color of recent posts in front end with wordpress 3.0.1

  8. Boribiz June 4th, 2011 at 11:42 pm

    Hi,

    Thank you for the tutorial. I’m a newbie, anywway you look at it. I foudn a widget that I love, Iframeless, but I can’t even get my head around how to make it multi-widget. I’ve tried emailing ht developers, but no reply. Their php file is short and refers to an outside source I think for the attributes of their widget. ‘http://wordpressiframe.omadataobjects.com‘ Any dieas are welcomed!

    Thank you for the tutorial! I’ll be learning my way through :)

    Boriana

  9. Greg Bowen August 25th, 2011 at 7:20 pm

    This is great! It is working well. Question: One of my plugins calls javascript, but needs to call a separate javascript file for each instance. Is there a way to get the instance of the widget, as in 1, 2 or 3 (etc)?

  10. Alex Prokopenko September 2nd, 2011 at 12:14 pm

    Hi Greg. You can try to print class object ($this) inside the function you need and there you will see class property which has instance number.

Leave a Reply

3d Party Adobe Flash Api Blog CMS Compatibility Cross Browser CSS Drupal FB Portfolio Custom FF Google Google Gears Html Code IE6 IE7 Implementation Javascript Libraries Joomla Jquery Kharkov Management Systems Multi color sIFR Open Source Cms Opera Optimization PHP Plugins Plug Ins PSD to Drupal psd to html PSD to Magento PSD to Wordpress Safari Semantics sIFR Templates W3c Standards Widget Example Widget Name Widgets Wordpress Wordpress Theme WP Xhtml