I'm using WooCommerce on my Wordpress site, and have a widget in the sidebar showing all product categories. It's setup to hide empty categories, and that works well. However, it still shows categories that contain only products that are out of stock - that I would like to change.

Technical explanation: WooCommerce products are a custom post type (product), the product categories are a custom taxonomy (product_cat), and the stock count is a custom field on the products (_stock). The WooCommerce Product Categories widget shows them using wp_list_categories(). I have tried digging into a code to look for some filter call that I could hook onto, but failed to find one.

Is there a good way of doing this without modifying core or WooCommerce code? Maybe a hook/filter somewhere that I missed that would allow to check the custom field value?

closed as off-topic by Johannes Pille, TheDeadMedic, birgire, Mark Kaplun, mrwweb Sep 4 '14 at 22:10

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "Your question should be specific to WordPress. Generic PHP/JS/HTML/CSS questions might be better asked at Stack Overflow or another appropriate site of the Stack Exchange network. Third party plugins and themes are off topic." – Johannes Pille, TheDeadMedic, birgire, Mark Kaplun, mrwweb
If this question can be reworded to fit the rules in the help center, please edit the question.


Use the woocommerce_product_categories_widget_args and woocommerce_get_availability filters in a custom function to filter the product categories widget for out of stock products.

See what you can come up using these filters and post the code back here if you get stuck.

Here's some code from my site which may help you get started.

add_filter( 'woocommerce_product_categories_widget_args', 'wpsites_exclude_product_cat_widget' );

function wpsites_exclude_product_cat_widget( $args ) {

$args['exclude'] = array('16','46');

return $args;

Here's all the hooks for WooCommerce

  • +1. I was just thinking about this approach, but in the reverse... using the 'include' parameter. If you query all the products in each category, as soon as you find 1 product in stock you can add that to the 'included' array and skip to the next category instead of checking every category. Apparently, this is an old question (I don't always notice dates), but I'm intrigued by it. – helgatheviking Feb 23 '14 at 8:45
  • Wrote the below after finding this thread in a Google search. I'm assuming the query itself could be optimized, my sql is weak. Curious to see how this approach compares to @helgatheviking's idea to loop, speedwise. gist.github.com/karpstrucking/1f6139d6899b1709f545 – karpstrucking Jan 16 '16 at 18:53

I'm not sure this is possible as I don't think there is a place in wp_list_categories() that would ever check the status of the posts/products in the category. Even if there was, you'd have to query a lot of products in ALL the categories which would be highly inefficient.

You could, maybe, replace the WC_Product_Cat_Dropdown_Walker and do your checking there.

The responsible function looks as if it accepts another Walker:

 * Walk the Product Categories.
 * @return mixed
function wc_walk_category_dropdown_tree() {
    global $woocommerce;

    if ( ! class_exists( 'WC_Product_Cat_Dropdown_Walker' ) )
        include_once( WC()->plugin_path() . '/includes/walkers/class-product-cat-dropdown-walker.php' );

    $args = func_get_args();

    // the user's options are the third parameter
    if ( empty( $args[2]['walker']) || !is_a($args[2]['walker'], 'Walker' ) )
        $walker = new WC_Product_Cat_Dropdown_Walker;
        $walker = $args[2]['walker'];

    return call_user_func_array(array( &$walker, 'walk' ), $args );

So if you duplicated the widget you could ostensibly change

// Stuck with this until a fix for http://core.trac.wordpress.org/ticket/13258
            wc_product_dropdown_categories( array(
                'show_counts'        => $c,
                'hierarchical'       => $h,
                'show_uncategorized' => 0,
                'orderby'            => $o
            ) );


// Stuck with this until a fix for http://core.trac.wordpress.org/ticket/13258
            wc_product_dropdown_categories( array(
                'show_counts'        => $c,
                'hierarchical'       => $h,
                'show_uncategorized' => 0,
                'orderby'            => $o,
                                'walker'             => 'InStock_Categories'
            ) );

And then you'd be responsible for creating and including an InStock_Categories Walker class. Totally untested, but just throwing some ideas out there.


If you go to WooCommerce => Settings and select the 'Inventory' tab you'll see an option to 'Hide out of stock items from the catalog'. If you enable this option then out of stock items won't be displayed and if a category doesn't contain any sellable (out of stock or no price) items it will be hidden as well.


Ok I read 'widget' and totally ignored it in my answer.

The WooCommerce Product Categories widget doesn't support filtering the products/categories as far as I know. So no hook or filter that I'm aware of.

But you could easily copy the single file and modify it as a stand alone widget that wouldn't be over written by a WooCommerce upgrade.

Hope that helps.

  • The option is checked. The out of stock items are not shown on shop pages, but they still count into category product numbers, and categories only containing out-of-stock items are still shown in the widget. – olex Dec 5 '12 at 8:50
  • Zoned out on the 'Widget'. See my updates in the answer. – Steve Dec 5 '12 at 14:13
  • It does support filtering the categories in the widget which you can also use with WooCommerce conditional tags. – Brad Dalton Feb 22 '14 at 0:36
  • @BradDalton Would you be so helpful as to add an answer to this question with links to the appropriate documentation? This would greatly improve the quality of the question/answer. – Steve Feb 23 '14 at 0:51
  • olex needs to post some code here and contribute some of the work. I have provided 2 filters and half the code to get started with this solution. There are others. – Brad Dalton Feb 23 '14 at 8:07

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