Hierarchy for CPT templates
Closed this issue · 5 comments
I originally opened this issue at soberwp/controller#86 but it was made aware to me that the issue lies more with Brain-WP/Hierarchy (check the issue for further details).
Would it be possible to support hierarchy slugs for CPT templates? E.g. single-event
(currently supported) and single-event-template-<template name>
or event-template-single-event-featured
(neither supported).
This would provide much more control over what CPT templates can share certain data or code.
By default this package acts just like WordPress core template hierarchy and there there's no support for what you are looking for.
I don't want to have differences between the templates recognized by this package and the those recognized by core.
However, WordPress (since 4.7) supports the filter "{$type}_template_hierarchy"
where $type
is the hierarchy leaf, in your case "single".
The support for that filter is added to this package as well (since version 2.3.0), so you can use that filter to change the hierarchy as you prefer.
Which means you could do something like this:
add_filter(
'single_template_hierarchy',
function(array $templates) {
$post = get_queried_object();
if ( !empty($post->post_type)) {
$templateFile = get_page_template_slug($post);
if ($templateFile && validate_file($templateFile) === 0) {
$template = "single-{$post->post_type}-template-" . basename($templateFile, '.php);
array_unshift($templates, $template);
}
}
return $templates;
}
);
Doing so, if you add in a file named featured.php
a template header like:
/*
* Template Name: Featured
* Template Post Type: post, event
*/
and the post being queried has "event" post type and "example" post slug, then Hierarchy package (currently) will output an array of templates that looks like:
[
'single-event-template-featured',
'single-event-example',
'single-event',
'single',
];
This is slightly different from WordPress that would also look for featured.php
(the file where the template header is set), but Hierarchy at the moment of writing has no support for page templates in CPT (will be added in version 2.4).
If you want, you could set the template name not only by setting the template header, but also via "theme_{$post_type}_templates"
filter.
Thanks for such a quick response! Looks like exactly what I'll need. Will be trying this out in the week.
@gmazzap This worked great, thanks for the solution.
One issue I see, though, is to do with naming conventions (If I'm looking at this wrong, apologies!).
E.g. I have my template single-event-featured-bh.blade.php
which you can see has a sensible prefix of single-event-
before the template name. Doing so means I can have various -featured
templates for different Post Types (rather than them all sharing featured.php
as per your example. The result of having these prefixes or naming conventions means I end up with a result of single-event-template-single-event-featured-bh
.
What can be done for developers that follow naming conventions like this? I think it's a very common approach to consider.
To make it fit with my setup (using theme Sage 9), I have modified to this:
/**
* Add support to \Sober\Controller for CPT Templates
*/
add_filter('single_template_hierarchy', function (array $templates) {
$post = get_queried_object();
if (! empty($post->post_type)) {
$templateFile = get_page_template_slug($post);
if ($templateFile && validate_file($templateFile) === 0) {
if (strpos($templateFile, "single-{$post->post_type}-") !== false) {
/** Remove .blade.php/.blade/.php from template names */
$template = preg_replace('#\.(blade\.?)?(php)?$#', '', ltrim($templateFile));
/** Remove partial $paths from the beginning of template names */
if (strpos($template, '/')) {
$template = preg_replace("#^(" . implode('|', ['views']) . ")/#", '', $template);
}
array_unshift($templates, $template);
}
}
}
return $templates;
});
The thing is that Hierarchy aims to have 1:1 match with WordPress hierarchy. Anything "custom" has to be done externally via hooks.
If code you posted works for you, good! My snippet was just a quick example with no claim to be perfect ...or even working :)
If you miss some hooks that would allow for easier customization, open an issue and I see if I can add them... otherwise feel free to use current hooks and customize the behavior of Hierarchy as much as you prefer.
Hierarchy has now support for CPT post templates (v2.4.0), and documentation about hierarchy filtering has been added. I guess I can close this.