Practical Theme Support For WordPress 3.0 Menus
June 21st, 2010 by Stephen Cronin (Please wait) [Shortlink]I’ve read quite a few articles on theme support for the new Menu functionality introduced in WordPress 3.0. However, these have all been theoretical rather than practical. I wanted a real life, working example, including support for users on older versions of WordPress. In the end, I wrote it myself.
Scope
I’m not going to delve into all the different options you can use when adding support for menus. There are enough articles out there that cover this in depth: I highly recommend you read Justin Tadlock’s excellent Goodbye, headaches. Hello, menus!.
Instead, I’m going to focus on the things missing from most articles, such as adding support for users on older versions and including support for static pages in the fallback menu. If you write themes that are used by other people, you need to include these.
Functions.php
First, this is the code to add to the functions.php file. I’ll explain it below.
// add menu support and fallback menu if menu doesn't exist
add_action('init', 'sjc_register_menu');
function sjc_register_menu() {
if (function_exists('register_nav_menu')) {
register_nav_menu('sjc-main-menu', __('Main Menu'));
}
}
function sjc_default_menu() {
echo '<ul>';
if ('page' != get_option('show_on_front')) {
echo '<li><a href="'. get_option('home') . '/">Home</a></li>';
}
wp_list_pages('title_li=');
echo '</ul>';
}
Check If register_nav_menu Exists Before Calling It
On line 2, we add an action to call a function (from line 3 to 7). The purpose of this function is to register the menu via the register_nav_menu function.
Most tutorials out there focus on how to use register_nav_menu (line 5). Fair enough, it’s new and we’re all interested in how to use it. However, I want you to notice line 4:
if (function_exists('register_nav_menu'))
Surprisingly, most tutorials leave this out. No problem if your theme will only ever run on WordPress 3.0. However, if you have users on an older version of WordPress, your theme will crash and burn if you leave this out. Visitors will be greeted with the following error:
Fatal error: Call to undefined function register_nav_menu() ...
Not cool.
The Fall Back Menu Catering For Static Pages
Lines 8 to 15 contain a function that provides a fall back menu that is used if the user has not added a menu via the new interface. The code for the fall back menu is pretty standard stuff. I’m sure someone will point out that I could use wp_nav_menu, but we’ll call the fall back menu directly for older versions of WordPress (see below) and wp_nav_menu only exists in 3.0 and above.
It’s worth noting the IF statement on line 10, wrapping the Home link. This says to only create the Home link IF the site is NOT using a static home page. If it is, then the Home link will not be created. Why? Without this, the Home page option will appear twice in the menu (if users have a static home page).
There are other ways of dealing with this, but my way seems simplest to me.
Header.php
Moving on to header.php, we add the following code where we want the menu to appear:
<div id="nav">
<?php
if (function_exists('wp_nav_menu')) {
wp_nav_menu(array('theme_location' => 'sjc-main-menu', 'fallback_cb' => 'sjc_default_menu'));
}
else {
sjc_default_menu();
}
?>
</div>
Call The Fallback Menu Function Directly For Pre WordPress 3.0
The menu is called via the wp_nav_menu function (see line 4 above). This function is what the other articles all focus on. Once again, fair enough, this is a new function that can give us access to the cool new menus. But note the IF statement in line 3:
if (function_exists('wp_nav_menu'))
Leave this out and anyone using your theme on versions of WordPress older than 3.0 is going to be serving the following up to their visitors:
Fatal error: Call to undefined function wp_nav_menu()
Checking that the wp_nav_menu exists is obviously essential, unless you are certain that your theme will only ever run on WordPress 3.0 or above.
But what do we do if wp_nav_menu doesn’t exist (ie the user is on an older version of WordPress)? Should we serve up the original code that we originally used to create the menu pre WordPress 3.0?
Well, we’ve already moved our old code into the fall back menu function. There’s nothing to stop us from calling the fall back menu function directly (line 7) assuming it doesn’t use wp_nav_menu. Simple! And good reuse of code.
Final Thoughts
WordPress Theme developers, what have you done to ensure menu support for your users on older versions of WordPress? Is your approach different from mine? Can you see a better way of doing this?
I’d love to hear from you in the comments.
Tags: menus, theme development, WordPress, WordPress 3.0

