admin管理员组

文章数量:1305361

I'm building a product catalog site and I created a product custom post type and a related product_type taxonomy. I added some products and created the following product_type terms:

  • Books
    • Classics
    • Fantasy
    • Mystery
  • Toys
    • Puzzles
    • Dolls
    • Cars

When a user visits the catalog I want to show him a product_type terms navigation by level. That is, when he enters the main catalog page I only want him to see the first level of terms: Books, Toys and a special link named All that when clicked shows all products.

When the user clicks one of the root terms, for example, Books, I want to show its child terms in addition to the root terms, that is: Classics, Fantasy, Mystery and a special link named All that when clicked shows all products under the Books term.

Likewise, when the user clicks the Toys root term, I want to show the its child terms in addition to the root terms, that is: Puzzles, Dolls, Cars and a special link named All that when clicked shows all products under the Toys term.

I'm using the following recursive function to get all the terms hierarchically:

function get_taxonomy_hierarchy( $taxonomy, $parent = 0 ) {
    $taxonomy = is_array( $taxonomy ) ? array_shift( $taxonomy ) : $taxonomy;
    $terms = get_terms( $taxonomy, array( 'parent' => $parent ) );
    $children = array();
    foreach ( $terms as $term ){
        $term->children = get_taxonomy_hierarchy( $taxonomy, $term->term_id );
        $children[ $term->term_id ] = $term;
    }
    return $children;
}

But I'm hitting a wall trying to handle the All links in all of this structure because they are not actual terms per se. Any ideas would be appreciated.

I'm building a product catalog site and I created a product custom post type and a related product_type taxonomy. I added some products and created the following product_type terms:

  • Books
    • Classics
    • Fantasy
    • Mystery
  • Toys
    • Puzzles
    • Dolls
    • Cars

When a user visits the catalog I want to show him a product_type terms navigation by level. That is, when he enters the main catalog page I only want him to see the first level of terms: Books, Toys and a special link named All that when clicked shows all products.

When the user clicks one of the root terms, for example, Books, I want to show its child terms in addition to the root terms, that is: Classics, Fantasy, Mystery and a special link named All that when clicked shows all products under the Books term.

Likewise, when the user clicks the Toys root term, I want to show the its child terms in addition to the root terms, that is: Puzzles, Dolls, Cars and a special link named All that when clicked shows all products under the Toys term.

I'm using the following recursive function to get all the terms hierarchically:

function get_taxonomy_hierarchy( $taxonomy, $parent = 0 ) {
    $taxonomy = is_array( $taxonomy ) ? array_shift( $taxonomy ) : $taxonomy;
    $terms = get_terms( $taxonomy, array( 'parent' => $parent ) );
    $children = array();
    foreach ( $terms as $term ){
        $term->children = get_taxonomy_hierarchy( $taxonomy, $term->term_id );
        $children[ $term->term_id ] = $term;
    }
    return $children;
}

But I'm hitting a wall trying to handle the All links in all of this structure because they are not actual terms per se. Any ideas would be appreciated.

Share Improve this question asked Jan 26, 2021 at 20:43 leemonleemon 2,0324 gold badges23 silver badges51 bronze badges 0
Add a comment  | 

1 Answer 1

Reset to default 0

I managed to find a solution myself. This code is to be used in taxonomy templates.

PHP:

function show_taxonomy_navigation( $post_type = 'post', $taxonomy = 'category', $parent = 0 ) {
    $html = get_taxonomy_hierarchy( $post_type, $taxonomy, $parent );
    echo $html;
}

function get_taxonomy_hierarchy( $post_type, $taxonomy, $parent = 0, $depth = 0 ) {
    $taxonomy = is_array( $taxonomy ) ? array_shift( $taxonomy ) : $taxonomy;
    $html = '';
    // get the id of the currently queried term
    $current_term_id = get_queried_object_id();
    $args = array(
        'taxonomy' => $taxonomy,
        'parent'   => $parent,
        'order_by' => 'name',
    );
    // Get the child terms of $parent
    $terms = get_terms( $args );
    if ( $terms ) {
        if ( $depth == 0 ) {
            $html .= '<nav class="taxonomy-navigation">';
        }
        $ul_classes = [];
        $ul_classes[] = 'terms';
        $html .= '<ul class="' . esc_attr( implode( ' ', array_filter( $ul_classes ) ) ) . '">';
        // Add 'All' link
        $all_link = ( $parent > 0 ) ? get_term_link( $parent ) : get_post_type_archive_link( $post_type );
        $html .= '<li><a href="' . $all_link . '">' . esc_html__( 'All', 'my-taxonomy-navigation' ) . '</a></li>';
        foreach ( $terms as $term ) {
            $li_classes = [];
            $li_classes[] = 'term-item';
            // Add class if term corresponds to the currently queried term
            $li_classes[] = ( $term->term_id == $current_term_id ) ? 'current-term' : null;
            // Add class if term is a parent of the currently queried term
            $li_classes[] = ( term_is_ancestor_of( $term->term_id, $current_term_id, $taxonomy ) ) ? 'current-term-parent' : '';
            $html .= '<li class="' . esc_attr( implode( ' ', array_filter( $li_classes ) ) ) . '">';
            $html .= '<a href="' . get_term_link( $term->term_id ) . '">' . $term->name . '</a>';
            // Recursively go deeper in the hierarchy
            $html .= get_taxonomy_hierarchy( $post_type, $taxonomy, $term->term_id, $depth + 1 );
            $html .= '</a>';
            $html .= '</li>';
        }
        $html .= '</ul>';
        if ( $depth == 0 ) {
            $html .= '</nav>';
        }
    }
    return $html;
}

CSS:

.taxonomy-navigation ul.terms {
    position: relative;
    list-style: none;
    text-align: center;
}

.taxonomy-navigation ul.terms li {
    display: inline-block;
    margin: 0;
    padding: 0 15px;
}

.taxonomy-navigation ul.terms li.current-term > a,
.taxonomy-navigation ul.terms li.current-term-parent > a {
    font-weight: 700;
}

.taxonomy-navigation ul.terms li ul.terms {
    display: none;
    position: absolute;
    top: auto;
    left: 0;
    right: 0;
    margin: 0 auto;
}

.taxonomy-navigation ul.terms li.current-term > ul.terms,
.taxonomy-navigation ul.terms li.current-term-parent > ul.terms {
    display: block;
}

本文标签: Custom taxonomy terms hierarchical navigation