I am trying to customize the behavior of my blog to serve a specific single post template based on the category the post is assigned to.
I came across this filter in my parent theme which is what gave me the idea. The theme is Photo Workshop by Graph Paper Press.
//add single post template depending on category slug
add_filter('single_template', 'gpp_single_template');
function gpp_single_template($single) {
global $wp_query, $post;
foreach((array)get_the_category() as $cat) :
// single posts template based on category slug
if(file_exists(TEMPLATEPATH . '/single-' . $cat->slug . '.php'))
return TEMPLATEPATH . '/single-' . $cat->slug . '.php';
//else load single.php
elseif(file_exists(TEMPLATEPATH . '/single.php'))
return TEMPLATEPATH . '/single.php';
endforeach;
return $single;
}
Instead of overriding the file it uses (which may not be possible because it's included using TEMPLATEPATH), I thought it would be a better idea to just remove their filter & then add my own. Essentially, I'm not really trying to do something different than their code, but I want it to look in the child theme directory first which is why I am using the locate_template()
function. In addition to that, I wanted to hard-code the highest priority template.
My version of the filter from my child theme's functions.php
:
// remove the stock filter
remove_filter('single_template','gpp_single_template');
// add the new one
add_filter('single_template', 'single_template_override');
//add single post template depending on category slug
function single_template_override($path) {
global $wp_query, $post;
$categories = get_the_category();
$cat_slugs = array();
foreach ($categories as $cat) {
$cat_slugs[] = $cat->slug;
}
$templates = array();
// add in the top priorities if present
if (in_array('fine-art', $cat_slugs)) {
// add to the beginning
$templates[] = 'single-fine-art.php';
}
foreach($cat_slugs as $cat_slug) :
// single posts template based on category slug
$filename = 'single-' . $cat_slug . '.php';
// if not already in the array, add it
if (!in_array($filename, $templates)) {
$templates[] = $filename;
}
endforeach;
$found = locate_template($templates, false);
if ($found) {
return $found;
} else {
return $path;
}
}
For some reason posts with the Fine Art category are not pulling the single-fine-art.php
template.
I have dug into the depths of the wordpress core to see where this filter is applied and everything seems like it should work to me. The filter can be found in get_single_template()
which passes it's parameters to get_query_template()
.
Any help would be much appreciated!
var_dump
andwp_die
after$found = locate_template($templates, false);
?/***/***/***/***/fineart/wp-content/themes/fpp-custom/single-fine-art.php
.add_filter
to 11, it worked. The original filter I was removing had the default priority and so did my remove function, so why would changing my filter's priority matter?