Add classname to the_category() function?

is it possible to use add_filter or something similar to add the slug of the category as classname to the the_category() function?

Right now when using the_category() the output looks like this …

Read More
<ul class="post-categories">
    <li>
        <a href="http://mysite.com/something" title="" rel="category tag">News</a>
    </li>
</ul>

Is it possible to somehow get this …

<ul class="post-categories">
    <li class="category-news">
        <a href="http://mysite.com/something" title="" rel="category tag">News</a>
    </li>
</ul>

Or something similar, at least some classname with the slug of the category so I can select it via CSS?

Thank you in advance, matt.

Related posts

Leave a Reply

2 comments

  1. First locate the_category() in the Codex. Scroll down to the bottom of the page to “Source Code”. There is a link “the_categfory() is located in …”. Click the link, you will be redirected to the source code. Alternativly open the file wp-includes/category-template.php in your IDE or editor.

    Now search for function the_category(). You will see that the function calls another function get_the_category_list(). Search for this function too. And now read the code and search for apply_filters() or add_action()

    As you can see, there is only one apply_filters() call at the end of the function. If you read the code carefully, you know now that you can only filter the complete html created by the_category().

    There are several ways to modifiy the html. DOMDocument is one of them, a good old preg_replace_callback() another one.

    function add_class_callback( $result ) {
    
      $class = strtolower( $result[2] );
      $class = str_replace( ' ', '-', $class );
      // do more sanitazion on the class (slug) like esc_attr() and so on
    
      $replacement = sprintf( ' class="%s">%s</a>', $class, $result[2] );
      return preg_replace( '#>([^<]+)</a>#Uis', $replacement, $result[0] );
    
    }
    
    function add_category_slug( $html ) {
    
      $search  = '#<a[^>]+(>([^<]+)</a>)#Uuis';
      $html = preg_replace_callback( $search, 'add_class_callback', $html );
    
      return $html;
    }
    
    add_filter( 'the_category', 'add_category_slug', 99, 1 );
    

    Thats easy, isn’t it? Apply a filter on the_category hook. Search for <a followed by some chars but not >[group the chars until <]</a>, pass the result to the callback function. The callback function retrieve an array with all search results, we pick the last one, this is the text of the link. Then create a class from the text, please sanitize this very well (by your own). Last but not least, insert the class attribute and return the generated result back to preg_replace_callback() weher it is replaced with the search result.

    Yes, I like DOM manipulation very much… not 😉

    Oh, I forgot. You can do this also with jQuery. Search for the class ‘.post-categories’, grep all link tags inside a list tag, walk over the result and get the href attributes, convert it to a propper classname, add the class with .addClass(class) to the link tag.

  2. While sanitizing for classNames can be very hard in some languages i prefere @powerbuoy’s comment and figured that out:

    function yourTheme_category_class($thelist){
      $categories = get_the_category();
    
      if ( !$categories || is_wp_error($categories) ) {
        return $thelist;
      }
    
      $output = '<ul class="post-categories">';
      foreach ( $categories as $category ) {
        $output .= '<li class="category-' . $category->slug . '"><a href="' . esc_url(get_category_link($category->term_id)) . '">' . $category->name . '</a></li>';
      }
      $output .= '</ul>';
    
      return $output;
    }
    add_filter( 'the_category', 'yourTheme_category_class');
    

    i hope that may help, cheers