Custom Menus Implementation: Use theme_location instead of menu in wp_nav_menu()
In several recent Theme reviews, I have noticed that Themes are implementing custom navigation menus incorrectly, primarily due to the arguments passed to wp_nav_menu. For example:
<?php
wp_nav_menu( array(
'menu' => 'primary-nav'
) );
?>
Notice what’s wrong there? Yeah: the 'menu' parameter.
By passing the 'menu' parameter, the Theme is telling WordPress, “display the user-defined menu with this slug“. This parameter will only work in one of two cases:
- As a matter of serendipity, the user has created a custom menu with the slug “primary-nav” (i.e. a custom menu named “Primary Nav”)
- As a matter of chance, the user has only defined one custom menu, which WordPress will use as an alternate, when it cannot find a menu with the slug “primary-nav”
In pretty much all other cases, the user-defined menu assigned to a given Theme location will not output correctly.
Instead, Themes should only and always pass the 'theme_location' parameter to wp_nav_menu(). The 'theme_location' parameter corresponds to the array keys passed to register_nav_menus(), like so:
register_nav_menus( array(
'primary-nav' => "Primary Menu",
'footer-nav' => "Footer Menu"
) );
The array key is the 'theme_location', and the array value is the title that displays under the “Theme Locations” meta box on the Dashboard -> Appearance -> Menus screen. So, Themes should pass those array keys to calls to wp_nav_menu(), like so:
<?php
wp_nav_menu( array(
'theme_location' => 'primary-nav'
) );
?>
That way, custom navigation menus will work properly:
- Theme registers custom menu Theme locations, via
register_nav_menus() - User creates custom menus, via the Dashboard -> Appearance -> Menus screen
- User assigns custom menus to Theme locations, via the “Theme Locations” meta box on the Dashboard -> Appearance -> Menus screen
- Theme outputs custom menus in appropriate locations within the Theme template, via
wp_nav_menu()
Hopefully this post will help eliminate a few Theme development headaches.
ZaMoose 3:28 pm on March 16, 2012 Permalink |
Huh. Didn’t realize this wasn’t obvious on its face…
Good to know.
Piet 2:40 am on April 7, 2012 Permalink |
If I may, I would like to suggest to properly internationalize these calls, thus:
register_nav_menus( array(
‘primary-nav’ => __( ‘Primary Menu’, ‘textdomain’ ),
‘footer-nav’ => __( ‘Footer Menu’, ‘textdomain’ )
) );
Chip Bennett 3:40 am on April 7, 2012 Permalink |
Oh, certainly. I highly recommend doing so; however, one, at this time, internationalization is not required (only recommended), and two, it’s slightly outside of the scope of the tutorial. But, as a matter of best practice, I agree with you 100%.
Peter 3:35 pm on February 23, 2013 Permalink |
[Mod: Make/Themes is not a general support venue. Please post support questions to the WordPress support forums.]