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.

When viewing a single post, the wp_list_categories function already marks the current category of this particular post by assigning the current-cat CSS class.

If the post is mapped to multiple categories, however, only the first category (hierarchically ordered) is marked.

How can I assign the current-cat class to all categories of the post?

share|improve this question

1 Answer 1

up vote 3 down vote accepted

In order to assign the current-cat class to all categories of the current post we will extend the wp_list_categories function by means of a dedicated Walker.

Suppose the current setup looks as follows:

$args = array(
    'hierarchical' => 0,
    'title_li' => '',
    'show_option_none' => '',
);
wp_list_categories($args);

Now we add the walker (which we will set up in the next step), and a new argument highlight that will provide an array of the current post's category IDs and that will be handled by our walker. Of course, we also have to populate the very array.

This leads to the following:

$highlight = array();
$categories = get_the_category();
foreach ($categories as $category)
    $highlight[] = $category->cat_ID;

$args = array(
    'hierarchical' => 0,
    'title_li' => '',
    'show_option_none' => '',
    'highlight' => $highlight,
    'walker' => new TFCategoryWalker(),
);
wp_list_categories($args);

The last step is the walker itself. Basically, we take the default Walker_Category class and add what's missing. Therefore we only have to customize the start_el function. Directly after the $class variable has been instantiated we add the following:

if (! $highlight) $highlight = array();
elseif (! is_array($highlight)) $highlight = array($highlight);
if (in_array($category->term_id, $highlight)) $class .= ' current-cat';

And that's it.


Altogether, this is the new walker class, which we put in our functions.php file:

class TFCategoryWalker extends Walker_Category {

    function start_el( &$output, $category, $depth = 0, $args = array(), $id = 0 ) {
            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 = 'cat-item cat-item-' . $category->term_id;

                    // START customization
                    if (! $highlight) $highlight = array();
                    elseif (! is_array($highlight)) $highlight = array($highlight);
                    if (in_array($category->term_id, $highlight)) $class .= ' current-cat';
                    // END customization

                    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";
            }
    } // function start_el

} // class TFCategoryWalker

References:

share|improve this answer
1  
I'm pretty sure that you could alter $category if you pass it by reference to a callback for apply_filters( 'list_cats', $cat_name, $category );. This would make it able to fake the result of if ( $category->term_id == $current_category ) for other items as well. But it's just a wild guess. +1 on Q and A. –  kaiser Sep 28 '13 at 19:37
1  
@kaiser In fact, I spent some time thinking about using the exact same filter you mentioned. However, I couldn't think of a way that wouldn't affect some other functionality. If I were to alter $category (or to be more precise: the category's ID), this would also affect the cat-item-{term_id} CSS class. That's why I ended up using a dedicated, extended walker. Apart from the purpose described in my question, one could also feed another set of IDs into the $highlight array/parameter, not just the current categories but some important cats that should be highlighted no matter what... –  t f Sep 29 '13 at 10:04

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.