[wp-trac] [WordPress Trac] #14310: Make template hierarchy filterable
WordPress Trac
noreply at wordpress.org
Thu Aug 20 21:46:28 UTC 2015
#14310: Make template hierarchy filterable
------------------------------------+-----------------------------
Reporter: scribu | Owner:
Type: enhancement | Status: reopened
Priority: normal | Milestone: Future Release
Component: Themes | Version:
Severity: normal | Resolution:
Keywords: has-patch dev-feedback | Focuses: template
------------------------------------+-----------------------------
Changes (by stevegrunwell):
* focuses: => template
Comment:
Well shoot, I was just starting on a patch for this concept and found the
ticket. Instead, I'll just have to contribute another use-case: a theme
wanting to cascade a custom category design through its child sub-
categories.
Assume a site has the given category hierarchy:
* Art
* Paintings
* Sculptures
* Music
* Blues
* Jazz
* Rock
* Recipes
* Sweet
* Savory
Art, Music, and Recipes may be three distinct categories of the same blog
and the site owner wants a distinct template for each section, so he/she
creates category-art.php in the theme, and the Art category looks great,
until the user clicks into Art > Painting and the theme has fallen back to
category.php as a template.
Using the this new filter, the site owner could implement something like
the following to permit "Paintings" and "Sculptures" to use category-
art.php without limiting the ability to use category-paintings.php down
the road.
{{{
/**
* Cascade category-specific templates to child categories.
*
* @param array $templates A list of template candidates, in ascending
order of priority.
* @return The filtered list of template candidates.
*/
function mytheme_cascade_category_templates( $templates ) {
$term_id = false;
$templates_before = array();
// Determine the category ID.
foreach ( $templates as $template ) {
$templates_before[] = $template;
if ( preg_match( '/^category-(\d+)\.php$/i', $template,
$matches ) ) {
$term_id = absint( $matches['1'] );
break;
}
}
// Proceed normally if we can't find a term ID
if ( false === $term_id ) {
return $templates;
}
// Get the category ancestors
$parent_terms = get_terms( 'category', array(
'orderby' => 'none',
'include' => get_ancestors( $term_id, 'category' ),
'hide_empty' => false,
'fields' => 'id=>slug',
) );
// Inject the ancestors into the template candidate array
$templates_after = array_diff( $templates, $templates_before );
$ancestor_templates = array();
foreach ( $parent_terms as $parent_term_id => $parent_term_slug )
{
$ancestor_templates[] = sprintf( 'category-%s.php',
$parent_term_slug );
$ancestor_templates[] = sprintf( 'category-%d.php',
$parent_term_id );
}
return array_merge( $templates_before, $ancestor_templates,
$templates_after );
}
add_filter( 'category_template_hierarchy',
'mytheme_cascade_category_templates' );
}}}
This (example) code effectively leverages this new filter to change the
list of template candidates from:
1. category-sculptures.php
2. category-2.php
3. category.php
To:
1. category-sculptures.php
2. category-2.php
3. category-art.php
4. category-1.php
5. category.php
I don't think it would make sense from a backwards compatibility
perspective to ever enforce this sort of cascade as default behavior, but
this filter lets site owners who *do* wish to introduce this functionality
to do so without affecting those who prefer the default functionality.
--
Ticket URL: <https://core.trac.wordpress.org/ticket/14310#comment:51>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list