Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

The newest version of Bootstrap (v3.0) adds a new List Group component which has the following structure:

<ul class="list-group">
  <li class="list-group-item">Cras justo odio</li>
  <li class="list-group-item">Dapibus ac facilisis in</li>
  <li class="list-group-item">Morbi leo risus</li>
  <li class="list-group-item">Porta ac consectetur ac</li>
  <li class="list-group-item">Vestibulum at eros</li>
</ul>
  1. I would like to be able to add a class to the ul (i.e. <ul class="list-group">)
  2. I would like to style my Category sidebar widget to support this new component, but as you see, this requires classes on each li item.

In reading some similar posts, one option I found is to use jQuery to add the class to each li, but I am concerned about the dreaded FOUC.

Is there some WordPress function that gets me to my goal?

Please advise,

Update:

I was able to add classes to the individual li's by creating a Custom Walker which extends Walker_Category (see code below), but this still does not get me to the ul which also needs a class added (eg <ul class="list-group">).

class Walker_Category_BS extends Walker_Category {
    function start_el( &$output, $category, $depth = 0, $args = array() ) {
        extract($args);

        $cat_name = esc_attr( $category->name );
        $cat_name = apply_filters( 'list_cats', $cat_name, $category );
        $link = '<a href="' . esc_url( get_term_link($category) ) . '" ';
        if ( $use_desc_for_title == 0 || empty($category->description) )
            $link .= 'title="' . esc_attr( sprintf(__( 'View all posts filed under %s' ), $cat_name) ) . '"';
        else
            $link .= 'title="' . esc_attr( strip_tags( apply_filters( 'category_description', $category->description, $category ) ) ) . '"';
        $link .= '>';
        $link .= $cat_name . '</a>';

        if ( !empty($feed_image) || !empty($feed) ) {
            $link .= ' ';

            if ( empty($feed_image) )
                $link .= '(';

            $link .= '<a href="' . esc_url( get_term_feed_link( $category->term_id, $category->taxonomy, $feed_type ) ) . '"';

            if ( empty($feed) ) {
                $alt = ' alt="' . sprintf(__( 'Feed for all posts filed under %s' ), $cat_name ) . '"';
            } else {
                $title = ' title="' . $feed . '"';
                $alt = ' alt="' . $feed . '"';
                $name = $feed;
                $link .= $title;
            }

            $link .= '>';

            if ( empty($feed_image) )
                $link .= $name;
            else
                $link .= "<img src='$feed_image'$alt$title" . ' />';

            $link .= '</a>';

            if ( empty($feed_image) )
                $link .= ')';
        }

        if ( !empty($show_count) )
            $link .= ' (' . intval($category->count) . ')';

        if ( 'list' == $args['style'] ) {
            $output .= "\t<li";
            $class = 'list-group-item cat-item cat-item-' . $category->term_id;
            if ( !empty($current_category) ) {
                $_current_category = get_term( $current_category, $category->taxonomy );
                if ( $category->term_id == $current_category )
                    $class .=  ' current-cat';
                elseif ( $category->term_id == $_current_category->parent )
                    $class .=  ' current-cat-parent';
            }
            $output .=  ' class="' . $class . '"';
            $output .= ">$link\n";
        } else {
            $output .= "\t$link<br />\n";
        }
    } /* end start_el */

} /* end Walker_Category_BS */

Update 02:

After viewing default-widgets.php in the core, I decided to create a new widget (WP_Widget_Categories_BS, see code below) wherein I basically, copied all the code from the default category widget and simply modified the the UL to add the necessary class.

<?php 

/**
 * Categories widget class
 *
 * @since 2.8.0
 */
class WP_Widget_Categories_BS extends WP_Widget {

    function __construct() {
        $widget_ops = array( 'classname' => 'widget_categories_bs', 'description' => __( "A list or dropdown of categories for Bootstrap 3.0" ) );
        parent::__construct('categories', __('Boostrap Categories'), $widget_ops);
    }

    function widget( $args, $instance ) {
        extract( $args );

        $title = apply_filters('widget_title', empty( $instance['title'] ) ? __( 'Categories' ) : $instance['title'], $instance, $this->id_base);
        $c = ! empty( $instance['count'] ) ? '1' : '0';
        $h = ! empty( $instance['hierarchical'] ) ? '1' : '0';
        $d = ! empty( $instance['dropdown'] ) ? '1' : '0';

        echo $before_widget;
        if ( $title )
            echo $before_title . $title . $after_title;

        $cat_args = array('orderby' => 'name', 'show_count' => $c, 'hierarchical' => $h);
        if ( $d ) {
            $cat_args['show_option_none'] = __('Select Category');
            wp_dropdown_categories(apply_filters('widget_categories_dropdown_args', $cat_args));
?>

<script type='text/javascript'>
/* <![CDATA[ */
    var dropdown = document.getElementById("cat");
    function onCatChange() {
        if ( dropdown.options[dropdown.selectedIndex].value > 0 ) {
            location.href = "<?php echo home_url(); ?>/?cat="+dropdown.options[dropdown.selectedIndex].value;
        }
    }
    dropdown.onchange = onCatChange;
/* ]]> */
</script>

<?php
        } else {
?>
        <ul class="list-group">
<?php
        $cat_args['title_li'] = '';
        wp_list_categories(apply_filters('widget_categories_args', $cat_args));
?>
        </ul>
<?php
        }

        echo $after_widget;
    }

