I’ve seen a few tutorials floating around the WordPress-o-Sphere about setting a default post thumbnail for WordPress’ featured image functionality. Some involve tactics like saving a permanent default image (theme authors, please don’t do that).
A default thumbnail is generally not something that’s permanent, so you wouldn’t want to save it, leaving yourself a world of pain if you ever wanted to change it in the future. I’ll keep this simple and afford you that future flexibility. I’ll even show you two ways to do it.
Option #1: Using a hook
WordPress has an awesome filter hook called post_thumbnail_html that works great for this. If you’re using a child theme, this is a pretty good option. Just drop the following code into your theme’s functions.php. It will load an image called default-thumbnail.png from your theme’s /images folder.
add_filter( 'post_thumbnail_html', 'my_post_thumbnail_html' );
function my_post_thumbnail_html( $html ) {
if ( empty( $html ) )
$html = '<img src="' . trailingslashit( get_stylesheet_directory_uri() ) . 'images/default-thumbnail.png' . '" alt="" />';
return $html;
}
Notes about this method:
- This won’t work if your theme does a conditional check for the thumbnail such as with the
has_post_thumbnail()function. Check with your theme author though; there might be alternate methods. - Use
get_template_directory_uri()in the above code instead ofget_stylesheet_directory_uri()if you’re working with a regular/parent theme.
Option #2: The tried and true method
There’s really no need to get fancy with hooks and such unless you’re trying to keep your theme’s templates clean (like when using a child theme). You can drop the following code right into your theme’s template.
<?php
if ( has_post_thumbnail() )
the_post_thumbnail();
else
echo '<img src="' . trailingslashit( get_stylesheet_directory_uri() ) . 'images/default-thumbnail.png' . '" alt="" />';
?>
There you have it: two simple ways to set default post thumbnails.
Hey Justin,
Good to see a new WordPress tutorial! It’s been awhile. I’ve also been enjoying the posts about country living. I myself have also been so fortunate as to find myself designing websites rurally by the ocean in Nova Scotia, so I can relate.
Anyhow, out of curiosity, in Option 2 I was wondering if there was any particular reason you used
get_stylesheet_directory_uri()as opposed toget_bloginfo('template_url')orget_template_directory_uri()? Also was wondering if there was any reason you choose to usetrailingslashit()as opposed to putting the slash in yourself?These probably seem like pretty meaningless questions but I am always interested in the “right” way to do things in WordPress and I certainly trust you as a source for that.
Thanks and take care!
I’ve just recently gotten through unpacking, so I have a little extra time now.
Basically for the same reason as noted in the first example. Just substitute
templateforstylesheetif you’re building a parent theme.As far as
get_bloginfo( 'template_url' )goes, I wouldn’t use it when there’s a function that already handles this. Plus, I don’t think its use is allowed in the WordPress theme repository.You should always use
trailingslashit()when adding a trailing slash to an unknown variable. You don’t know 100% for certain whether there’s a slash when you’re not hardcoding something.trailingslashit()adds a trailing slash only if there’s not already one.Thanks for your reply Justin. I feel a bit silly for not reading the notes under option 1 now. hah. Interesting to know that
get_bloginfo()is one to avoid. Does that apply as well tobloginfo()?As always, it’s the little things that count and these little tips you’ve provided have always helped me become a better coder. Your book is the only tech book I ever open anymore!
bloginfo()is just a wrapper forget_bloginfo()that prints out the return value. They’re basically the same thing. So, the same things apply to it.Also, just in case I wasn’t clear: Only avoid these functions when there’s a function that makes more sense to use. There are legitimate uses of them, such as
get_bloginfo( 'name' ).I use my own function for getting a post thumbnail which :
1. Looks for an assigned featured thumbnail,
2. if nothing found, (optionally) grabs the first attached image to the post,
3. or (optionally) inserts a default image.
Of course, there are parameters depending on where I use it within my custom themes.
On a (somewhat) related note…
new clients often forget to click “use as featured image” once an image is uploaded. On the client’s defense, I find it misleading that when you use “Set Featured Image” as opposed to using the media uploader that the new image is not automatically assigned as the featured image upon uploading (or saving the post, or closing the popup, etc.).
Thanks for the post_thumbnail_html tip. Now that I am far more into using hooks and filters I find it very hard to locate the one you need.
Option #2 (changing the theme) is not necessary.
Just hook into
'get_post_metadata'. If the third argument is'_thumbnail_id'returnTRUE.Thomas, you can’t just return true when get_post_thumbnail_id is expecting an integer for an attachment id. If you’re hooking into the get metadata functions, you’re expected to return valid results. In your case you can create an attachment post for default thumbnail and always return its id, if _thumbnail_id doesn’t exist in post meta.
However Justin’s (second) method is much cleaner, easier to understand, and more future proof. Yours is quite dangerous. Cheers!
Finally a honest and accurate article about default thumbnails. It really can’t get any simpler than that. Thanks Justin!
Hi Justin, great stuff, as always! I don’t really see a good reason to use the first option you mentioned, other than for changing the markup for post thumbnails, for example a div with a background-image, instead of an img element. Second option is very straight to the point.
Thanks!
I’ve been using the second method for ages. Looks like I’m good at WP sometimes
Now you prove me right
Thanks, going to be using the second method on some new project.
Hi Justin
Can I just use
the_post_thumbnail()in the theme withouthas_post_thumbnail()check ? This way it allows the first method to be able to work, is this okay ?Thanks
Thanks for this Justin, I’ve been trying to get my head around advancing my theme development and posts like this really help. Great blog by the way – bookmarked.
Great tutorial!
Is there a way to have two default Thumbnails? For example if a user is male or female the thumbnail will reflect that? It might be more trouble than it’s worth, but thought I would ask.
One other non related question. Do you or anyone else know anything about this site, discountwpthemes.com? It seem legit, I’ve just never used them before.
Any information would be awesome. Thanks.
Drew
How do you put a style class in the first example? I want to put a thumbnail in the page so I can have the image available when I post the article to facebook fan page. I want the class so I can move the thumb off the page with img.class{left:-999px}
Thanks
Here a modified version using a placehold.it
function default_thumbnail($html) {
global $_wp_additional_image_sizes;
$isize = $_wp_additional_image_sizes;
$w = $isize['post-thumbnail']['width'];
$h = $isize['post-thumbnail']['height'];
if (empty($html)) {
$html = '';
$html .= '';
$html .='';
}
return $html;
}
Was wondering if there was a better way to do this??
-shawn
**sorry some of the above code got chopped here is a link to the gist
https://gist.github.com/4102907
All these methods are very deficient. The signature of the_post_thumbnail() is:
None of the solutions given above handle the $size and $attr parameters. For example, if the theme wants to display 320×200 thumbnails in one context, and 150×150 thumbnails in another context, then none of the methods given make it possible to automatically display the correctly cropped versions of the default thumbnail in both contexts.
The solutions given in the tutorial are just a base to build from. You can most certainly do the things you want with the functionality I provided. Just think about it for a little bit. Or, I’m available for hire if you need me to do it for you.
I tested these code snippets and they work however is this really a big problem:
“saving a permanent default image (theme authors, please don’t do that).”
Couldn’t you simply replace the image?
Yes, a user can simply replace it. However, we shouldn’t force users to replace an image that they didn’t ask to be saved in their database in the first place. Imagine that your theme saves a default image that looks good with the theme. Then, the user changes to another theme. Now, the user has these thumbnails that they must manually replace if they want something different.
If you’re talking about replacing it via code, that’s a bit harder to do. It’s not impossible, but it’s not something I’d want to try. Plus, you’d just be giving yourself more and harder work to do.