1

Scenario: Clients can add or remove posts at will, but may not be comfortable (or even bother) adding categories to a menu.

Problem: This can cause empty categories to be displayed in menus.

Question: Is there a core function or resource that can be called from functions.php that will cause empty categories not to show on the front side even if they are showing as added in the dashboard.

Previous research: I have searched in both Google and this StackExchange for an answer. I may not be finding it by using the wrong search terms.

6
  • 1
    Are you talking only about wp_nav_menus? If so, I'd suggest building more widgets into the site rather than strictly menus. That way for example in a blog sidebar you could add a menu widget which will automatically hide empty categories and also automatically add any new categories they create.
    – WebElaine
    Apr 11, 2018 at 19:21
  • To be sure I understand you correctly, when you say, "wp_nav_menu's" does this mean all menus that are created and managed in Appearance -> Menus and only those menus? Apr 11, 2018 at 19:28
  • 1
    Yes, precisely.
    – WebElaine
    Apr 11, 2018 at 20:54
  • Taking the next step, it seems that you are saying that if a menu is created in Appearance -> Menu and then added to the site as a Custom Menu in Appearance -> Widgets, it will not show empty Categories. If that is correct, then the function to check for empty Categories is in the code for sidebars or widgets, not in the code for Menus. Am I understanding correctly? Apr 11, 2018 at 23:03
  • No. I am saying that instead of adding a custom Menu in the widgets screen, you would instead add a Category widget. WP's built-in widgets will automatically grab the current list of categories that contain posts. Menus are always managed by the user so they fall out of date - the exception being you can set one to always include new Pages. (I mistyped above - rather than adding a "menu widget" I should have said "category widget".)
    – WebElaine
    Apr 12, 2018 at 13:27

2 Answers 2

4

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 ) {
    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;
}

Please use the above code, it will unset the category which has No post. Assuming that you were are managing Menu from Apperance->Menu.

Hope that helps :)

3
  • I will try this and report on the results. Apr 12, 2018 at 16:36
  • Yes, this code did the job I needed! Apr 16, 2018 at 17:36
  • I recommend reading the solution posted by @Gui if you want to keep the menus instead of removing them.
    – gael
    Mar 24, 2020 at 12:37
4

It's a fairly old tread but using @Aishan's function in a similar context I faced an issue.

Without the is_admin() condition before the exclusion of the empty categories from the menu items, these items would be excluded from the menu edit in the wp-admin. That means that they would be deleted from the menu if anyone save the menu while these categories are empty.

In my specific case I needed the menu items to remain there while just being filtered on the front if empty. If the category become not empty again, the item will then reappear in the menu.

Anyway here is my edited version

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;

}
1
  • Thanks for your warning @gui because the loss of my empty categories would have been a mess for me and my client and me... I would suggest your answer as the Accepted answer because the accepted one does not hide (as asked) the menu but removes it. Which can be annoying when products of the category removed in menu are back in stock.
    – gael
    Mar 24, 2020 at 13:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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