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?

1 Answer
1

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:

  • get_the_category function Codex page
  • Walker class Codex page
  • Walker_Category class source

Leave a Reply

Your email address will not be published. Required fields are marked *