7

How can I get the number of widgets that are active on a specific sidebar? Is there a core function for this?

I want to add a class to each widget on a sidebar based on how many of them are displayed.

Thanks.

12

After some research and based on the answer from Eugene Manuilov I made a function that adds custom classes to widgets in a specific sidebar ('sidebar-bottom' in my case) based on the number of widgets set in that sidebar. This will suit perfectly in horizontal sidebars and themes based on twitter bootstrap that need spanX class to adjust the element's width.

function cosmos_bottom_sidebar_params($params) {

    $sidebar_id = $params[0]['id'];

    if ( $sidebar_id == 'sidebar-bottom' ) {

        $total_widgets = wp_get_sidebars_widgets();
        $sidebar_widgets = count($total_widgets[$sidebar_id]);

        $params[0]['before_widget'] = str_replace('class="', 'class="span' . floor(12 / $sidebar_widgets) . ' ', $params[0]['before_widget']);
    }

    return $params;
}
add_filter('dynamic_sidebar_params','cosmos_bottom_sidebar_params');
  • 1
    You shouldn't be calling wp_get_sidebars_widgets: This function’s access is marked private. This means it is not intended for use by plugin or theme developers, only in other core functions. It is listed here for completeness. developer.wordpress.org/reference/functions/… – Alexander Holsgrove Nov 23 '16 at 12:00
  • 1
    @AlexHolsgrove maybe we can use get_option( 'sidebars_widgets', array() ) ? – Guglie Apr 16 '17 at 17:34
1

Also, if you're looking to do things to the first and last widget, you can use the code below. I took nautilus7's code and combined it with MathSmath + durin's code over at http://wordpress.org/support/topic/how-to-first-and-last-css-classes-for-sidebar-widgets to target a specific sidebar, add span classes based on the number of widgets in the sidebar, and then add a custom class to the first and last widget of the groups.

function cur_target_sidebar_add_classes_to_params($params) {

global $my_widget_num; // Global a counter array
$sidebar_id = $params[0]['id'];

if ( $sidebar_id == 'sidebar' ) {

    $registered_widgets = wp_get_sidebars_widgets();
    if(!isset($registered_widgets[$sidebar_id]) || !is_array($registered_widgets[$sidebar_id])) { // Check if the current sidebar has no widgets
        return $params; // No widgets in this sidebar... bail early.
    }

    $number_of_widgets = count($registered_widgets[$sidebar_id]);
    $rounded_number_of_widgets = floor(12 / $number_of_widgets); //Rounds number of widgets down to a whole number

    if(!$my_widget_num) {// If the counter array doesn't exist, create it
        $my_widget_num = array();
    }

    if(isset($my_widget_num[$sidebar_id])) { // See if the counter array has an entry for this sidebar
        $my_widget_num[$sidebar_id] ++;
    } else { // If not, create it starting with 1
        $my_widget_num[$sidebar_id] = 1;
    }

    $classes = 'span' . $rounded_number_of_widgets;

    if($my_widget_num[$sidebar_id] == 1) { // If this is the first widget
        $classes .= ' first-widget ';
    } elseif($my_widget_num[$sidebar_id] == count($registered_widgets[$sidebar_id])) { // If this is the last widget
        $classes .= ' last-widget ';
    }

    $params[0]['before_widget'] = preg_replace('/class=\"/', 'class="' . $classes . ' ', $params[0]['before_widget'], 1);
    }

    return $params;
}
add_filter('dynamic_sidebar_params','cur_target_sidebar_add_classes_to_params');
  • Thanks. You can also add 'even' and 'odd' classes to the widgets. I did it that way originally, but I removed it because you can do the same with CSS3 selectors (nth-child). Anyway extra options don't hurt. – nautilus7 Jun 7 '12 at 23:21
0
function wpse_54162_get_widgets_count( $sidebar_index ) {
    global $wp_registered_sidebars;

    $index = "sidebar-{$sidebar_index}";

    $sidebars_widgets = wp_get_sidebars_widgets();
    if ( empty($wp_registered_sidebars[$index]) || !array_key_exists($index, $sidebars_widgets) || !is_array($sidebars_widgets[$index]) || empty($sidebars_widgets[$index]) )
        return 0;

    return count( (array) $sidebars_widgets[$index] );
}
  • Thanks for the answer, but now I realize that what I want can't be done. At least with a method I know... I want to add a class on each widget based on how many of them are on a sidebar. For example if there are 4 widgets I want them to have class x or if they are 3 I want them to have class y etc. This can't be done with simply counting the number of widgets because the class (any class) they get is defined uppon sidebar registering, not drawing. At this point no widgets are set. – nautilus7 Jun 4 '12 at 17:11
0

Lets try with below code

function sidebar_widget_init()
    {
        global $_wp_sidebars_widgets;
        if ( empty( $_wp_sidebars_widgets ) ) :
            $_wp_sidebars_widgets = get_option( 'sidebars_widgets', array() );
        endif;

        $sidebars_widgets_count = $_wp_sidebars_widgets;
        $sidebar_count = count( $sidebars_widgets_count[ 'sidebar3' ] );

        if($sidebar_count == 2){
            $sidebar_class = 'class_name1';
        } elseif($sidebar_count == 3){
            $sidebar_class = 'class_name2';
        } elseif($sidebar_count == 4){
            $sidebar_class = 'class_name3';
        }
        register_sidebar(array( 'name'          => __( 'Sidebar Footer', 'templatemesh' ),
                                'id'            => 'sidebar3',
                                'description'   => __( 'Widgets in this area will be shown on footer Sidebar.', 'templatemesh' ),
                                    'before_title'  => '<h3  class="widget_title">',
                                    'after_title'   => '</h3>',
                                    'before_widget' => '<div class="'.$sidebar_class.'"><div id="%1$s" class="widget %2$s" >',
                                    'after_widget'  => '</div></div>'
                    )
        );
    }
    add_action('widgets_init','sidebar_widget_init');
  • 1
    Any comments on how this works and how this is different from the other answers would be nice here. – tfrommen Aug 20 '15 at 9:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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