6

Is it possible to include or exclude specific named widgets that are assigned to a named dynamic_sidebar call?

For example, if I've registered a sidebar named "my_sidebar" and the user had placed a "Links" widget into it, I want to be able to include or exclude it based on a custom setting in my theme options panel.

Is this possible?

Any insights much appreciated.

3 Answers 3

7

dynamic_sidebar() calls wp_get_sidebars_widgets() to get all widgets per sidebar. I think filtering this output is the best way to remove a widget from an sidebar.

add_filter( 'sidebars_widgets', 'wpse17681_sidebars_widgets' );
function wpse17681_sidebars_widgets( $sidebars_widgets )
{
    if ( is_page() /* Or whatever */ ) {
        foreach ( $sidebars_widgets as $sidebar_id => &$widgets ) {
            if ( 'my_sidebar' != $sidebar_id ) {
                continue;
            }
            foreach ( $widgets as $idx => $widget_id ) {
                // There might be a better way to check the widget name
                if ( 0 === strncmp( $widget_id, 'links-', 6 ) ) {
                    unset( $widgets[$idx] );
                }
            }
        }
    }

    return $sidebars_widgets;
}
3
  • Thanks very much. I'm working on this now. Glad to know there's a way to do this.
    – Scott B
    Commented May 19, 2011 at 15:23
  • can you tell me the purpose of the ampersand before the $widgets variable in the foreach?
    – Scott B
    Commented Jun 16, 2011 at 16:23
  • @Scott: The ampersand makes sure we pass a reference to the $widgets array, and not a copy of it that will only exist in the foreach loop. If you leave it out, the unset( $widgets[$idx] ) will remove it from the copy of the array, and $sidebar_widgets will still have the complete array.
    – Jan Fabry
    Commented Jun 17, 2011 at 7:02
1

I am adding another answer to answer this question:- How to exclude certain widget from showing up on home/front page?

WordPress has an internal function _get_widget_id_base() I am not sure how safe to use it. But this is the method which WordPress uses to get widget ID base by using widget ID instead of strpos() and strncmp().

Example:-

add_filter('sidebars_widgets', 'conditional_sidebar_widget');
/**
 * Filter the widget to display
 * @param array $widets Array of widget IDs
 * @return array $widets Array of widget IDs
 */
function conditional_sidebar_widget($widets) {
    $sidebar_id = 'sidebar-1'; //Sidebar ID in which widget is set

    if ( (is_home() || is_front_page()) && !empty($widets[$sidebar_id]) && is_array($widets[$sidebar_id]) ) {
        foreach ($widets[$sidebar_id] as $key => $widget_id) {
            $base_id = _get_widget_id_base($widget_id);
            if ($base_id == 'recent-posts') {
                unset($widets[$sidebar_id][$key]);
            }
        }
    }

    return $widets;
}
0

Extending Jan's answer, I found strpos() rather than strncmp() for checking the widget name (it's faster.. )

Following you'll find a similar function (working & tested) that will take you to the same result:

 add_filter( 'sidebars_widgets', 'hide_widgets' );
 function hide_widgets( $excluded_widgets )
    {
        if ( is_page() /* Or whatever */ ) {
     //set the id in 'sidebar-id' to your needs
            foreach ( $excluded_widgets['sidebar-id'] as $i => $inst) {

     //in this example we'll check if the id for the rss widgets exists.(change it to suit your needs)

            $pos = strpos($inst, 'rss');

            if($pos !== false)
            {
                //unsetting the id will remove the widget 
                unset($excluded_widgets['sidebar-id'][$i]);
            }
        }    
    }
    return $sidebars_widgets;
    }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.