4

I have menus set corresponding to a custom field on a page. Ie I have menu1, menu2, and menu3 on three pages under custom field => MenuName. Under functions.php I have:

/* Add Menu Locations */
add_action( 'init', 'register_my_menus' );
function register_my_menus() {
    register_nav_menus(
        array(
            'one-menu' => __('menu1'),
            'two-menu' => __('menu2'),
            'three-menu' => __('menu3'),
            'footerBlocka' => __('Footer Block 1'),
            'footerBlockb' => __('Footer Block 2'),
            'footerBlockc' => __('Footer Block 3'),
            'footerBlockd' => __('Footer Block 5')
        )
    );
}

Then in my page template I have:

<?php
    /* Division */
    wp_nav_menu(array(
        'menu' => get_post_meta( $post->ID, 'MenuName', true),
        'depth' => 2,
        'container' => false,
        'menu_class' => 'nav navbar-nav'
    ));
?>

This works just fine as long as a) the menu exists and b) the menu actually contains menu items. If the menu exists but there are no menu items, it strangely displays a listing of all menu items from all menus on the site. If the menu does not exist, it just shows the next menu listed in functions.php.

So I think in my page template I need to check for the menu and if it exists then print the menu. I have seen a couple of other examples but all I could find were if the theme region exists or a menu exists. Since I'm using 'menu' => get_post_meta( $post->ID, 'MenuName', true), to call the menu dynamically, I don't know how to check this dynamic menu before trying to print the menu.

So how do I check the menu that is called from 'menu' => get_post_meta( $post->ID, 'MenuName', true), and if it exists and has menu items then print it, if not, print nothing?

EDIT: I tried the following:

<?php
    /* Division */
    wp_nav_menu(array(
        'menu' => get_post_meta( $post->ID, 'MenuName', true),
        'depth' => 2,
        'fallback_cb' => false,
        'container' => false,
        'menu_class' => 'nav navbar-nav'
    ));
?>

This new addition will still render the next menu in line from the functions.php function. So if menu3 does not exist, it prints the footerBlocka menu. I am thinking my goal is to check page ID for MenuName custom field, if it exists, then check whether the menu exists and has links, if true, then print menu, else do nothing. Something like:

$menu = get_post_meta($post->ID, 'MenuName');
if($menu){
  if([wp_nav_menu == $menu AND has links]){
      wp_nav_menu(array(...));
  }
}

That's the pseudo code I think would be needed but I don't know enough about the WordPress hooks to know what it needs to be.

2 Answers 2

5

wp_nav_menu has the argument fallback_cb, which is the function called if a menu doesn't exist. This is set to wp_page_menu by default, which is why you see a list of pages if the menu doesn't exist. If you explicitly set that to false, then nothing will be output if the menu doesn't exist.

EDIT-

Given a menu name, you can load the menu object with wp_get_nav_menu_object. This will tell you if it exists, what its ID is (to pass as menu argument), and how many menu items it has.

$menu_name = get_post_meta( $post->ID, 'MenuName', true );
$menu = wp_get_nav_menu_object( $menu_name );
if( is_object( $menu ) ){
    echo 'This menu exists!';
    echo 'This menu has ' . $menu->count . ' menu items.';
    echo 'This menu ID is ' . $menu->term_id . '.';
} else {
    echo 'A menu with that name doesn\'t exist';
}
10
  • I added an edit to my question. I tried what fallback_cb and that doesn't seem to help. It is still printing the next menu from the functions.php list if the menu does not exist.
    – o_O
    Commented Nov 5, 2015 at 4:13
  • 1
    I'm not sure I understand what you're describing. Have you tried has_nav_menu?
    – Milo
    Commented Nov 5, 2015 at 5:13
  • For example, I have added the edit in the template the one with fallback_cb. If you check the functions.php portion, you will not three-menu is followed by footerBlocka in the code. On my page, if it's calling three-menu from the MenuName custom field, and this menu does not exist, then the page template will render the footerBlocka menu since it is next in line in functions.php presumably. If two-menu doesn't exist, it tries three-menu, and on down the line until it comes to a menu that does exist. Do you see what I mean?
    – o_O
    Commented Nov 5, 2015 at 17:07
  • I don't know what I would need to do with has_nav_menu since it appears it calls for a specific location check in $location? As far as the template php goes above, it doesn't know the menu location until it starts the wp_nav_menu and checks to page ID and custom field MenuName.
    – o_O
    Commented Nov 5, 2015 at 17:09
  • ok, I think I understand the problem, will edit answer in a moment.
    – Milo
    Commented Nov 5, 2015 at 17:43
2

A simpler approach is to just use:

<?php if(wp_get_nav_menu_items(get_nav_menu_locations()['theme_location'])): ?>
    Do something here IF the menu location you used in the line above has any items
<?php endif; ?>
3
  • This worked as expected, Thanks.
    – Jodyshop
    Commented Oct 8, 2021 at 23:15
  • @Jodyshop Glad to hear!
    – revive
    Commented Oct 11, 2021 at 16:48
  • Make sure to check for isset( get_nav_menu_locations()['theme_location'] ) first as it might be undefined.
    – KittMedia
    Commented Apr 4, 2022 at 6:00

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.