Reputation: 5403
I have a standard single.php that will be used by most posts on this website I am working on, but for a specific category and its subcategories, I want to use a custom single.php. How do I do that? I know the logic behind what I want, I'm just not sure how to write it.
Here is the code I am using but it isn't working:
<?php
$post = $wp_query->post;
if ( in_category('2,6,7,8') ) {
include(TEMPLATEPATH . '/single-blog.php'); }
else {
include(TEMPLATEPATH . '/single-default.php');
}
?>
Cat IDs 6, 7 and 8 are subcats of Cat ID 2.
Any help would be most appreciated!
Thanks,
Cynthia
Upvotes: 0
Views: 2593
Reputation: 26319
I think you need to filter template_include
or even better single_template
. I'm leaving the has_category()
conditional as hard-coded, but you could do something to get the top-level category and always test that instead.
EDIT now using post_is_in_descendant_category()
from a codex example. Note, this isn't a built-in WordPress function so you need to include it in your plugin/theme.
EDIT #2 Use locate_template()
to ensure that the file is really there.
function get_custom_category_template($single_template) {
if ( in_category( 'blog' ) || post_is_in_descendant_category( 2 ) ) {
$new_template = locate_template( array( 'single-blog.php' ) );
if ( '' != $new_template ) {
$single_template = $new_template ;
}
}
return $single_template;
}
add_filter( 'single_template', 'get_custom_category_template' );
/* Checks if a category is a descendant of another category */
if ( ! function_exists( 'post_is_in_descendant_category' ) ) {
function post_is_in_descendant_category( $cats, $_post = null ) {
foreach ( (array) $cats as $cat ) {
// get_term_children() accepts integer ID only
$descendants = get_term_children( (int) $cat, 'category' );
if ( $descendants && in_category( $descendants, $_post ) )
return true;
}
return false;
}
}
Upvotes: 2
Reputation: 5403
I figured it out! helgatheviking's suggestion about the top-level category got me thinking about ancestor and descendant categories. From there I discovered the post_is_in_descendant_category
function.
After putting the following function in my functions.php:
/* Checks if a category is a descendant of another category */
if ( ! function_exists( 'post_is_in_descendant_category' ) ) {
function post_is_in_descendant_category( $cats, $_post = null ) {
foreach ( (array) $cats as $cat ) {
// get_term_children() accepts integer ID only
$descendants = get_term_children( (int) $cat, 'category' );
if ( $descendants && in_category( $descendants, $_post ) )
return true;
}
return false;
}
}
I figured out how to modify my original category query and template assignment like this:
<?php
$post = $wp_query->post;
if ( in_category( 'blog' ) || post_is_in_descendant_category( 2 ) ) {
include(TEMPLATEPATH . '/single-blog.php'); }
else {
include(TEMPLATEPATH . '/single-default.php');
}
?>
Thanks to everyone who tried to assist. I appreciate it a lot!
Upvotes: 1
Reputation: 3755
Updated
You can go for single-[post-type].php
.
Read more about The Template File Hierarchy
Upvotes: 1