How to modify lists like ‘Categories’ and ‘Blogroll’ in WordPress?

November 25, 2009 at 9:55 am

Every time you build a theme for Wordpress you are bound to the CSS classes which are hard-coded.
Here’s a method to overwrite the default method for printing the HTML for those lists.

In this example I’ll use the ‘Categories’ widget, although it can be done with most lists which are found at WordPress.

First, create a new filter in your functions.php file:

<?php
function my_filter_widget_categories($args) {
   $walker = new My_Walker_Category();
   $args = array_merge($args, array('walker' => $walker));
   return $args;
}
add_filter('widget_categories_args', 'my_filter_widget_categories');
?>

This filter does nothing, except for defining a custom Walker Class.

The following class (named My_Walker_Category) also have to be placed into your functions.php and is basically a copy of the original Walker_Category class, which can be found in /wp-includes/classes.php.

<?php
class Walker_Category_W5 extends Walker_Category {
   function start_el(&$output, $category, $depth, $args) {
      extract($args);
      $cat_name = esc_attr( $category->name);
      $cat_name = apply_filters( 'list_cats', $cat_name, $category );
      $link = '<a href="' . get_category_link( $category->term_id ) . '" ';
      if ( $use_desc_for_title == 0 || empty($category->description) )
         $link .= 'title="' . 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>';
      $link .= $cat_name;
      if(!empty($category->description)) {
         $link .= ' <span>'.$category->description.'</span>';
      }
      $link .= '</a>';
      if ( (! empty($feed_image)) || (! empty($feed)) ) {
         $link .= ' ';
         if ( empty($feed_image) )
            $link .= '(';
         $link .= '<a href="' . get_category_feed_link($category->term_id, $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 ( isset($show_count) && $show_count )
         $link .= ' (' . intval($category->count) . ')';
      if ( isset($show_date) && $show_date ) {
         $link .= ' ' . gmdate('Y-m-d', $category->last_update_timestamp);
      }
      if ( isset($current_category) && $current_category )
         $_current_category = get_category( $current_category );
      if ( 'list' == $args['style'] ) {
          $output .= "\t<li";
          $class = 'cat-item cat-item-'.$category->term_id;
          if ( isset($current_category) && $current_category && ($category->term_id == $current_category) )
             $class .=  ' current-cat';
          elseif ( isset($_current_category) && $_current_category && ($category->term_id == $_current_category->parent) )
             $class .=  ' current-cat-parent';
          $output .=  '';
          $output .= ">$link\n";
       } else {
          $output .= "\t$link<br />\n";
       }
   }
}
?>

As you can see I only copied the ‘start_el’ method, since this is the only part I would like to modify but if you need to change more you can copy the complete class without a problem.

The change I made is bold and as a reference I commented the original line. As you can see I added the category description to the link between a <span>, which gives me the opportunity to create subtitles to the categories.

Although this example only changes the Walker_Category class you also can use: Walker_Page (for bloggroll or navigation), Walker_PageDropdown and Walker_CategoryDropdown which can be found in classes.php and Walker_Comment (comment listing) in comment-template.php.

This recipe has been writed by Johan de Jong. Big thanks to him for contributing to WpRecipes!

Tags: