How to highlight all current categories when viewing a single post?

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: