single-{$post_type}-{slug}.php for custom post types

A) The Base in Core

As you can see in the Codex Template Hierarchy explanation, single-{$post_type}.php is already supported.


B) Extending the core Hierarchy

Now there’re gladly some filters and hooks inside /wp-includes/template-loader.php.

  • do_action('template_redirect');
  • apply_filters( 'template_include', $template )
  • AND: a specific filter inside get_query_template( $type, ... ) named: "$type}_template"

B.1) How it works

  1. Inside the template loader file, the template gets loaded by a query var/wp_query conditional: is_*().
  2. The conditional then triggers (in case of a “single” template): is_single() && $template = get_single_template()
  3. This triggers then get_query_template( $type, $templates ), where $type is single
  4. Then we have the "{$type}_template" filter

C) The solution

As we only want to extend the hierarchy with one template that gets loaded before the actual "single-{$object->post_type}.php" template, we’ll intercept the hierarchy and add a new template to the beginning of the templates array.

// Extend the hierarchy
function add_posttype_slug_template( $templates )
{

    $object = get_queried_object();

    // New 
    $templates[] = "single-{$object->post_type}-{$object->post_name}.php";
    // Like in core
    $templates[] = "single-{$object->post_type}.php";
    $templates[] = "single.php";

    return locate_template( $templates );    
}
// Now we add the filter to the appropriate hook
function intercept_template_hierarchy()
{
    add_filter( 'single_template', 'add_posttype_slug_template', 10, 1 );
}
add_action( 'template_redirect', 'intercept_template_hierarchy', 20 );

NOTE: (If you want to use something other than the default objects slug) You’ll have to adjust $slug according to your permalink-structure. Just use whatever you need from the global (object) $post.

Trac Tickets

As the above approach is currently not supported (you can only filter the absolute located path this way), here’s a list of trac tickets:

Leave a Comment