0

I have a strange issue with my if/else test for "has_nav_menu()" I have three menu locations in the template and each is tested if a menu exist in the defined location. However this example below does not echo the warning i want when and if a menu does not exist. The first test works fine, but this one does not. What am i missing ?

<!-- Secondary Navigation Area -->                  
        <div class="row">
            <div class="small-12 columns">
                <?php
                    if ( has_nav_menu( 'header-top' ) ) {
                        wp_nav_menu( array(
                            'theme_location'    => 'header-top',
                            'container'         => 'nav',
                            'menu_class'        => 'right no-bullets no-margin',                                        
                            'fallback_cb'       => false,                               
                        ));
                    } else {
                        /* echo Fallback code if no menu has been choosen from the dashboard */
                        echo '<p class="warning dark-bg">Her mangler det en meny.   Venligst gå tilbake til kontrollpanelet, <strong>Utseende > Menyer > Bestem plassering</strong> og velg en meny.</p>';
                    }
                ?>
            </div>
        </div>
2
  • what does echo has_nav_menu('header-top') return?
    – Guerrilla
    Commented Apr 29, 2015 at 12:19
  • If the custom menu exist i.e created on the dashboard and placed in theme location, it returnd the menu. If NOT the 'else' statement should (but in this case does not) echo a warning text instructing the user to return to the dashboard and added a menu to the location. Commented Apr 29, 2015 at 12:56

1 Answer 1

2

If you check out has_nav_menu(), you'll see that it first checks if a menu exists for the location (what we expect).

However, it will also return true if the location is merely registered, hence why your condition is still true even when there's no menu:

function has_nav_menu( $location ) {
    $registered_nav_menus = get_registered_nav_menus();
    if ( ! isset( $registered_nav_menus[ $location ] ) ) {
        return false;
    }

    $locations = get_nav_menu_locations();
    return ( ! empty( $locations[ $location ] ) );
}

Instead, use the snippet from above to just check if an actual menu is registered:

$registered_nav_menus = get_registered_nav_menus();
if ( isset( $registered_nav_menus[ 'header-top' ] ) ) {
    // Your nav menu
} else {
    // No menu
}

Update: To check a valid menu exists & has items, use echo => false and check the output:

$menu = wp_nav_menu(
    array(
        'theme_location' => 'header-top',
        'container'      => 'nav',
        'menu_class'     => 'right no-bullets no-margin',
        'fallback_cb'    => false,
        'echo'           => false,
    )
);

if ( $menu ) {
    echo $menu;
} else {
    echo 'No menu!';
}
2
  • Thank you for your reply, you're IF test works fine on the first menu tested but does not work on the following menu tests. Which is the same result i got earlier with "has_nav_menu". Is there some consideration i am missing when running three consecutive tests (of different theme locations) ? Commented Apr 29, 2015 at 13:35
  • It will still fail if a menu is assigned, but empty (i.e. has no items). You can use the echo argument for wp_nav_menu instead (see revision). Commented Apr 29, 2015 at 13:52

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.