HowTo: Add Class to Sidebar Widget List-Items

Update: 12/19/15 :
Here’s a plugin on Github that I developed (using the method in answer I provided below) adding support for changing all widget to bootstrap components/styling.


Wordpress Widgets Bootstrapped


Original Answer

I understand not wanting to use javascript, but it seems like overkill in my opinion to completely create a new widget just for the list-group class to be added to the widget <ul> html tag. If you look at what the list-group class actually does you’ll notice all it’s doing is removing default browser padding and adding some bottom margins.

.list-group {
    padding-left: 0;
    margin-bottom: 0;
}

Most likely you won’t even want the bottom margins there because you should be adding the default margins to the .widget or similar sidebar before_widget class in your themes css.

For example: Setting default sidebar widget margins

.sidebar-primary .widget {
    margin-bottom: 20px;
}

So essentially, the only real benefit the class is giving you is removing the default browser padding for lists. This is also something (in my opinion) you should probably be doing in your css since this how bootstrap is handling it anyway.

.sidebar-primary .widget.widget_categories {
    padding-left: 0;
}

As for the the list-group-item classes on the <li> elements we can use the wp_list_categories filter for that. And while we’re at it we might as well change the styling for count as well to bootstraps formatting…

function bs_categories_list_group_filter ($variable) {
   $variable = str_replace('<li class="cat-item cat-item-', '<li class="list-group-item cat-item cat-item-', $variable);
   $variable = str_replace('(', '<span class="badge cat-item-count"> ', $variable);
   $variable = str_replace(')', ' </span>', $variable);
   return $variable;
}
add_filter('wp_list_categories','bs_categories_list_group_filter');

If you must have list-group added with php and don’t want to use css or javascript, you do have a few other options…

Option 1 – Use output buffering in your theme templates:

ob_start();
dynamic_sidebar( 'registered-sidebar-name' );
$sidebar_output = ob_get_clean();
echo apply_filters( 'primary_sidebar_filter', $sidebar_output );

Then in your function.php you would use the primary_sidebar_filter and use regex to replace the default html for

function bs_add_list_group_to_cats( $sidebar_output ) {

    // Regex goes here...
    // Needs to be a somewhat sophisticated since it's running on the entire sidebar, not just the categories widget. 

    $regex = "";
    $replace_with = "";
    $widget_output = preg_replace( $regex , $replace_with , $widget_output );    

    return $sidebar_output;

}
add_filter( 'primary_sidebar_output', 'bs_add_list_group_to_cats' );

Option 2 – Use output buffering in a plugin / outside of your templates:

This is probably the best way to do this as it gives you a lot more freedom to customize any widgets. This can either be added as a plugin thanks to Philip Newcomer or directly to your functions.php with this code.

Then to use the new callback function for your category widget filtering (to add bootstrap styling) you’d add this to your functions.php:

function wpse_my_widget_output_filter( $widget_output, $widget_type, $widget_id ) {
    if ( 'categories' == $widget_type ) {
        $widget_output = str_replace('<ul>', '<ul class="list-group">', $widget_output);
        $widget_output = str_replace('<li class="cat-item cat-item-', '<li class="list-group-item cat-item cat-item-', $widget_output);
        $widget_output = str_replace('(', '<span class="badge cat-item-count"> ', $widget_output);
        $widget_output = str_replace(')', ' </span>', $widget_output);
    }      
      return $widget_output;
}
add_filter( 'widget_output', 'my_widget_output_filter_footer', 10, 3 ); 

Leave a Comment