Theme Review Team

Tagged: best practices Toggle Comment Threads | Keyboard Shortcuts

  • Chip Bennett 3:18 pm on March 16, 2012 Permalink |
    Tags: best practices, custom menus   

    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:

    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:

    1. 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”)
    2. 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:

    wp_nav_menu( array(
        'theme_location' => 'primary-nav'
    ) );

    That way, custom navigation menus will work properly:

    1. Theme registers custom menu Theme locations, via register_nav_menus()
    2. User creates custom menus, via the Dashboard -> Appearance -> Menus screen
    3. User assigns custom menus to Theme locations, via the “Theme Locations” meta box on the Dashboard -> Appearance -> Menus screen
    4. 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 | Log in to Reply

      Huh. Didn’t realize this wasn’t obvious on its face…

      Good to know.

    • Piet 2:40 am on April 7, 2012 Permalink | Log in to Reply

      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 | Log in to Reply

        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 | Log in to Reply

      [Mod: Make/Themes is not a general support venue. Please post support questions to the WordPress support forums.]

    • Hellog. 7:06 am on June 28, 2014 Permalink | Log in to Reply

      What is menu in WordPress

  • Chip Bennett 2:43 pm on July 1, 2011 Permalink
    Tags: , best practices,   

    WordPress 3.2: Fixing the edit_theme_options/manage_options bug 

    Theme Developers:

    Many of you are aware of a minor bug in the Settings API implementation for Themes, in which add_theme_page() is passed the “edit_theme_options” capability, but the settings form submission via options.php requires the “manage_options” capability, resulting in users with the Editor role having access to the settings page, but being unable to submit the settings page form.

    Fortunately, WordPress 3.2 adds a new filter that can be used to resolve this issue: option_page_capability_{option_page}, where {option_page} is the name of the option page, as defined in the fourth parameter passed to add_theme_page().

    To get an idea of how to implement the fix, refer to the patch for the filter, which also includes an implemented fix for TwentyEleven. The key is to ensure that the capability passed to the hook is the same as the capability passed to add_theme_page.

    Here’s one example of how to implement:

    First, create a function to return the “edit_theme_options”:

    function themeslug_get_options_page_cap() {
        return 'edit_theme_options';

    Then, hook the function:

    add_filter( 'option_page_capability_themeslug-options', 'themeslug_get_options_page_cap' );

    Then, ensure consistency with the add_theme_page() call. Notice that I replace the hard-coded string with the previously defined function:

        'Theme Name Options',
        'Theme Name Options',

    If you’re already testing against the 3.2 Release Candidate (and you are, aren’t you?), you should now be able to save Theme settings as a user with the Editor role.

    • Carl 9:44 am on October 27, 2011 Permalink

      The variable {option_page} in the filter option_page_capability_{option_page} should not be the fourth parameter from the add_theme_page call.

      Rather, it must be the same as the intended settings group that is to be modified. Clarification: the first parameter when doing register_setting(‘settings-group’, ‘setting’);

      For many these are set alike but that might not always be the case.

compose new post
next post/next comment
previous post/previous comment
show/hide comments
go to top
go to login
show/hide help
shift + esc