The release of WordPress 3.0 is almost here, so I thought it would be a good idea to start an in-depth discussion on some of the new features. One that I am really looking forward to, and that has been getting a lot of buzz, is the new menu system. Inspired by a similar system created by WooThemes, WP 3.0 allows the user to create multiple menus that can include any category, page or link they choose. I have been testing the latest build (3.0-beta2-14769) and so far, the menu system interface is looking pretty good.

Here are a couple of screen shots to show you what it looks like:

WordPress 3.0's new menu system.

This is what you will see once you have created a menu.

Taking a look behind the scenes of TwentyTen, the new default theme for WP 3.0, gives a little insight as to how it all works and what needs to be in place to make sure that the theme you are using will take advantage of this new feature.

First, you need to include the following in your functions.php file:

add_theme_support( 'nav-menus' );

Make sure it is placed within the PHP tags. That is all you really need to activate the menu system. A link to the Menus admin page will appear in the Appearance panel. If you really want your theme to stand out, you can even register menu locations so that the user can assign menus to specific areas of your theme templates. This is similar to the sidebar functionality.

register_nav_menu('main', 'Main Navigation Menu');

This will register a menu with the ID “main” and the description “Main Navigation Menu”. Including this snippet will make a new panel appear on the Menus admin page (see the second image above). Now users can select which of their menus will appear in that registered location.

Next comes the function to actually display these menus in your theme. This is how TwentyTen uses the function in header.php:

<?php wp_nav_menu( array( 'sort_column' => 'menu_order', 'container_class' => 'menu-header' ) ); ?>

The above code displays the first menu you created, ordered how you have set it, within a div container with the classname “menu-header”.

Here is a list of all the arguments that the function can take (so far):

  • menu – The menu that is desired. Accepts (matching in order) id, slug, name. Defaults to blank.
  • menu_class – CSS class to use for the ul container of the menu list. Defaults to ‘menu’.
  • container – Whether to wrap the ul, and what to wrap it with. Defaults to ‘div’.
  • container_class – the class that is applied to the container. Defaults to blank.
  • fallback_cb – If the menu doesn’t exists, a callback function will fire. Defaults to ‘wp_page_menu’.
  • before – Text before the link text.
  • after – Text after the link text.
  • link_before – Text before the link.
  • link_after – Text after the link.
  • echo – Whether to echo the menu or return it. Defaults to echo.
  • depth – how many levels of the hierarchy are to be included. 0 means all. Defaults to 0.
  • walker – allows a custom walker to be specified.
  • context – the context the menu is used in.
  • theme_location – the location in the theme to be used. Must be registered with register_nav_menu() in order to be selectable by the user.

You need to use the theme_location argument to call a registered menu:

<?php wp_nav_menu( array( 'theme_location' => 'main', 'sort_column' => 'menu_order', 'fallback_cb' => 'display_home' ) ); ?>

I have also added the fallback_cb argument to show how to control the default callback if no menu is created. If you don’t include a callback it will default to wp_page_menu() which will just list your pages. I have assigned a function called display_home() as my callback.

function display_home() {
	echo '<div class="navigation"><ul><li><a href="'.get_bloginfo('url').'">Home</a></li>';
	echo '</ul></div>';

By default, that will display a home link and 5 categories.

There still seem to be a few bugs in the new menu system, but that is to be expected in a beta version. All in all, it is a great addition to WordPress, and theme developers should rejoice that they can now easily offer more control to their users by taking advantage of one of the many core features that will be included in WP 3.0.