    function update( $new_instance, $old_instance ) {
        $instance = $old_instance;
        $instance['title'] = strip_tags($new_instance['title']);
        $instance['count'] = !empty($new_instance['count']) ? 1 : 0;
        $instance['hierarchical'] = !empty($new_instance['hierarchical']) ? 1 : 0;
        $instance['dropdown'] = !empty($new_instance['dropdown']) ? 1 : 0;

        return $instance;
    }

    function form( $instance ) {
        //Defaults
        $instance = wp_parse_args( (array) $instance, array( 'title' => '') );
        $title = esc_attr( $instance['title'] );
        $count = isset($instance['count']) ? (bool) $instance['count'] :false;
        $hierarchical = isset( $instance['hierarchical'] ) ? (bool) $instance['hierarchical'] : false;
        $dropdown = isset( $instance['dropdown'] ) ? (bool) $instance['dropdown'] : false;
?>
        <p><label for="<?php echo $this->get_field_id('title'); ?>"><?php _e( 'Title:' ); ?></label>
        <input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo $title; ?>" /></p>

        <p><input type="checkbox" class="checkbox" id="<?php echo $this->get_field_id('dropdown'); ?>" name="<?php echo $this->get_field_name('dropdown'); ?>"<?php checked( $dropdown ); ?> />
        <label for="<?php echo $this->get_field_id('dropdown'); ?>"><?php _e( 'Display as dropdown' ); ?></label><br />

        <input type="checkbox" class="checkbox" id="<?php echo $this->get_field_id('count'); ?>" name="<?php echo $this->get_field_name('count'); ?>"<?php checked( $count ); ?> />
        <label for="<?php echo $this->get_field_id('count'); ?>"><?php _e( 'Show post counts' ); ?></label><br />

        <input type="checkbox" class="checkbox" id="<?php echo $this->get_field_id('hierarchical'); ?>" name="<?php echo $this->get_field_name('hierarchical'); ?>"<?php checked( $hierarchical ); ?> />
        <label for="<?php echo $this->get_field_id('hierarchical'); ?>"><?php _e( 'Show hierarchy' ); ?></label></p>
<?php
    }

} // end WP_Widget_Categories_BS

Combined with a Custom Walker I created (Walker_Category_BS) I now have what I wanted.

Analysis

Is this the best way to do it? Don't know as I have have received zero feedback so far, and this is the first time i've done this (hence the question), but ...it works! I could use a review.

Debug Warning

Concerning my Custom Category Walker Walker_Category_BS, i'm seeing this message

"Strict standards: Declaration of Walker_Category_BS::start_el() should be compatible with Walker::start_el(&$output, $object, $depth = 0, $args = Array, $current_object_id = 0) in C:\wamp\www\mysite\wp-content\themes\mytheme\assets\inc\Walker_Category_BS.php"

It appears to be a warning, of some sort.

share|improve this question
    
Please move your solution to the answer, that is more in line with site's mechanics. –  Rarst Sep 12 '13 at 21:23
add comment

2 Answers

what about creating a seperate sidebar for this widget and adding class using register_sidebar funciton ?

register_sidebar(array(
    'name' => 'First_sidebar',
    'id' => 'sidebar-1',
    'class'         => 'ul-class-name',
    'before_widget' => '<div class="well">',
    'after_widget' => '</div>',
    'before_title' => '<h4>',
    'after_title' => '</h4>'
));
share|improve this answer
1  
I created a new sidebar and added a class to it. Nothing showed in the HTML. Also, after looking at several tutorials (and several books) not one even mentions the class attribute. The codex states "class - CSS class name to assign to the widget HTML (default: empty)." but then the example provided does not even use that parameter. At this point, I have NO IDEA what this attribute actually does. ...go figure. –  sleeper Sep 9 '13 at 7:28
    
It appears that the class parameter only shows on the backend and only on the containing div, not the UL. –  sleeper Sep 9 '13 at 9:54
add comment
up vote 0 down vote accepted

Update: I fixed the debug warning and everything appears to be working. In the absence of any other comments, I will accept my own solution outlined in the original questions updates.

share|improve this answer
    
I have been (and I am still) in this situation too. I d try your solution but it is just ridiculous it has to be so damn complicated... I understand that in principle it is unnecessary because you can use the class of the sidebar to reference the <ul> but it became a nightmare when it comes to bootstrap. –  toto_tico Mar 11 at 9:23
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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