I am working in WooCommerce and trying to filter out the empty sub categories. I found this code, which filters out everything "empty"...including my Home page link, About us link, etc.

function exclude_empty_cat_menu_items( $items, $menu, $args ) {
  // Get a list of product categories that excludes empty categories
  $non_empty_categories = get_categories(array('taxonomy' => 'product_cat'));
 // Iterate over the menu items
 foreach ( $items as $key => $item ) {
$is_empty = true;
// check current item is in the non-empty categories array
foreach ( $non_empty_categories as $key => $cat )
  if ($item->title == $cat->name) 
    $is_empty = false;
  // if it is empty remove it from array
  if ($is_empty) unset($items[$key]);
 return $items;
  add_filter( 'wp_get_nav_menu_items', 'exclude_empty_cat_menu_items', null, 3 );

And here is my menu...

$args = array(
'theme_location' => 'lower-bar',
'depth' => 0,
'container' => false,
'fallback_cb' => false,
'menu_class' => 'nav navbar-nav',
'walker' => new BootstrapNavMenuWalker()

I'm not married to the idea of using the WordPress menu this way. I normally hard code it in. Is there any way I can accomplish showing all parent categories and pages while filtering out empty child categories?


1 Answer 1


I would go about this slightly differently. Still using the wp_get_nav_menu_items filter, but first I'll build an array containing the IDs of all empty terms. Then I'll compare each of the $items to this for potential exclusion:

add_filter( 'wp_get_nav_menu_items', 'wpse177082', 10, 3 );
function wpse177082 ( $items, $menu, $args ) {
        global $wpdb;
        $empty = $wpdb->get_col( "SELECT term_taxonomy_id FROM $wpdb->term_taxonomy WHERE count = 0" );
        foreach ( $items as $key => $item ) {
                if ( ( 'taxonomy' == $item->type ) && ( in_array( $item->object_id, $empty ) ) ) {
                        unset( $items[$key] );
        return $items;

You could of course further restrict this to only affecting WooCommerce Product Categories if needed.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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