Call dynamic_sidebar but include/exclude named widgets?

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.

Read More

Is this possible?

Any insights much appreciated.

Related posts

Leave a Reply

3 comments

  1. 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;
    }
    
  2. 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;
    }
    
  3. 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;
        }