0

I have a custom post type called "alz-products" under this i also have a taxonomy called "products-category"

The arranged category structure to manage products as follows

Spill Kits
|
|
|
|------ Chemical
        |
        |------ 15 to 120 Liters
        |------ 660 to 1100 Liters
        |------ 80 to 360 Liters

As you can see "Spill Kits" is the main parent category here under that there is child category "Chemical", then under "Chemical" there are child categories like "15 to 120 Liters" etc.

Basically "Spill kits" have more categories like "Chemical" which also have child categories under those. What i want is a way to list all the child categories under the child categories of parent on the main category page.

for example I want to list 15 to 120 Liters, 660 to 1100 Liters, 80 to 360 Liters on "Spill kits" page (ones makred as Child categories of Chemicals in the image below). no need of showing "Chemical" at all.

enter image description here

I have only able to list main child categories using this so far

$term_children = get_terms( array( 'taxonomy' => 'products-category', 'parent' => get_queried_object_id(), ) );

if ( ! is_wp_error( $terms ) ) {
foreach ( $term_children as $child ) {
 echo '
 <div class="product-archive">
  <div class="post-title">
 <h3 class="product-name"><a href="' . get_term_link( $child ) . '">' . $child->name . '</a></h3>
  </div>
  </div>
 ';
}
}

enter image description here

7
  • can you share the code for your spill kits page/template? If it does not exist make sure to say so, use the edit button to improve the question and add new information
    – Tom J Nowell
    Sep 26 at 15:15
  • @TomJNowell Actually i was only able to list the children categires in the template using this $term_children = get_terms( array( 'taxonomy' => 'products-category', 'parent' => get_queried_object_id(), ) ); if ( ! is_wp_error( $terms ) ) { foreach ( $term_children as $child ) { echo ' <div class="product-archive"> <div class="post-title"> <h3 class="product-name"><a href="' . get_term_link( $child ) . '">' . $child->name . '</a></h3> </div> </div> '; } } Sep 26 at 16:01
  • Why not just put them under both categories (spill kits and chemicals)?
    – rudtek
    Sep 26 at 16:26
  • Not clear about what you mean here Sep 27 at 6:33
  • note that if you get an answer that gives you what you literally asked for, there will be no way to tell the difference between 15-20 litre spill kits from different parent terms, it'll look like a tonne of duplicates that all lead to different places. Also it looks like you don't know about recursion
    – Tom J Nowell
    Sep 27 at 11:14

1 Answer 1

0

The missing part from what you've written in code is the idea of putting extra foreach loops inside the foreach loop you already have to go one level deeper. Likewise recursion would have solved this, but it's unlikely it would have been helpful once it was revealed what you were trying to build.

  • foreach child term
    • print that child term
    • fetch the grandchildren, aka the children of the child term
    • foreach grandchild term
      • print the grandchild term
      • fetch the great-grandchildren, aka the children of the grandchild term
      • foreach great-grandchild term
        • print the great-grandchild term
        • fetch the great-great-grandchildren aka the children of the great-grandchild term
        • foreach great-great-grandchild term
          • print the great-great-grandchild term
          • etc etc

Notice how each loop does the same thing but is nested one level deeper?

For example this prints out a list of child terms, with sub-lists of grandchild terms:


// ## display the child terms
$child_terms = get_terms( [
    'taxonomy' => 'products-category',
    'parent' => get_queried_object_id(),
] );
if ( ! is_wp_error( $child_terms ) ) {
    echo '<ul>';
    foreach ( $child_terms as $child_term ) {
        echo '<li>' . $child_term->name . '</li>';

        // ### display the grandchild terms
        $grandchild_terms = get_terms( [
            'taxonomy' => 'products-category',
            'parent'   => $child_term->parent,
        ] );
        if ( ! is_wp_error( $grandchild_terms ) ) {
            echo '<ul>';
            foreach ( $grandchild_terms as $grandchild_term ) {
                echo '<li>' . $grandchild_term->name . '</li>';

                // #### display the great-grandchild terms.. etc
                $greatgrandchild_terms = get_terms( [
                    'taxonomy' => 'products-category',
                    'parent' => $grandchild_term->parent,
                ] );
                if ( ! is_wp_error( $greatgrandchild_terms ) ) {
                    // etc...


            }
            echo '</ul>';
        }
        echo '</ul>';
    }
}

You could add additional loops inside the deepest foreach to grab 3, 4, or more levels deeper.

Note that earlier I mentioned recursion, this would allow you to write a single function that went infinitely deep, but this probably won't help you since you want to display each level using different HTML in different places.

For example:

function display_product_categories_as_list( int $term_id ) : void {
    $child_terms = get_terms( [
        'taxonomy' => 'products-category',
        'parent'   => $term->term_id,
    ] );
    if ( ! is_wp_error( $child_terms ) ) {
        echo '<ul>';
        foreach ( $child_terms as $child_term ) {
            echo '<li>' . $child_term->name . '</li>';
            display_product_categories_as_list( $child_term );
        }
    }
}

display_product_categories_as_list( get_queried_object_id() );

That would display the entire tree of terms as a list with child terms indented, but they would all be displayed the same, and it would go past 3 levels. Notice the function calls itself inside the loop, this is a basic form of recursion. Instead manual nested loops would work better for your use case.

4
  • This only prints the first child categories like Chemical Oil/Fuel Chemical Chemical Oil/Fuel Sep 29 at 8:08
  • this isn't copy pasta, it's to demonstrate that the solution is nesting as an example, you can keep nesting for great grandchild terms, and great great grandchild terms by going to the deepest foreach and putting another get_terms that uses $grandchild->parent instead of $child->parent, etc and so on and so on. If it was a copy paste solution you were after though then that's unfortunate, my goal is to explain how to solve it and answer the question
    – Tom J Nowell
    Sep 29 at 14:27
  • I've made tweaks and renamed things that should make it easier to read and understand, but it's not a copy paste solution and will require the answer and code to be read and understood. Without this understanding it would not be possible to adapt it to your desired HTML even if it was a copy paste solution
    – Tom J Nowell
    Sep 29 at 14:33
  • I've also added an example of a recursion function
    – Tom J Nowell
    Sep 29 at 14:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.