Taxonomy Templates... by hierarchical level?

admin2025-06-05  4

Is there a way to use different templates for different levels within a hierarchical taxonomy, specified by filename. I know about taxonomy-taxonomyname.php and taxonomy-taxonomyname-term.php templates. Looking for a more generic "per taxonomy level" based method.

So, a taxonomy named Earth might contain:

  1. Africa
    • Cameroon
    • Congo
    • Senegal
  2. Asia
    • Japan
    • Korea
  3. Europe
    • Greece
    • ...
  4. South America
  5. ...

Is there a way to have one template for Africa, Asia, Europe and South America (earth-numbers-level.php)... and another template for Cameroon, Congo, Japan, Greece... (earth-bullets-level.php)?

Looking over a few different template hierarchy docs, I'm guessing not. If that's true, what's the best/most efficient way to differentiate taxonomy levels within taxonomy-earth.php so that I might use different template parts for each?

Is there a way to use different templates for different levels within a hierarchical taxonomy, specified by filename. I know about taxonomy-taxonomyname.php and taxonomy-taxonomyname-term.php templates. Looking for a more generic "per taxonomy level" based method.

So, a taxonomy named Earth might contain:

  1. Africa
    • Cameroon
    • Congo
    • Senegal
  2. Asia
    • Japan
    • Korea
  3. Europe
    • Greece
    • ...
  4. South America
  5. ...

Is there a way to have one template for Africa, Asia, Europe and South America (earth-numbers-level.php)... and another template for Cameroon, Congo, Japan, Greece... (earth-bullets-level.php)?

Looking over a few different template hierarchy docs, I'm guessing not. If that's true, what's the best/most efficient way to differentiate taxonomy levels within taxonomy-earth.php so that I might use different template parts for each?

Share Improve this question edited Dec 23, 2018 at 5:45 Will asked Nov 23, 2015 at 4:06 WillWill 1,35512 silver badges15 bronze badges 0
Add a comment  | 

2 Answers 2

Reset to default 6

+1ed Pieter Goosen's answer, but this time I want to be the one who advocate the "make it simple" way.

In your taxonomy-earth.php template, you can check if the queried term as a parent, and require another template if so.

If you ask this question, I guess you already have (or wish to create) 2 templates, let's call them:

  • taxonomy-earth-continent.php
  • taxonomy-earth-country.php

In your taxonomy-earth.php file you can:

<?php
$slug = 'taxonomy-earth';
// default to continent
$name = 'continent';

// maybe set specific template to "country" if queried term has a parent
$term = get_queried_object();
if ( is_object( $term ) && ! empty( $term->parent ) )
    $name = 'country';

get_template_part( $slug, $name );

These 6 lines of template code, will be enough to require a different template for "child" terms.

Thanks to the use of get_template_part the template code is also child-theme friendly and triggers an hook: get_template_part_taxonomy-earth that can be used to do things when the template is required.

You have a couple of options here:

taxonomy-{$taxonomy}-{$term->parent}-{$term}.php

We can create our own hierarchy (or actually extends the existing hierarchy) by creating our own taxonomy-{$taxonomy}-{$term->parent}-{$term}.php template for use when a child term is being viewed. We will also make use of the taxonomy_template filter to add our new taxonomy templates to the hierarchy so that they will be used.

You can try something like the following: (NOTE: All code is untested and all code is commented for easy following and understanding. The code also assumes that top level terms already have a taxonomy-{$taxonomy}-{$term}.php template.)

add_filter( 'taxonomy_template', function ( $template )
{
    // Get the current term object being viewed
    $current_term = get_queried_object();

    // We can restrict this to a single taxonomy, for example
    // if ( $current_term->taxonomy !== 'my_taxonomy' )
        // return $template;

    /**
     * Check if current term is top level, if so, return the default $template which
     * should be template taxonomy-{$taxonomy}-{$term}.php if found
     */
    if ( $current_term->parent == 0 ) // Top level terms have parent of 0
        return $template;

    // We made it to here, so the term is not top level

    // We need to get the top level term of the current term
    $hierarchy = get_ancestors( $current_term->term_id, $current_term->taxonomy );
    // The parent ID will always be the last ID in the array returned by get_ancestors
    $parent_ID = end( $hierarchy );
    // Now we can get the top level term object
    $top_level_term = get_term_by( 'id', $parent_ID, $current_term->taxonomy );

    /** 
     * Lets build our custom template name, add subfolder name if template
     * is in a subfolder, for example /subfolder/name-of-template.php
     */
    $custom_template = 'taxonomy-{$current_term->taxonomy}-{$top_level_term->slug}-{$current_term->slug}.php';
    // Check if our custom template exist, if not, return default $template
    $locate_template = locate_template( $custom_template );
    if ( !$locate_template )
        return $template;

    // Finally, everything checked out, return our custom template
    return $template = $locate_template;
}); 

You can adjust the code as needed

Custom template parts

You can create your taxonomy-{$taxonomy}-{$term}.php template and the make use of template parts inside your loop to include template parts according to child term. The best here will be to write a custom function and then calling that function inside the loop (or wherever you need it) instead of get_template_part()

For this to work, we need to call our template part as follow:

  • top level terms will be {$term}.php, like africa.php

  • child terms will be {$term->parent}-{$term}.php like africa-cameroon.php

  • default/fallback template like content.php. Just remember not to pass the .php part of the template name to the function

Here is the code

/** 
 * Function to set template parts according to child term
 *
 * @param (string) $default Default template part to use like content.php
 * @return $template
 */
function get_custom_template_part( $default = '' )
{
    // Check if we have a value for $default, if not, return false
    if ( !$default )
        return false;

    // Sanitize the $default value
    $default = filter_var( $default, FILTER_SANITIZE_STRING );

    // Check if we are on a taxonomy page, if not, return the $default template
    if ( !is_tax() )
        return get_template_part( $default );

    // Get the current term being viewed
    $current_term = get_queried_object();

    /**
     * Set our custom variables
     * $top_level_term will hold the top level term object
     * $part will hold the current term slug if the current term is not top level
     */
    $top_level_term = '';
    $part = '';

    // Check if current term is top level, if not, get the top level parent
    if ( $current_term->parent != 0 ) {
        // We need to get the top level term of the current term
        $hierarchy = get_ancestors( $current_term->term_id, $current_term->taxonomy );
        // The parent ID will always be the last ID in the array returned by get_ancestors
        $parent_ID = end( $hierarchy );
        // Now we can get the top level term object
        $top_level_term = get_term_by( 'id', $parent_ID, $current_term->taxonomy );
        $part = $current_term->slug;
    }

    // We now will set our template's name accordingly
    if ( $top_level_term ) {
        $name = $top_level_term->slug;
    } else {
        $name = $current_term->slug;
    }

    // We will now check if our template parts exist, if not, return our default
    if ( $part ) { // This means we have a child term
        $template = get_template_part( $name, $part );
    } else { // This means top level term
        $template = get_template_part( $name );
    }

    if ( $template )
        return $template;

    return get_template_part( $default );
}

You can extend this as needed, and you can also add your template parts in a subfolder, and then just append the subfolder name to the value of $name inside the function

You can now use the function in the following way in your taxonomy-{$taxonomy}-{$term}.php or taxonomy-{$taxonomy}.php template

Default template: content.php

get_custom_template_part( 'content' );
转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1749074393a316133.html

最新回复(0)