最新消息:Welcome to the puzzle paradise for programmers! Here, a well-designed puzzle awaits you. From code logic puzzles to algorithmic challenges, each level is closely centered on the programmer's expertise and skills. Whether you're a novice programmer or an experienced tech guru, you'll find your own challenges on this site. In the process of solving puzzles, you can not only exercise your thinking skills, but also deepen your understanding and application of programming knowledge. Come to start this puzzle journey full of wisdom and challenges, with many programmers to compete with each other and show your programming wisdom! Translated with DeepL.com (free version)

Taxonomy Templates... by hierarchical level?

matteradmin10PV0评论

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' );

Articles related to this article

Post a comment

comment list (0)

  1. No comments so far