How To Show WooCommerce Categories On Product Pages

I was recently working on building a little eCommerce store for a client and they wanted to have the categories show up on the product category pages. This design didn't have a sidebar, so the usual option was out. I had to dig into the WooCommerce template code to figure it out.

So how do you show WooCommerce categories on the product pages? Write a function that hooks into woocommerce_before_main_content and use a conditional like is_product_category() to display the product_categories shortcode.

Here's how I did it. I put the following code into the functions.php for the child theme...

/*** WooCommerce Add Categories to Product List ***/
add_action ('woocommerce_before_main_content', 'add_categories_to_product_list');

function add_categories_to_product_list()
{
	if (is_product_category()) {
		echo do_shortcode('[product_categories]');
	}
}

This was built using WordPress 4.9.8 and WooCommerce 3.4.5, but will work for anything over WooCommerce 3.1. If you're reading this and still using WooCommerce pre-3.1, go right now and update on a staging site, then roll it out to your live site. No really, stop reading and go do that now.

What Parameters Are Available For Customising The product_categories shortcode?

The official documentation is surprisingly unhelpful on this. You have a number of parameters available to customise the product_categories shortcode. They are:

  • ids - comma separated list of ids if you want to restrict them. Otherwise will display all categories
  • number - number to display
  • orderby - use name, title, date, ID, parent, rand or menu_order
  • orderasc or desc
  • columns - number of columns
  • parent - id of the parent category if you want to limit it, 0 being the top level
  • hide_empty - 1 for hiding empty categories, 0 to display all

The order you write the parameters doesn't matter.

Customise Your Category Display

The problem I ran into with just that code was that it used the default WooCommerce styling that I used for the shop. I really wanted it to be more of a menu bar.

You can't just apply styling to what's outputted, because it uses the same classes as the rest of the store.

You could always just insert a custom menu at that spot, but I wanted something more dynamic, so I didn't have to go back and touch the site over something so minor.

The solution was to wrap the shortcode in a div and apply the CSS to that. I also changed the number of columns from the default 4 to better suit the spacing.

This was my final code:

/*** WooCommerce Add Categories to Product List ***/
add_action ('woocommerce_before_main_content', 'add_categories_to_product_list');

function add_categories_to_product_list()
{
	if (is_product_category()) {
		echo "<div id='wc-category-menu'>";
		echo do_shortcode('[product_categories columns="5"]');
		echo "</div>";
	}
}

And CSS...

#wc-category-menu {
	margin-top: 30px;
	background-color: #fcfcfc;
}
#wc-category-menu ul,
#wc-category-menu ul li {
	margin-bottom: 0;
}
#wc-category-menu .wc-product-image {
	display:none;
}
.tax-product_cat .inside-article {
	padding-top: 20px;
}

What If You Want To Display The Categories Elsewhere On The Page?

The template file you're hooking into is

/wp-content/plugins/woocommerce/templates/archive-product.php

That page has hooks at a number of different spots.

If you wanted to show the categories under the title, you'd hook it into woocommerce_archive_description.

Underneath the content, you can choose between woocommerce_after_shop_loop and woocommerce_after_main_content.

I'd probably recommend hooking into woocommerce_after_main_content because woocommerce_after_shop_loop won't show if there are no products. But it depends on what effect you're going after.

Can You Use This Hook To Display A Menu Of The Categories?

The way you'd display the categories as a custom menu, as I talked about above, is you'd setup a new menu with the product categories, then replace the shortcode line with a menu call as follows:

wp_nav_menu(['menu' => 'test']);

Or if you needed to be safe for pre php 7.0, you'd use:

wp_nav_menu(array('menu' => 'test'));

Those examples are assuming the newly created menu slug is "test". Obviously replace it with your own menu slug. You could alternatively use the menu ID, just remove the quotes (because it's an integer, not a string).

Remember this will just bring the test menu in as an unordered list. Check out the documentation on wp_nav_menu() for all the options you have available to you.

Mike Haydon

Thanks for checking out my WordPress and coding tutorials. If you've found these tutorials useful, why not consider supporting my work?

Buy me a coffee

Leave a Comment