WordPress Post Thumbnails Revisited

Shortly after the release of WordPress 2.9, I published my technique for bulletproof post thumbnails. Since then, it’s evolved yet simplified into a more robust solution, specifically for use in WordPress themes. The problem, was that each image uploaded was generating a new set of images in various sizes, on top of the three that WordPress creates by default. This resulted in 6 or 7 images, instead of just a handful. While this isn’t really a huge deal, it means you’re going to be using more space on your server, and the uploads directory will get a bit unruly.

From the Ground Up

I’m going to assume you haven’t read my original article, and aren’t familiar with implementing post thumbnails in a WordPress theme. The first step, is to activate post thumbnails in your functions.php template. If you don’t see functions.php in your theme directory, create one.

if (function_exists('add_theme_support')) {
	add_theme_support('post-thumbnails');
}

Note: If you’re creating a new functions.php template, you’ll need to wrap that in a php tag.

Dynamic Image Resizing Instead of Physical Files

At this point, you’re able to create additional images at various sizes, but that’s where this implementation differs from the original. Instead of having WP create physical files on upload, we’re going to use the TimThumb image resizing script to create the new image sizes on the fly. Download the latest version of TimThumb and add it to your theme directory. Now, create a directory named “cache” and make sure it has appropriate write permissions (755 or 777, depending on your server), also in your theme directory.

For Theme Developers

Theme developers have to try and anticipate every situation to ensure their product works for as many people as possible. Because of this, the implementation that’s used in my themes is still pretty complex. I’m now in the habit of creating a file to include where thumbnails are present, and would suggest you do the same.

<?php
	// Checks to see if there is a post thumbnail, or image specified via custom field
	if (has_post_thumbnail() || get_post_meta($post->ID, 'post_image_value', true)) {
		// Opens a container called post-tnail and accompanying link to enclose the image
		echo '<div class="post-tnail"><a href="'.get_permalink().'" title="'.get_the_title().'">';
		// Creates a function for both methods of attaching images to posts for inclusion later on
		$thumbnail = wp_get_attachment_image_src(get_post_thumbnail_id(), 'large');
		$postimage = get_post_meta($post->ID, 'post_image_value', true);
		// If the post thumbnails function exists, there is a post thumbnail assigned, and image resizing is enabled
		if ((function_exists('has_post_thumbnail')) && (has_post_thumbnail() && $mb_resize == 0)) {
			echo '<img src="'.get_bloginfo('template_url').'/thumb.php?src='.$thumbnail[0].'&amp;w=150&amp;h=110&amp;zc=1&amp;q=95" alt="'.get_the_title().'" />';
		}
		// Or if the post thumbnails function exists, there is a post thumbnail assigned, and image resizing is disabled
		else if ((function_exists('has_post_thumbnail')) && (has_post_thumbnail() && $mb_resize == 1)) {
			echo '<img src="'.$thumbnail[0].'" alt="'.get_the_title().'" />';
		}
		// Or if the post thumbnails function does not exist and there is no post thumbnail, but there is a custom field image, and image resizing is enabled
		else if (get_post_meta($post->ID, 'post_image_value', true) && $mb_resize == 0) {
			echo '<img src="'.get_bloginfo('template_url').'/thumb.php?src='.$postimage.'&amp;w=150&amp;h=110&amp;zc=1&amp;q=95" alt="'.get_the_title().'" />';
		}
		// Or if the post thumbnails function does not exist and there is no post thumbnail, but there is a custom field image, and image resizing is disabled
		else if (get_post_meta($post->ID, 'post_image_value', true) && $mb_resize == 1) {
			echo '<img src="'.$postimage.'" alt="'.get_the_title().'" />';
		}
		// Closes the surrounding link and container
		echo '</a></div>';
	}
?>

If your theme doesn’t have an option for disabling image resizing, you can use this simplified version…

<?php
	// Checks to see if there is a post thumbnail, or image specified via custom field
	if (has_post_thumbnail() || get_post_meta($post->ID, 'post_image_value', true)) {
		// Opens a container called post-tnail and accompanying link to enclose the image
		echo '<div class="post-tnail"><a href="'.get_permalink().'" title="'.get_the_title().'">';
		// Creates a function for both methods of attaching images to posts for inclusion later on
		$thumbnail = wp_get_attachment_image_src(get_post_thumbnail_id(), 'large');
		$postimage = get_post_meta($post->ID, 'post_image_value', true);
		// If the post thumbnails function exists, there is a post thumbnail assigned
		if ((function_exists('has_post_thumbnail')) && (has_post_thumbnail())) {
			echo '<img src="'.get_bloginfo('template_url').'/thumb.php?src='.$thumbnail[0].'&amp;w=150&amp;h=110&amp;zc=1&amp;q=95" alt="'.get_the_title().'" />';
		}
		// Or if the post thumbnails function does not exist and there is no post thumbnail, but there is a custom field image
		else if (get_post_meta($post->ID, 'post_image_value', true)) {
			echo '<img src="'.get_bloginfo('template_url').'/thumb.php?src='.$postimage.'&amp;w=150&amp;h=110&amp;zc=1&amp;q=95" alt="'.get_the_title().'" />';
		}
		// Closes the surrounding link and container
		echo '</a></div>';
	}
?>

For Use in Personal or Client Themes

Things get a lot easier when you don’t have to worry about potentially hundreds or thousands of people using your theme. When I’m building a theme for a client, this new implementation that relies on TimThumb for dynamic resizing is much simpler.

<?php 
	$thumbnail = wp_get_attachment_image_src(get_post_thumbnail_id(), 'large');
	if (has_post_thumbnail()) {
		echo '<div class="post-tnail"><a href="'.get_permalink().'" title="'.get_the_title().'"><img src="'.get_bloginfo('template_url').'/thumb.php?src='.$thumbnail[0].'&amp;w=150&amp;h=110&amp;zc=1&amp;q=95" alt="'.get_the_title().'" /></a></div>';
	}
?>

As you can see, there are no checks to see if image resizing is enabled, or if there are legacy images present, or if the site is even running a compatible version of WP. All of these factors are known, so there’s no need to worry about all of the fall-backs.

Make Sense?

This new implementation, while still backwards compatible, is more future proof than the previous one. But in some cases, the original implemtation is a better fit. Especially if you’re running a fairly high-traffic site. The TimThumb script can be costly as far as server resources are concernced, and you might incur extra load time.