[]Here’s yet another time-saving WooCommerce function. No need to reinvent the wheel — with a single line of code and no custom queries, you can get all the categories a product belongs to.
[]This week’s function is wc_get_product_category_list, and there’s no need to explain what it does as its name is self-explanatory.
[]As usual, we’ll study the WooCommerce core function code, see where and why it’s used, and finally we’ll cover a quick case study. Enjoy!
Function code
[]The function wc_get_product_category_list can be found under woocommerceincludeswc-product-functions.php:
/** * Returns the product categories in a list. * * @param int $product_id Product ID. * @param string $sep (default: ‘, ‘). * @param string $before (default: ”). * @param string $after (default: ”). * @return string */ function wc_get_product_category_list( $product_id, $sep = ‘, ‘, $before = ”, $after = ” ) { return get_the_term_list( $product_id, ‘product_cat’, $before, $sep, $after ); } []First of all, let’s look at the function parameters:
- $product_id, which is of course the product we want to get the categories for.
- $sep, by default a comma, which defines the list separator.
- $before and $after, by default empty strings, which define what shows before and after the list of categories. (prefix / suffix)
[]Now to the function statements — actually, statement, as there is only one:
return get_the_term_list( $product_id, ‘product_cat’, $before, $sep, $after ); []That really sounds like a WordPress function as there is no mention of “woo,” “wc,” or any other WooCommerce prefixes. Let’s look it up in the WordPress developer code reference documentation. (https://developer.wordpress.org/reference/functions/get_the_term_list/)
[]Here we go:
function get_the_term_list( $post_id, $taxonomy, $before = ”, $sep = ”, $after = ” ) { $terms = get_the_terms( $post_id, $taxonomy ); if ( is_wp_error( $terms ) ) { return $terms; } if ( empty( $terms ) ) { return false; } $links = array(); foreach ( $terms as $term ) { $link = get_term_link( $term, $taxonomy ); if ( is_wp_error( $link ) ) { return $link; } $links[] = ‘‘ . $term->name . ‘‘; } /** * Filters the term links for a given taxonomy. * * The dynamic portion of the hook name, `$taxonomy`, refers * to the taxonomy slug. * * Possible hook names include: * * – `term_links-category` * – `term_links-post_tag` * – `term_links-post_format` * * @since 2.5.0 * * @param string[] $links An array of term links. */ $term_links = apply_filters( “term_links-{$taxonomy}”, $links ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores return $before . implode( $sep, $term_links ) . $after; } []Simple enough — get_the_term_list accepts basically the same parameters we covered above, plus the $taxonomy parameter, which in our case is passed as product_cat to tell WordPress we’re retrieving WooCommerce product categories.
[]Here’s how it works:
- get_the_terms( $post_id, $taxonomy ) gets the product ID category objects.
- $links array gets filled with the list of categories, each with its own link.
- return $before . implode( $sep, $term_links ) . $after gives us the content we need: “prefix + $links separated with $sep + suffix”
Function usage
[]Define a product ID (e.g., 57) — and that’s all you need to do!
[]Call the function:
echo wc_get_product_category_list( 57 ); []And see the magic happen:
cat1 link, cat2 link, cat3 link, … []Of course, if you have access to the $product global, you can call the function dynamically. For example, if you want to call the function on every single product pages, you could do this:
echo wc_get_product_category_list( $product->get_id() ); []Now I want to see where and when the function is called, so we give it a bit of context. With a quick search through the WooCommerce plugin, I find a single result in woocommercetemplatessingle-productmeta.php, line 34:
get_id(), ‘, ‘, ‘‘ . _n( ‘Category:’, ‘Categories:’, count( $product->get_category_ids() ), ‘woocommerce’ ) . ‘ ‘, ‘‘ ); ?> []Which generates this output on my single product page:
[]Now we know wc_get_product_category_list is responsible for showing the list of categories in the single product page where it comes with a prefix (‘Category:’ or ‘Categories:’ based on category count) plus the default comma separator and no suffix.
[]Let’s use wc_get_product_category_list for our custom development example now and consider a quick case study.
Case study
[]Where could wc_get_product_category_list come in handy? Surely, in the shop page.
[]By default, WooCommerce shows the list of products with image, title, price and button. There is no mention of product categories there, so let’s add them ourselves.
[]Before:
[]The custom snippet:
/** * @snippet Show Categories | WooCommerce Shop * @how-to Get CustomizeWoo.com FREE * @author Rodolfo Melogli * @testedwith WooCommerce 6 * @donate $9 https://businessbloomer.com/bloomer-armada/ */ add_action( ‘woocommerce_after_shop_loop_item’, ‘bbloomer_show_product_categories’, 9 ); function bbloomer_show_product_categories() { global $product; echo wc_get_product_category_list( $product->get_id(), ‘ – ‘, ‘[]In: ‘, ‘ ‘ . _n( ‘category’, ‘categories’, count( $product->get_category_ids() ), ‘woocommerce’ ) . ‘
‘ ); } []After:
[]A few notes:
- I used the woocommerce_after_shop_loop_item hook with priority 9, which is just before priority 10 (the add-to-cart button). TLDR: I’m outputting the category list above the add to cart button.
- I declare the global $product so that I can access the product ID.
- I then call the wc_get_product_category_list function, with the following parameters:
- $product->get_id() -> the product ID
- ‘ – ‘ -> the separator
- ‘[]In: ‘ -> the prefix
- ‘ ‘ . _n( ‘category’, ‘categories’, count( $product->get_category_ids() ), ‘woocommerce’ ) . ‘
‘ -> the suffix
[]It’s interesting how I reused this line from the single product page, as I mentioned above:
_n( ‘category’, ‘categories’, count( $product->get_category_ids() ), ‘woocommerce’ ) []Basically, if count = 1 the first string is returned (singular “category”), while if count > 1 you get the plural “categories.” You can see the difference in the last screenshot above.
[]Any other use cases you have in mind? Let me know in the comments!
[]Rodolfo Melogli
[]Author, WooCommerce expert and WordCamp speaker, Rodolfo has worked as an independent WooCommerce freelancer since 2011.