So far in this series we’ve looked at how to creating and use Custom Page Templates and Custom Category Templates, but what about custom single post templates? As of right now, there is no built in function for creating custom single post templates in WordPress (though I believe it’s coming – at least partially – in version 3.1. In the meantime we can still create custom single post templates based on the categories a post belongs to, we just have to write the actual function for it as well. On this 18th Day of WordPress I’ll show you how to do just that.
Creating a Custom Single Post Template function
There are just two steps to this process: Create a function to activate custom single post templates and creating the actual template itself. Let’s tackle the first one first. What you need to do is wirte a function – to be placed in functions.php of your theme or child-theme – that grabs the category info for the post in question and checks if there is a custom single post template that matches that particular category. That function looks something like this:
add_filter('single_post_template', create_function(
'$the_template',
'foreach( (array) get_the_category() as $cat ) {
if ( file_exists(TEMPLATEPATH . "/single-{$cat->slug}.php") )
return TEMPLATEPATH . "/single-{$cat->slug}.php"; }
return $the_template;' )
);
This function, actually a filter, finds the category slug(s) for the post and checks if there is a template file called single-[slug].php in the theme. If there is, that tempalte is used in place of single.php. So for example if you have a category called Portfolio with the slug “portfolio” you can create a new file called single-portfolio.php that will then become the custom single post template for posts assigned to this category.
But… Isn’t there a plugin for that?
The question you are probably asking yourself right now is “Isn’t there a plugin for that?” And the answer is yes, there is. It’s called Single Post Template. So why am I making things difficult by serving up a function that needs to be added to the theme files? Two reasons: First off I don’t particularly like plugins because they tend to bog down sites and often create a big mess in the code. But more importantly, if you are creating a custom theme for distribution you can’t rely on people always installing a specific plugin. The method described here is much better because you can serve up custom single post templates for selected categories and then all the user has to do is create those categories and the template will kick in automatically. It’s clean, it’s simple and it’s foolproof.
This tutorial is part of the 24 Days of WordPress series. If you want to learn more about WordPress and Expression Web check out the Sams Teach Yourself Microsoft Expression Web in 24 Hours series (version 2, 3 and 4), Lynda.com’s WordPress 3.0 Essential Training course and Microsoft Expression Web 4 LiveLessons.
15 replies on “Day 18: Creating Custom Single Post Templates”
Actually, there is no (or no more) ‘single_post_template’ filter. This function would never get executed. (WordPress 3.2.1)
The real name of the filter is ‘single_template’, once changed it works.
Thanks Darko and Morten,
Saved my bacon.
ACtually – I ended up using the following in my functions file
function get_category_post_template($single_template) {
global $post;
$categories = get_the_category($post->ID) ;
foreach ( $categories as $cat) {
if (file_exists( dirname( __FILE__ ) . "/single-{$cat->cat_ID}.php" ) )
$single_template = dirname( __FILE__ ) . "/single-{$cat->cat_ID}.php" ;
}
return $single_template;
}
add_filter( "single_template", "get_category_post_template" ) ;
Referenced from http://codex.wordpress.org/Plugin_API/Filter_Reference/_single_template
Wow this is some sweet code! Thank you Morten and Darko!
Sometime we needed to show our details page (that means single.php) in different styles. For this sense, I write a post on http://www.webinbangla.com/2012/05/different-style-of-single-php/
Thanks for this it’s exactly what I was looking for! However as I am using a child theme I had to modify it slightly to use STYLESHEETPATH instead of TEMPLATEPATH (see below):
add_filter(‘single_template’, create_function (
‘$the_template’,
‘foreach( (array) get_the_category() as $cat ) {
if ( file_exists(STYLESHEETPATH . “/single-{$cat->slug}.php”) )
return STYLESHEETPATH . “/single-{$cat->slug}.php”; }
return $the_template;’ )
);
Exactly what I was looking for. 2 plugins broke my websites previously, while this was so easy to do with above code. And ability to related to slug is much better than having to manually chose template for each post. Thanks a lot!
Nice code
Yeah this works really well, thanks very much guys. And nice work DARKO for the edit.
Thank You, I have been looking for hours on how to do this.
Works Great.
Great …Its working
HI
Is there a conditional tag to check if a singl-[slug].php page is being used?
something like:
if (is_single_template(single-slug.php)){
the condition
}
Thanks
Dan
The tag for this filter has changed. “single_post_template” doesn’t exist anymore, if you exchange it for “single_template” the filter works again. Thanks for this!
YOU SAVED MY LIFE. THANK YOU MATE
function theme_custom_single($template)
{
if (in_category(array(451,452,453,454,455,40))) {
$template = dirname(__FILE__) . ‘/single-webinar.php’;
} else if (in_category(array(449))) {
$template = dirname(__FILE__) . ‘/single-store.php’;
}
return $template;
}
add_filter(‘single_template’, ‘putduchi_custom_single’);