Search code examples
phpwordpresswoocommercetaxonomy

Wordpress WooCommerce display nested product category for individual product


I have a Wordpress WooCommerce site that sells car parts. For each part (product) I have created unique Product Categories that I can assign to the part. So e.g. a headlight (part) can be from a 3-Door 1999 Blue Alfa Romeo 156 1.1 Petrol Manual.

On the individual product page I want to display a nested list of only the Product Categories associated with THIS part. So when I tag a part I will have a nested view like the image below. enter image description here

However, my current code below the second image displays all Product Categories that has a part associated with it including THIS part. As can be seen in the second image below I have many other parts assigned to other car Makes and they are all displayed for THIS part. I only want THIS part to display Product Categories associated with THIS part. So under Make it should only display Alfa Romeo - not all the other Product Categories that has parts in them regardless if they are tagged in THIS part. enter image description here

Can anyone please help?

Current code

<?php 
    $woocCategoryTerms = get_terms('product_cat', array(
        'order'        => 'ASC',
        'hide_empty'   => true,  // (boolean) 
        'parent'       => 0,     // (integer) Get direct children of this term (only terms whose explicit parent is this value). If 0 is passed, only top-level terms are returned. Default is an empty string.
        'hierarchical' => true,  // (boolean) Whether to include terms that have non-empty descendants (even if 'hide_empty' is set to true).
        ));    

    foreach($woocCategoryTerms as $wooCategoryTerm) : 
?>
        <ul>
            <li>
                <a href="<?php echo get_term_link( $wooCategoryTerm -> slug, $wooCategoryTerm -> taxonomy ); ?>">
                    <?php 
                        echo $wooCategoryTerm -> name; 
                    ?>
                </a>
                <ul class="wsubcategs">
                    <?php
                        $wooSubArgs = array(
                            'hierarchical' => true,
                            'hide_empty' => true,
                            'parent' => $wooCategoryTerm -> term_id,
                            'taxonomy' => 'product_cat'
                        );

                        $wooSubCategories = get_categories($wooSubArgs);

                        foreach ($wooSubCategories as $wooSubCategory):
                    ?>
                            <li>
                                <a href="<?php echo get_term_link( $wooSubCategory -> slug, $wooSubCategory -> taxonomy );?>">
                                    <?php 
                                        echo $wooSubCategory -> name;
                                    ?>
                                </a>
                            </li>
                            <?php
                        endforeach;
                            ?>  
                </ul>
            </li>
        </ul>
        <?php 
    endforeach; 
        ?>

Solution

  • get_terms returns all the terms for the specific taxonomy given, and not the post. You have a couple of choices here, but I like to use wp_list_categories of its flexibility. It not only works with build in categories, but also with custom taxonomies

    Here is an example from the codex

    <?php
    $taxonomy = 'category'; //change to your taxonomy name
    
    // get the term IDs assigned to post.
    $post_terms = wp_get_object_terms( $post->ID, $taxonomy, array( 'fields' => 'ids' ) );
    // separator between links
    $separator = ', ';
    
    if ( !empty( $post_terms ) && !is_wp_error( $post_terms ) ) {
    
        $term_ids = implode( ',' , $post_terms );
    $terms = wp_list_categories( 'title_li=&style=none&echo=0&taxonomy=' . $taxonomy . '&include=' . $term_ids );
    $terms = rtrim( trim(  str_replace( '<br />',  $separator, $terms ) ), $separator );
    
    // display post categories
    echo  $terms;
    }
    ?>
    

    You can also make use of get_the_terms