WordPress Widget System – How it Works

The Widget System is one of the most powerful aspects of a WordPress blog. It allows us to easily customize various regions of our blog without having to do any PHP programming.

Here we examine how the WordPress Widgets System works. For an example of the different widget filters and functions in action, check out the Shiba Custom Widgets Plugin.

1. Widget Objects

There are two key objects in the Widgets System –

a) Sidebars

The sidebar is basically a “widget container”. Sidebars are usually defined, styled, and positioned by a WordPress theme. The most common sidebar is the right-sidebar which exists in most themes.

However, most themes today contain many more “sidebar” areas – including those that are positioned in the header, footer, and content areas of a blog. As a result, the term sidebar is no longer very accurate.

Nevertheless, the term is used in WordPress to refer to a general widget container, wherever it may be placed.

WordPress uses the global variable $wp_registered_sidebars to keep track of all the sidebars registered by your theme. Sidebars are registered using the
register_sidebar function.

The $wp_registered_sidebars global variable contains an array that looks something like this –

Array (
    [sidebar-1] => Array (
            [name] => Right Sidebar
            [id] => sidebar-1
            [description] => 
            [before_widget] => <li id="%1$s" class="widget %2$s"> 
            [after_widget] => </li> 
            [before_title] => <div class="widget-title">
            [after_title] => </div> )
 
    [sidebar-2] => Array (
            [name] => Extra Sidebar
            [id] => sidebar-2
            [description] => 
            [before_widget] => <li id="%1$s" class="widget %2$s"> 
            [after_widget] => </li> 
            [before_title] => <div class="widget-title"> 
            [after_title] =></div> )
... )

b) Widgets

There are a variety of widgets that are packaged with a WordPress installation including Archives, Calendar, Category, Recent Posts, Text Widget, and many more.

Widgets can be dragged and dropped into Sidebar objects from the Appearance >> Widgets menu. Each widget usually has several customization parameters that can be set in the same Appearance >> Widgets screen.

Each widget performs its own unique back-end operations based on its customization parameters, and sometimes, on user input. Depending on which sidebar object you dropped the widget in, its results will appear at different locations within your WordPress blog.

For example, the Archives widget accesses all previous posts, and organizes them based on month of publication. Customization options include –

  • Show the post counts.
  • Display the results as a drop-down menu.

Based on these customization options, different results will be displayed on your blog sidebar. For example, this page has an Archives widget that is set to display post count on its right-sidebar.

In addition to widgets that come with the native WordPress installation, various plugins may also add their own widgets. By adding these plugins, you can extend your blog functionality without having to do any PHP programming yourself.

WordPress uses the global variable $wp_registered_widgets to keep track of all the widget instances in your blog.

The $wp_registered_widgets global variable contains an array that looks something like this –

