Show or Hide a WP widget only on specific page/s without using a plugin

1 Sep

Widgets make a WP theme’s sidebar alive. Small but important pieces of info which shouldn’t be restricted to a single page, can be put into a widget and made available on all the pages through the sidebar. But sometimes you might want to show a widget only on specific pages or page. One would code multiple sidebars and call them according to the pages, by adding different widgets to them or simply use a plugin to do this. But you don’t need to code multiple sidebars, just follow this simple piece of code, and you’ll know how to show/hide widgets according to the pages without using a plugin.

Obviously, you should know the following before you read further:
1. WP – Yeah, of course 😉 But more on the developer level.
2. WordPress Filters – What, Why, How, When?
3. Firebug powered FireFox – Stop developing websites if you don’t know what Firebug is :P!

You reached here? Kewl! Let’s get to work…

Consider the following use case – We don’t want to show the default ‘Archives’ widget on the home page of our site.

When a new widget is coded, a unique identifier is added for it. Look at the code for the default ‘Archives’ widget that comes along with WordPress (‘default-widgets.php’, line no. 214):

class WP_Widget_Archives extends WP_Widget {

	function WP_Widget_Archives() {
		$widget_ops = array('classname' => 'widget_archive', 'description' => __( 'A monthly archive of your site’s posts') );
		// The first argument to WP_Widget, 'archives' is the identifier we're talking about
		$this->WP_Widget('archives', __('Archives'), $widget_ops);
	}
// blah blah.....
}

Here, the identifier is ‘archives’. This identifier is also used to generate an id for the ‘<li>’ tag that holds the widget in the sidebar, by dynamically appending a number to its end. You can examine the id by using Firebug. See the following screens for an idea:

‘archives-4’ was generated from ‘archives’ in the code. You can get the identifier for any widget you want to show/hide by examining it using Firebug.
Now we get to the ‘meat of the matter’, hiding the widget according to the page.
We’ll use the Filter Hook ‘sidebars_widgets’ for accomplishing this. Let’s hook a function to this filter. You can put this code in the ‘functions.php’ file of your theme.

add_filter('sidebars_widgets', 'hidemywidget');
function hidemywidget($all_widgets)
{
    echo "<pre>";
    print_r($all_widgets);
    echo "</pre>";
//comment the following and tell me what happens!
    return $all_widgets;
}

We’ve hooked the function ‘ hidemywidget’ to the ‘sidebars_widgets’ filter hook. The argument to this function contains the array of generated identifiers for all the widgets active in the sidebars, as well as the inactive ones. We’re interested in the id for the ‘archives’ widget. Observe the contents of the ‘$all_widgets’ array. It contains an array that holds the id’s of all the inactive widgets, ‘wp_inactive_widgets’, and the arrays of widget id’s corresponding to the dynamic sidebars/widget areas that you register using ‘register_sidebar’. I’m using the ‘primary-widget-area’ from ‘Twenty Ten’ theme. So my array of widget id’s looks as follows:

Now we check if we’re on the homepage, and if yes, remove the ‘Archives’ widget, by removing the ‘archives-4’ id from the ‘primary-widget-area’ array. We cannot use the generated id ‘archives-4’ directly to remove the widget, as the number ‘4’ is dynamically appended to it and may change depending on the widget’s position, and some other factors (which I seriously don’t know :P)
Modify the code as follows:

function hidemywidget($all_widgets)
{
    //this should run on the homepage / frontpage only! you can use more conditions here
    if(is_front_page() || is_home())
    {
        foreach ($all_widgets['primary-widget-area'] as $i => $inst)
        {
            //check if the id for the archives widgets exists.
            $pos = strpos($inst, 'archives');
        
            if($pos !== false)
            {
                //remove the archives widget by unsetting it's id
                unset($all_widgets['primary-widget-area'][$i]);
            }
        }
    }
//comment the following and tell me what happens!
return $all_widgets;
}

Visit your site’s homepage, and wallah, the ‘Archives’ widget has disappeared from the sidebar! Don’t forget to check the other pages to make sure it shows up in the sidebar!

There might be better ways to do this, please let me know if you find one! In case of a doubt, feel free to mail me at ‘mail@rutwick.com’.
Adios!

18 Responses to “Show or Hide a WP widget only on specific page/s without using a plugin”