8

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.

4 Answers 4

13

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');
2
  • 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/… Nov 23, 2016 at 12:00
  • 1
    @AlexHolsgrove maybe we can use get_option( 'sidebars_widgets', array() ) ?
    – Guglie
    Apr 16, 2017 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');
1
  • 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, 2012 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] );
}
1
  • 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, 2012 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
  • 1
    Any comments on how this works and how this is different from the other answers would be nice here.
    – tfrommen
    Aug 20, 2015 at 9:08

Your Answer

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

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