Search code examples
phpwordpresswoocommercemenunavbar

WooCommerce - Hide empty categories and subcategories from the navbar automatically


I have the following block of code that allows for any empty category or subcategory archive pages to become hidden from the navbar but it has two distinct issues that I need help fixing.

  1. The code hides the empty archive pages at both front and back ends which makes editing menus at the back end difficult as the code needs to be manually removed and then re-added after menu alterations have been made.
  2. Categories and subcategories are not automatically added to the menu sections of the website. I cannot activate the section 'Automatically add new top-level pages to this menu' as this is global and doesn't apply only to product categories/subcategories.

The code I am currently using is as follows:

/* HIDE EMPTY CATEGORIES AND SUBCATEGORIES FROM NAVBAR - TO CORRECTLY EDIT THE MENU AT THE BACK-END, MAKE SURE YOU REMOVE THIS CODE */

function hide_empty_navbar_items ( $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;
}
add_filter( 'wp_get_nav_menu_items', 'hide_empty_navbar_items', 10, 3 );

Solution

  • I managed to find the following code which allows you to hide the empty category and subcategory levels from the navbar at the front end of the site whilst also allowing for anyone logged in as an Admin to still see the complete menu structure at the back end.

    This code essentially fixes the issue with the code left in the initial question and offers a much more practical solution.

    add_filter( 'wp_get_nav_menu_items', 'nav_remove_empty_category_menu_item',10, 3 );
      function nav_remove_empty_category_menu_item ( $items, $menu, $args ) {
        if ( ! is_admin() ) {
          global $wpdb;
          $nopost = $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, $nopost ) ) ) {
              unset( $items[$key] );
            }
          }
        }
        return $items;
      }