How to Acheive the custom woocommerce category template

Lets see if this is helpfull.
From your description you have/want the following setup:

-Category 
--Sub-Category-1
---Products of Sub-Category-1
--Sub-Category-2
---Products of Sub-Category-2
--Sub-Category-3
---Products of Sub-Category-3

OK, so you first need to get all top level categories. You can get them with something like this:

$top_categories_args = array(
    'taxonomy' => 'product_cat', // the taxonomy we want to get terms of
    'parent' => 0 // all top level cats with a parent of 0
);
$top_categories = get_terms( $top_categories_args );

With an foreach loop the iterate trough all top level cats:

foreach ($top_categories as $top_category) {

    $top_id = $top_category->term_id; // get term ID
    $top_slug = $top_category->slug; // get term slug
    $top_name = $top_category->name; // get term title
    $top_desc = $top_category->description; // get term description

    echo '<div class="'.$top_slug.'">';

    echo '<h2>'.$top_name.'</h2>';

    if ($top_desc) {
        echo '<p>'.$top_desc.'</p>';
    }

    // here we now need to get all the sub-categories

    echo '</div><!-- END top categories container -->';

}

Now we need an similar new get_terms query for the sub-categories:
(should replace”// here we now need to get all the sub-categories”)

// here we get all the sub categories of the current cat

$sub_categories_args = array(
    'taxonomy' => 'product_cat',
    'parent' => $top_id // we use the top_id from before to get only sub-cats
);
$sub_categories = get_terms( $sub_categories_args );

foreach ($sub_categories as $sub_category) {

    $sub_id = $sub_category->term_id;
    $sub_slug = $sub_category->slug;
    $sub_name = $sub_category->name;
    $sub_desc = $sub_category->description;

    echo '<div class="'.$top_slug.'-'.$sub_slug.'">';

    echo '<h3>'.$sub_name.'</h3>';

    if ($sub_desc) {
        echo '<p>'.$sub_desc.'</p>';
    }

    // here we now need to get all the products inside this sub-categories

    echo '</div><!-- END sub categories container -->';

}

And now, inside this sub-category code, you can now get the products with a query combined with a tax_query.
(should replace”// here we now need to get all the products inside this sub-categories”)

$products_args = array(
    'post_type'     => 'product', 
    'tax_query'     => array( 
        array(
            'taxonomy' => 'product_cat',
            'field'    => 'term_id', // we look for the ID, you could also use slug
            'terms'    => $sub_id, // get only products with the sub-cat ID
        ),
    ),
);
$products = new WP_Query( $products_args );

if ( $products->have_posts() ) { // only start if we hace some products

    // START some normal woocommerce loop

    woocommerce_product_loop_start();

    while ( $products->have_posts() ) : $products->the_post();

        wc_get_template_part( 'content', 'product' );

    endwhile; // end of the loop.

    woocommerce_product_loop_end();

    // END the normal woocommerce loop

    // Restore original post data, maybe not needed here (in a plugin it might be necessary)
    wp_reset_postdata();

} else { // if we have no products, show the default woocommerce no-product loop

    // no posts found
    wc_get_template( 'loop/no-products-found.php' );

}//END if $products

I created a gist here, with an complete product-archive.php and more details: product-archive.php


If you have some terms that you dont want to show, you can use exclude or exclude_tree, to disable them. For more options take a look at the codex page here.

// first we get all top-level categories
$top_categories_args = array(
    'taxonomy' => 'product_cat', // the taxonomy we want to get terms of
    'parent' => 0, // all top level cats with a parent of 0
    'hide_empty' => true,
    'exclude' => '11,23,99', // Array or comma/space-separated string of term ids to exclude.
    'exclude_tree' => '2,5,12' // Array or comma/space-separated string of term ids to exclude along with all of their descendant terms.
);

Also you can change the order of the terms with the default drag and drop function from WooCommerce. Just drag and drop the terms in the backend.

Leave a Comment