A simple filter to hide specific widgets on specific pages

It’s not uncommon to only want to show specific sidebar widgets or footer widgets in certain views. In the case below we didn’t want to show a client’s teaser widget of their recent installations when the visitor was already viewing any of their portfolio pages. So here’s a simple filter that does just that:

/**
 * Hide portfolio teaser widget on any portfolio page
 */
add_filter( 'widget_display_callback', function ( $instance, $widget, $args ) {
    return ( 'portfolio' === get_post_type() and 'portfolio_recent_installs' === $widget->id_base) ? false : $instance;
}, 10, 3 );

Aside: I’m a big fan of one-liners, hence the body of the filter only containing the return value. For those that prefer to build up the return value beforehand, here’s the same filter, but using many more lines of code:

/**
 * Hide portfolio teaser widget on any portfolio page
 */
add_filter( 'widget_display_callback', function ( $instance, $widget, $args ) {
    // the post type and widget ID to compare
    $post_type_to_compare = 'portfolio';
    $widget_id_to_compare = 'portfolio_recent_installs';
    
    // the current page's post type and current widget's base ID
    $post_type = get_post_type();
    $widget_id = $widget->id_base;
    
    // the Boolean results from each comparison
    $is_widget_match = $widget_id_to_compare === $widget_id;
    $is_post_type_match = $post_type_to_compare === $post_type;
    
    // the expression to determine which value will be returned
    if ( $is_post_type_match && $is_widget_match ) {
        return false;
    } else {
        return $instance;
    }
}, 10, 3 );

Refining the widget’s visibility

But we could go further. Say we wanted to:

  1. only hide a widget on very specific pages (e.g. the homepage), or;
  2. hide several widgets, or;
  3. only hide a widget on specific page templates, or;
  4. only show them in the left sidebar, or;
  5. hide when a combination of the above conditions are met.

All these scenarios can be achieved by modifying the filter above. Lets take one and modify the filter to support it. I’ll take item 5 with the following conditions:

  • hide a specific widget (portfolio_recent_installs);
  • only hide the widget in the footer area;
  • only hide on specific pages (homepage and partners);
/**
 * Hide portfolio teaser footer widget on the homepage, frontpage and 'partner' pages
 */
add_filter( 'widget_display_callback', function ( $instance, $widget, $args ) {
    return (
        'sidebar-footer' === $args['id'] and
        ( is_front_page() or is_page(['homepage', 'partners'])) and
        'portfolio_recent_installs' === $widget->id_base
    ) ? false : $instance;
}, 10, 3 );

So what have we changed to filter widgets with more granularity?

The string comparison:

'portfolio' === get_post_type()

has been replaced with two Boolean functions:

is_front_page()

and

is_page()

NB: is_page() takes either an array of strings or a single string and compares each string to the current page’s id, title and name.

And there’s an additional string comparison to determine which widget area we’re talking to:

'sidebar-footer' === $args['id']

Wrapping it up

So there it is, using filters to control the visibility of widgets is pretty straight forward stuff. But, if you find you’re struggling, please get in touch and we’ll gladly help. We have many years of WordPress experience, developing custom themes and plugins, and helping clients with all manner of performance and search engine optimisations.

Reply