[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