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):
[php]
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…..
}
[/php]

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.
[php]
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;
}
[/php]

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:

[php]
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;
}
[/php]

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!

By rutwick

18 thoughts on “Show or Hide a WP widget only on specific page/s without using a plugin”
    1. Exactly!
      I did this for the same reason, I didn’t wanna use another plugin just to show/hide a widget and wanted to have a better control over my code!

      You’re welcome!
      -Rutwick

  1. Hey rutwick, unfortunately this didn’t work for me.

    I want to hide tag_cloud widget which is on sidebar-1. This is what I am using:

    .
    .
    foreach ($all_widgets[‘sidebar-1’] as $i => $inst)
    {
    $pos = strpos($inst, ‘tag_cloud’);

    if($pos !== false)
    {
    unset($all_widgets[‘sidebar-1’][$i]);
    }
    }
    }
    .
    .

    What’s wrong with it??

    1. Hi,
      As far as I can see, there seems nothing wrong with this code.
      Aren’t you checking which page you’re on to hide the widget? Could you paste/mail me the code you’re trying and the $all_widgets array (print_r > copy > paste)? I’ll need to see the array and what you’re trying to figure out what’s wrong.

      -Rutwick

  2. Good morning, I apologize in advance because I do not understand English but I will translate through google, I hope my words are understood.

    I asked a question through “WordPress answers” in which I answered very timely because my problem is with the error that I mark on my blog, I can not get into my desktop the message is:

    Warning: require(/home/miyamoto/public_html/blog/wp-includes/classes.php) [function.require]: failed to open stream: No such file or directory in /home/miyamoto/public_html/blog/wp-settings.php on line 68

    Fatal error: require() [function.require]: Failed opening required ‘/home/miyamoto/public_html/blog/wp-includes/classes.php’ (include_path=’.:/usr/lib/php:/usr/local/lib/php’) in /home/miyamoto/public_html/blog/wp-settings.php on line 68 as I realize that I have is like the file that says “clase.php” so that gives me the error What I can do or how to fix it?

    Gracias por la respuesta.

    Bendiciones

    Roberto.

    1. Hi Roberto,
      It’s a commonly known error with WordPress upgrades. Google around for that error message you’re getting, and I’m sure you’ll find something. Let me know if you found anything, if not, I’ll do the favor!
      Gracias!

  3. Thanks man it works for me. I use the code like this,

    add_filter(‘sidebars_widgets’, ‘hidemywidget’);
    function hidemywidget($all_widgets)
    {
    //comment the following and tell me what happens!
    if (is_page(‘5’)|| is_page(‘9’)){
    unset($all_widgets[‘sidebar-1′][2]);
    return $all_widgets;
    }
    else if (is_page(’33’)||is_page(’45’)){
    unset($all_widgets[‘sidebar-1’][2]);
    unset($all_widgets[‘sidebar-1’][1]);
    return $all_widgets;
    }
    else{return $all_widgets;}
    }

    1. Hi Abid,
      Glad it worked !
      But what is if (is_page(’5′)|| is_page(’9′)) doing in your code? Let me warn you it can and will fail if you transfer the code between 2 sites as the page ids will change! Use the Conditional Tags provided by WordPress instead. Let me know if I can assist you.

      – Rutwick

      1. The styles.css file if its a theme, or make a new css file and enqueue it using wp_enqueue_styles.

    1. How can i remove more then one widget? With your code i can get the archives widget out from posts page, but if i want remove others no. I try the array but no sucess. Can you help me? Thanks anyway!

Leave a Reply

Your email address will not be published. Required fields are marked *