wp_list_categories: get latest featured_image of category

You can use a custom Walker, the easiest of which in your case is the Walker_Category and extend it like so:

class CategoryThumbnail_Walker extends Walker_Category {
    // A new element has been stumbled upon and has ended
    function end_el( &$output, $category, $depth, $args ) {
        // Output the standard link ending
        parent::end_el( &$output, $category, $depth, $args );

        // Get one post
        $posts = get_posts( array(
            // ...from this category
            'category' => $category->cat_ID,
            'numberposts' => 1
        ) );
        // If a post has been found
        if ( isset($posts[0]) ) {
            // Get its thumbnail and append it to the output
            $featured = get_the_post_thumbnail( $posts[0]->ID, 'thumbnail', null );
            $output .= $featured;
        }
    }
}

Now your wp_list_categories can utilize that walker by supplying an additional walker argument like so:

wp_list_categories( array('walker' => new CategoryThumbnail_Walker()) );

As you can see we have two additional queries for each category, one to get the latest post, and one to get its featured image, so make sure that this overhead is acknowledged.

If you want to further customize the output you will have to override all of the functionality of end_el or start_el for the Walker_Category class.

Duplicates

To make sure that no duplicate images are shown you have to do the following things:

  • store the displayed image in an array
  • check with every new image whether it exists in the array
  • if it exists – get next post and check its image
  • if it does not exist, add it to array and output
  • understand what you’re doing, how it will work and how to turn in into working code in your context (by reading the docs and learning more about PHP and WordPress)

So the code would look something like this:

class CategoryThumbnail_Walker extends Walker_Category {

    // A new element has been stumbled upon and has ended
    function end_el( &$output, $category, $depth, $args ) {
        // Output the standard link ending
        parent::end_el( &$output, $category, $depth, $args );

        // Get one post
        $posts = get_posts( array(
            // ...from this category
            'category' => $category->cat_ID,
            'numberposts' => 10
        ) );

        // we'll record the seen images here
        if ( !isset($this->images_seen) ) $this->images_seen = array();

        foreach ( $posts as $post ) {
            // Get its thumbnail and append it to the output
            $featured = get_the_post_thumbnail( $post->ID, 'thumbnail', null );
            // have we already seen this image?
            if ( in_array($featured, $this->images_seen) ) continue;
            else {
                $this->images_seen []= $featured;
                $output .= $featured;
                break;
            }
        }
    }
}

Leave a Comment