How to Create Dynamic Featured Images in WordPress

When most people want a featured image (say a regular graphic for a “Discussion” feature), they use the “Set featured image” option inside WordPress. However, if you’re like me, you create feature graphics to match your theme. But then what happens when you change your blog design and update your “Discussion” feature graphic? All of your old discussions will no longer match your new design, because they’ll be using the old graphic!

To combat this, and to make setting featured images easier (actually, non-existent), I use dynamic featured images.

Basically, the normal way of displaying a featured image is like this:

Use the “Set featured image” feature inside your theme. Then add this code somewhere in your theme to display that image:

<?php 
if ( has_post_thumbnail() ) {
  the_post_thumbnail();
} 
?>

That says “if there is a featured image, show the featured image”.

Instead of doing that, I use logic like this:

  • If the post has a featured image, then show that featured image.
  • Or else, if the category this post is in has a designated image saved inside my theme, display that image automatically.

Then I don’t upload a featured image to my “Discussion” or “Bitchin’ Book Blog” posts at all! Instead, it automatically uses an image I’ve specified in my theme. And if I change the image inside my theme, it automatically changes the image everywhere! But, if I want, I can override the default image by uploading a featured image anyway.

Here’s how the code works

function nosegraze_get_featured() {
	$output = '';

	// If this post has a featured image, use that
	if ( has_post_thumbnail( get_the_ID() ) {
		$featured = wp_get_attachment_image_src( get_post_thumbnail_id( get_the_ID() ), 'full' );
		$img = $featured[0];
		$output .= '<a href="' . get_permalink() . '" title="' . the_title_attribute('echo=0') . '"><img src="' . $img . '" alt="' . get_the_title() . '"></a>';
	}
	// There is no featured image, so let's check for a theme thumbnail
	else {
		$category = get_the_category();
		foreach( $category as $the_cat ) {
			$image_path = $the_cat->category_nicename . '.png';
			if ( file_exists( get_stylesheet_directory() . '/images/thumbnails/' . $image_path ) ) {
				$output .= '<a href="' . get_permalink() . '"><img src="' . get_stylesheet_directory_uri() . '/images/thumbnails/' . $image_path . '" alt="' . get_the_title() . '"></a>';
			}
		}
	}
	
	return $output;
}

Wow, so what’s going on here?

First, I check to see if the current post has a featured image. If it does, then I display that. If it doesn’t, then I get a list of the post’s categories. I get the “nice name” of each category (the slug). So for “Stacking the Shelves” it would be stacking-the-shelves (all lowercase, dashes instead of spaces, no symbols). For each category “nice name”, I check to see if a file exists inside this path:

{Path to my theme folder}/images/thumbnails/category-nice-name.png

So an example would be: /images/thumbnails/discussions.png

If it does exist, then I display that image.

So here’s an example of what my thumbnails folder looks like:

Dynamic featured images in WordPress

You can see my category images there, plus a variety of size options that I use in other places throughout my blog.

How to use the code

The code assumes you have a folder inside your theme folder called “images”, then a folder inside that folder called “thumbnails”. You would place your category images inside that folder and name them appropriately (use the “Category Slug”).

You would paste the code function inside your theme’s functions.php file.

You would actually display the image one of two ways:

Add code inside your single.php file

You would add code like this wherever you want the image to appear inside your single.php file:

<?php echo nosegraze_get_featured(); ?>

The downside to this method is that the image will not appear in RSS feeds.

Add the code to the the_content filter

Alternatively, you can add another function to your functions.php file like so:

function add_before_content($content) {
	return nosegraze_get_featured() . $content;
}
add_filter('the_content', 'add_before_content', 20);

This will automatically insert the image before your post content.

What else do I use this for?

I use this same dynamic image method for:

  • Every single thumbnail on my site (featured images, post thumbnails on archive pages, the thumbnails on my Latest/Popular/Upcoming widget)
  • My “Verdict” word ratings.
  • My review “badges” (example: in my Sweet Evil review I have badges for “giggle book” and “swoon-a-licious” at the bottom)

Do you use banner graphics that match your design? Have you ever gone back and edited all your old ones (or thought about it) to match a new design?

Photo of Ashley
I'm a 28 year old California girl living in England (I fell in love with a Brit!). My three great passions are: books, coding, and fitness. more »

Don't miss my next post!

Sign up to get my blog posts sent directly to your inbox (plus exclusive store discounts!).

You might like these

28 comments

  1. This is so cool! I’m going to try it. I HAVE been wanting to change my graphics on old features to match my new theme, but it seemed like such a pain that I never started on it. It’ll be much easier going forward to have dynamic featured images, though, so I’m totally going to do this and then fix up my old posts.

    Thanks so much, Ashley! <3

    Anastasia @ Here There Be Books recently posted: REVIEW: A Long, Long Sleep by Anna Sheehan
  2. It’s funny that I was looking for a tutorial like this a while ago and you just posted this. xD Anyway, for those who aren’t good with code or changing their themes there’s a plugin that actually changes all of your featured images for you – Quick Featured Images. It’s what I used to change featured images from months ago instead of having to do it manually. I like your method much better, but this might help those who aren’t very good with code. 😛 Great post!

    1. Yeah this method definitely requires you to be familiar with code, or at least unafraid of digging in! But that plugin would be a great alternative. 🙂 Thanks for sharing!

    1. Sorry to post again but I want to try this for my new site. So say for example I want an image placed in the middle of the post or at the end for specific types of posts, how does the image know where to display? Or will it only appear at the top of bottom? For reviews I have book info at the top, the standard image between the book info and the review, and then eating at the bottom. Is there a way to make it so my review image displays in between the book info and before the review by using this code? I hope in making so sense lol.

      1. The image always appears at the top with the code I gave you. You can force it to display after the book info as long as you’re using UBB and the second method (“Add the code to the the_content filter”). You just have to change the priority.

        I gave this code in the post:

        add_filter('the_content', 'add_before_content', 20);

        So you add the image before the content with a priority of 20. You would want to change that to something else, like maybe this:

        add_filter('the_content', 'add_before_content', -1);

        That adds the image before the content with a priority of -1 (so as soon as possible). So if you think about it, the image will be added before the content first, then UBB gets added at 10, but at that point the image is already at the top so when the UBB book info gets added to before the content, it will get added before the image.

        Kind of confusing, but it should work. 🙂

  3. And I’m totally typing all this from my phone and auto correct messed it up at the end. It should be *rating at the bottom, and * I hope I’m making some sense. 🙂 thanks for your help!

  4. Your tutorials are always so easy to follow. And although I’ve followed this one, I really don’t know where I’ve gone wrong – as it’s not working. o.O I’ve added the codes to my .fuctions, and added the path to the image. Do you have to do something different when editing your posts? I’ve added the category ‘book-haul’ into the category_nicename area, and it’s still not working. Any idea what I’m doing wrong?

    1. Can you link me to one of your posts where this should be showing up? Then can you also tell me where you placed your images and paste me EXACTLY what you put in your functions.php file? Please put a <pre> tag before the code and a </pre> tag afterwards when you paste it.

  5. I used the code in my blog it’s not working. It displays the featured image; but the category/theme thumbnail won’t display. I’m using a child theme. In cpanel I created a folder childthemeimusing – images – thumbnails – quote.png I wonder where I got it wrong?

    1. Since you’re on a child theme, you’ll want to replace this section:

      if (file_exists( TEMPLATEPATH . '/images/thumbnails/' . $image_path )) {
      	$output .= '<a href="' . get_permalink() . '" rel="nofollow"><img src="' . get_bloginfo('template_directory') . '/images/thumbnails/' . $image_path . '" alt="' . get_the_title() . '"></a>';
      }

      With this:

      if (file_exists( get_stylesheet_directory() . '/images/thumbnails/' . $image_path )) {
      	$output .= '<a href="' . get_permalink() . '" rel="nofollow"><img src="' . get_stylesheet_directory_uri() . '/images/thumbnails/' . $image_path . '" alt="' . get_the_title() . '"></a>';
      }

      Hope that helps. 🙂

      1. Hello. Thanks. It works for the single posts. However it doesn’t display the category/theme thumbnail for the posts page (Settings – Reading – Front page displays – select static page – Posts page – I select the page where all the recent posts will be displayed).

        1. As long as you’re placing it inside the loop, it should work. There’s literally no difference between the code on the archive and the code on single post pages.

        2. There is a content.php in my child theme. I inserted this code echo nosegraze_get_featured but it still didn’t display/fetch the category/theme thumbnail.

          1. I’m not really sure what to tell you, because I know the code does work. It’s possible that your theme isn’t using content.php on that particular page, which is why it’s not showing up.

            1. Oh this is exciting. 🙂 In content.php, there is a row that has two columns – first column is for excerpt; second column is for the thumbnail. I inserted the code in the second column; it didn’t work. But when I inserted the code in the first column just after the excerpt – it works!

              1. Wonderful. 🙂 All themes are set up differently so sometimes it’s hard to navigate and figure out where to place your code.

Recent Posts

    Random Posts