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:

  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” metaMeta Meta is a term that refers to the inside workings of a group. For us, this is the team that works on internal WordPress sites like WordCamp Central and Make WordPress. 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:

  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.

#best-practices, #custom-menus

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 APIAPI An API or Application Programming Interface is a software intermediary that allows programs to interact with each other and share data in limited, clearly defined ways. 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:

add_theme_page(
    'Theme Name Options',
    'Theme Name Options',
    themeslug_get_options_page_cap(),
    'themeslug-options',
    'themeslug_callback_function'
);

If you’re already testing against the 3.2 Release CandidateRelease Candidate A beta version of software with the potential to be a final product, which is ready to release unless significant bugs emerge. (and you are, aren’t you?), you should now be able to save Theme settings as a user with the Editor role.

#3-2, #best-practices, #settings-api