Array (
    [archives-1] => Array (
            [name] => Archives
            [id] => archives-1
            [callback] => Array (
                    [0] => WP_Widget_Archives Object (
                            [id_base] => archives
                            [name] => Archives
                            [widget_options] => Array (
                                    [classname] => widget_archive
                                    [description] => A monthly archive of your blog&#8217;s posts )
 
                            [control_options] => Array (
                                    [id_base] => archives )
 
                            [number] => 1
                            [id] => archives-1
                            [updated] => 
                            [option_name] => widget_archives )
 
                    [1] => display_callback )
 
            [params] => Array (
                    [0] => Array (
                            [number] => -1 ) 
                )
 
            [classname] => widget_archive
            [description] => A monthly archive of your blog&#8217;s posts )
 
    [text-8] => Array (
            [name] => Text
            [id] => text-8
            [callback] => Array (
                    [0] => WP_Widget_Text Object (
                            [id_base] => text
                            [name] => Text
                            [widget_options] => Array (
                                    [classname] => widget_text
                                    [description] => Arbitrary text or HTML )
 
                            [control_options] => Array (
                                    [id_base] => text
                                    [width] => 400
                                    [height] => 350 )
 
                            [number] => 8
                            [id] => text-8
                            [updated] => 
                            [option_name] => widget_text )
 
                    [1] => display_callback )
 
            [params] => Array (
                    [0] => Array (
                            [number] => 8 )
                 )
 
            [classname] => widget_text
            [description] => Arbitrary text or HTML )
... )

2. Positioning Widgets

Widgets are created and positioned in the Appearance >> Widgets menu.

In addition to keeping track of all the registered sidebars and widgets, WordPress also keeps track of which widget instances are stored in which sidebar object. When you drag and drop widget objects in the Appearance >> Widgets menu, the results get stored in your database as a WordPress option named sidebars_widgets.

You can access and change this information through the wp_get_sidebars_widgets and wp_set_sidebars_widgets commands.

$sidebar_widgets = wp_get_sidebars_widgets();

wp_get_sidebars_widgets returns an array of all sidebar objects and the widget instances they contain. An example array returned by wp_get_sidebars_widgets may look something like this –

Array (
    [wp_inactive_widgets] => Array (
            [0] => pages-4
            [1] => archives-3
            [2] => categories-3
            [3] => text-4
            [4] => menubar-3
            [5] => calendar-19
            [6] => meta-6
            [7] => meta-7 )
 
    [sidebar-1] => Array (
            [0] => archives-2
            [1] => search-3
            [2] => categories-2 )
 
    [sidebar-2] => Array ()
 
    [sidebar-3] => Array (
            [0] => menubar-4 )
... )

wp_set_sidebars_widgets accepts an array of all sidebar objects and the widget instances they contain. It replaces the existing sidebars_widgets option with this new array.

wp_set_sidebars_widgets($sidebar_widgets);

The WordPress Widgets interface is controlled by the widgets.js Javascript which is added with the admin-widgets command in the widgets.php file.

wp_enqueue_script('admin-widgets');


When a widget is released, the stop function in widgets.js file gets called. This function fills in all the needed POST values for the widget using values in hidden input fields that were determined during page creation. It is important to note that one of these values is the widget id number which is stored in the multi_number input field of each corresponding widget class.

After filling in all the necessary information, the Javascript code makes an AJAX call to wp-admin/admin-ajax.php with the action name widgets-order.

The admin-ajax process will then call wp_set_sidebars_widgets to update your sidebars_widget option with the new widget array structure.

3. Widget Hooks and Filters

There are a variety of widget hooks available that allow you to change the behavior and look of various widgets. Probably the most flexible and powerful hook is the sidebars_widgets filter which gets called from within the wp_get_sidebars_widgets function. By hooking into this function you can change the results returned by wp_get_sidebars_widgets.

add_filter('sidebars_widgets', array(&$this,'sidebars_widgets')); 

function sidebars_widgets($sidebars_widgets) {
    ...
    return $new_widgets;
}

Other related Widget filters extracted from the wp-includes/widgets.php file –

  • widget_form_callback – Filters the widget admin form before displaying, return false to stop displaying it.
  • widget_display_callback – Filters the widget’s settings, return false to stop displaying the widget.
  • widget_update_callback – Filters the widget’s settings before saving, return false to cancel saving (keep the old settings if updating).
  • dynamic_sidebar_params – Gets called from within the dynamic_sidebar function which displays a widget container. This filter gets called for each widget instance in the sidebar.

Other related Widget actions extracted from the wp-includes/widgets.php file –

  • in_widget_form – Add extra fields in the widget form – be sure to set $return to null if you add any. If the widget has no form the text echoed from the default form method can be hidden using css.
  • widgets_init – Gets called when a new widget instance is instantiated.

Related Articles

Comments

  1. says

    First of all, about your website…I totally LOVE the imagery! Whoever did the art is VERY good. Usually programmers are not that great artists…they use different sides of the brain, so people are usually good at one or the other, but not both. But I must say, your art is simply fantastic…and the coding information in regard to WordPress widgets, is really awesome also. This information is exactly what I was looking for. (though I don’t know if it’s going to help me exactly)

    I have a problem that I have a testimonials plugin that has a widget, which was working fine, until I changed from a Windows to a Linux server, AND updated WordPress to the latest version, all at the same time. Now I have almost the entire site back up again after some headaches, and messing around in the database and fixing some links…but this damn widget is not working. The files (testimonials posts ) are there, the custom sidebars are there, and the other stuff on the sidebars are working, just not this particular widget. And it’s a great widget…I don’t want to lose it. If you want to look at the site (cause it’s not “my” site that I entered above) it’s http://walkingtreeoflife.com …though i don’t know if you (or anyone) can help with just the URL or not…but there it is. Thanks for taking the time to write this great post.

  2. klwk says

    hi

    do you know is it possible to manually clear all sidebar widgets information (i.e. reset) so that we can assign widgets from the beginning again? Because I have a problem now I cannot access Appearance – Widgets page, it turns into a blank page showing nothing. Any help will be much appreciated. Thanks.

  3. Amit Sukapure says

    This is the great article, really useful for developers.
    I have one query, can we get widget title and content by widget id?

    By $wp_registered_widgets we can get details of widgets but not title and content. Is there any variable or function available?

    Thanks for this article.

    • ShibaShake says

      Presumably you can just go through the WP global variable $wp_registered_widgets and extract the ids from there.

  4. Srikanth S says

    Thank you for the concise writeup. But how do i search and catch a particular widget instance (custom menu widget instance with name as ‘my home’) in the sidebar and hide it conditionally ? Any help will be really appreciated.

  5. says

    Very helpful post, thanks! I couldn’t find information on setting the $sidebars_widgets variable anywhere else online, not even on the WP codex.

  6. says

    hi
    thanks for the information but i want to know, if a plugin has only widget enabled and does not have a shortcode or if there are no hint to function call, how can i call the function of that plugin?
    thanks

Trackbacks

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>