Exclude Empty Child Categories in Menu

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…

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

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.

Leave a Comment