wp_list_categories: get latest featured_image of category

I was thinking about a nicer way to display the categories in my sidebar.
Instead of a plain list style, I’d like to have images / thumbnails show up as well.

Currently I’m using the following:

<?php wp_list_categories('show_last_updated=1&show_count=1&title_li='); ?>

Simply displaying the name/link + post count of each category.
I want to keep, that but also add a thumbnail to it.

I’ve been browsing through this board for answers and also thought about how to do it, but I couldn’t find a solution yet.

I guess I have to create a function that gets the featured image of the latest post in that category. If a post has more categories, that also shouldn’t cause any problems.

Creating a loop with only 1 post in that category and only outputting the thumbnail would be an option, but to set it so that the thumbnail and category match could be a hassle.
I’m sure that there must be a better way to do it.

I’m not looking for a plugin (as I’m sure there are some), I want to hardcode it.

If anybody has a good idea or some advice how to approach this, then please help me out.

Thank you very much!

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

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;
            }
        }
    }
}

Method 2

I know you said you wanted to not use a plugin, but I am still going to recommend this: Taxonomy Images

You can always just hardcode it into your functions file.
It adds a nice little interface to the categories for adding a specific images to each category, and supplies some easy ways to get that image on your pages. It also works on custom taxonomies with no problem.

I mention the plugin because, for a project I was working on I was trying your first approach (to just show the featured image of the latest post in that category) but when a particular post was in more than one category, the same image was repeated multiple times and looked funky.

Having an image for each category kept a consistent look. The plugin is easy to use so the client could change the image with no probleem. I also wrote a little if statement in case the client created a new category but failed to add an image so that it then went on to use the thumbnail of the latest post for that category (sort of long-winded but you get the point):

 <?php
      while ($my_query->have_posts()) : $my_query->the_post(); ?>
        <!--thumbnail -->
<? /*asks if the category has an image...else use the post Thumbnail...then  if not use the wedding.jpg  */ ?>
<span  class="lighten"><a href="<?= add_query_arg('t', strtolower($term->name), home_url( '/videos/' )); ?>" rel="nofollow noreferrer noopener">

    <?php 
    $image_link =  "<a href=".home_url( '/' ).(strtolower($term->name))." rel="nofollow noreferrer noopener">";
    $image = apply_filters( 'taxonomy-images-list-the-terms', '', array(
        'taxonomy'     => 'video_types',
        'image_size' => 'detail',
        'after'        => '',
        'after_image'  => '',
        'before'       => '',
        'before_image' => ''
         )
    );


    if ( ! empty( $image ) ) {print $image;}

            elseif ( has_post_thumbnail() ) {the_post_thumbnail(); } 
             else { ?>
    <img src="<?php bloginfo('template_directory'); ?>/images/weddings.jpg" alt="<?php echo $term->name;?>" />
    <?php } ?></a></span><!--#lighten -->
        </div><!--#thumb -->
           <?php
          endwhile;
          ?>
      <?php
        }
      }
    }
    wp_reset_query();  // Restore global post data stomped by the_post().
    ?>


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x