WordPress Custom Menu Support for themes

The WordPress Custom Menu feature, introduced in WordPress 3.0, allows for the intuitive creation and maintaining of navigation menus in themes.

At the very least, a standard theme will need a main navigation menu, perhaps in the header and a secondary navigation menu in the footer. To achieve this, we’ll need to register our menus with a function and then call that function on the “front-end”/view e.g. in the header.php template.

Register the menu(s)

We will register two menus: “Main Menu” and “Secondary Menu”. The main menu will appear in our header and the secondary menu will appear in the footer.

First, crack open the functions.php file and include the following:

register_nav_menus(
  array(
    'main_menu' => __( 'Main Menu', 'butter' ),
    'secondary_menu' => __( 'Secondary Menu', 'butter' ),
  )
);

With that simple function, WordPress now knows that we have 2 menu locations. Taking a look at the admin screen — by navigating to Appearance > Menus — we’re now able to create menus and assign them to either of our two menu locations.

At this point though, while we can add, edit and delete our menus—assigning them to either of our two locations—we can’t actually see these menus in the header or footer. Lets rectify that.

Showing the menu(s)

Now that the Menus are registered, we need to tell the theme where to output them. We’d like the Main Menu to appear in our header so, in our header.php file, we include the following code:

<?php if ( has_nav_menu( 'main_menu' ) ) : ?>
  <nav class="main-nav">
    <?php wp_nav_menu( array( 'theme_location' => 'main_menu' ) ); ?>
  </nav>
<?php endif; ?>

Before we output our navigation markup, first we establish that we actually have a menu assigned to the main_menu location and if we do, we wrap it in a

tag and output the wp_nav_menu()With no further arguments included in the wp_nav_menu() array, our nav links will be wrapped in <li> tags which will themselves be collectively wrapped by a [class-less] parent <ul> tag.

If you need more granular control over how the menu is output, you’ll want to use the relevant options/ specify the parameters afforded you by the wp_nav_menu() function. e.g. if you’re using something like the Superfish jQuery plugin to handle drop-down menus that requires your <ul> to have a class of “sf-menu” in order to work properly, you might need to do something like this:

<?php if ( has_nav_menu( 'main_menu' ) ) : ?>
  <?php $defaults = array(
    'theme_location'  => 'main_menu',
    'echo'            => true,
    'items_wrap'      => '<ul id="%1$s" class="sf-menu"> %3$s</ul>',
    'depth'           => 0 );
  wp_nav_menu( $defaults );
  ?>
<?php endif; ?>

First, we check to see if we have a menu called ‘main_menu’ defined and if we do, we insert its contents here otherwise, we fallback to the default wp_list_pages() which we can further customize to display the links as we need. A little overkill but if you need such control then its available to you.

If you’d like even further customization of the menu, see the WordPress codex page on wp_nav_menu() function.

We want the secondary menu to appear in the footer, so in the same way we did in the header, we open up the footer.php and include the following code:

<?php if ( has_nav_menu( 'footer_menu' ) ) : ?>
  <nav class="footer-nav">
    <?php wp_nav_menu( array( 'theme_location' => 'footer_menu' ) ); ?>
  </nav>
<?php endif; ?>

With that in place, we can now create menus and assign them to the two locations.
Creating a third, fourth and fifth location is just as easy as defining it in the functions.php and then showing it in the front-end/view template.