you can get the product categories using the get_terms() and a loop.
<?php
$cat_args = array( 'orderby' => 'name', 'order' => 'asc', 'hide_empty' => true);
$cats = get_terms( 'product_cat', $cat_args );
foreach ($cats as $key => $cat):
if ($cat->parent == 0): ?>
<a href="<?php echo get_term_link($cat) ?>"><?php echo $cat->name; ?></a> <?php
endif;
endforeach;
This gives back the categories ("first generation"), to have sub-categories we just need to add a new loop inside the one we have. next code goes already until the third generation.
<?php
$cat_args = array( 'orderby' => 'name', 'order' => 'asc', 'hide_empty' => true);
$cats = get_terms( 'product_cat', $cat_args );
foreach ($cats as $key => $cat):
if ($cat->parent == 0): ?>
<a href="<?php echo get_term_link($cat) ?>"><?php echo $cat->name; ?></a> <?php
foreach ($cats as $key => $cat2):
if ($cat2->parent == $cat->term_id): ?>
<a href="<?php echo get_term_link($cat2) ?>"><?php echo $cat2->name; ?></a> <?php
foreach ($cats as $key => $cat3):
if ($cat3->parent == $cat2->term_id): ?>
<a href="<?php echo get_term_link($cat3) ?>"><?php echo $cat3->name; ?></a><?php
endif;
endforeach;
endif;
endforeach;
endif;
endforeach;
This only shows the categories with products, to have all the categories just change the 'hide_empty' on the first line to false.
To show the products name of a category or sub-category we can use this function.
<?php
function get_prod($prod_per_page, $prod_slug){
$args = array( 'posts_per_page' => $prod_per_page,
'tax_query' => array(
'relation' => 'AND',
array('taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => $prod_slug
)
),
'post_type' => 'product',
'orderby' => 'title'
);
$products = new WP_Query( $args );
echo "<ul>";
while ( $products->have_posts() ) {
$products->the_post(); ?>
<li>
<a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
</li> <?php
}
wp_reset_postdata();
echo "</ul>";
}
Now we can add next to the a tag this custom function that has 2 parameters, first the number of products to show, where -1 is all and e.g. for 4 products is 4, the second is the category slug.
And here it is the answer, now you can delete the 3th "generation" of categories if not needed and change the number of products to show per page.
<?php
function get_prod($prod_per_page, $prod_slug){
$args = array( 'posts_per_page' => $prod_per_page,
'tax_query' => array(
'relation' => 'AND',
array('taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => $prod_slug
)
),
'post_type' => 'product',
'orderby' => 'title'
);
$products = new WP_Query( $args );
echo "<ul>";
while ( $products->have_posts() ) {
$products->the_post(); ?>
<li>
<a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
</li> <?php
}
wp_reset_postdata();
echo "</ul>";
}
$cat_args = array( 'orderby' => 'name', 'order' => 'asc', 'hide_empty' => true);
$cats = get_terms( 'product_cat', $cat_args );
foreach ($cats as $key => $cat):
if ($cat->parent == 0): ?>
<a href="<?php echo get_term_link($cat) ?>"><?php echo $cat->name; ?></a> <?php
get_prod(-1, $cat->slug);
foreach ($cats as $key => $cat2):
if ($cat2->parent == $cat->term_id): ?>
<a href="<?php echo get_term_link($cat2) ?>"><?php echo $cat2->name; ?></a> <?php
get_prod(10, $cat2->slug);
foreach ($cats as $key => $cat3):
if ($cat3->parent == $cat2->term_id): ?>
<a href="<?php echo get_term_link($cat3) ?>"><?php echo $cat3->name; ?></a><?php
get_prod(4, $cat3->slug);
endif;
endforeach;
endif;
endforeach;
endif;
endforeach;
The first parameter of this get_prod() is to change for the number of products each one wants to show.
the html, css or javascript can be added!
Hope that it helps!