The new Worpdress 3.0 feature that adds custom menu’s is a great add-on to an already amazing piece of software. Previously, if you wanted specific items to appear in a specific order, you had to add plugins, edit theme files, update exclude lists and basically jump through a bunch of hoops.
No more. Say hello to my little custom menu. Thanks to all the WordPress community developers. You guys really rock.
Unfortunately, if you purchased or installed your theme prior to WordPress 3.0, your theme might not be *custom menu ready*. You have two choices. Go buy/get a new theme that is custom menu ready, or retro-fit your existing theme.
I don’t know about you, but I have dozens and dozens of hours over the last couple of years invested in custom tweaks and feature additions I don’t want to lose. I choose to retro-fit my theme.
Before I jump into telling you HOW to retro-fit your theme to use this cool new feature, perhaps we should talk about what the cool new feature is. And to understand what the WordPress community has gifted us with, we first need to explain what we had. Pages. Posts. That’s it. And most themes would display one navigation menu for pages, and another for categories of posts (if you were lucky).
If you wanted to have a single page appear in the navigation bar were the posts were displayed, you had to hack the theme. If you wanted to add a menu item to the top menu bar that pointed to another of your sites, you had to hack your theme. Remove 3 pages that you didn’t want displayed to everyone and their dog, hack the theme. Get the idea?
With the new WordPress Navigation Menu system, you now have complete control over your menus. Want three categories, two pages and an external link on your top menu? Just drag and drop exactly those items and save the menu. Done.
Want to show a page within a list of category items on your bottom menu? Drag and drop into the order you want and save. Done.
Get the idea? Forget hacking the theme for something that should be (and now is) easy.
In WordPress 3.0, you’ll have a new screen in your Dashboard area under the Appearance menu. It’s called Menus. (Dashboard | Appearance | Menus) In the screen capture below, I have outlined the four areas you will have more control.
If your theme was created prior to WordPress 3.0, check for an upgrade. If there isn’t one, you will have to hack your theme one last time to retro-fit it for the custom menus. Grab your editor and let’s go through that.
There are two methods to add a menu. Add a single navigation menu, and add multiple navigation menus. To associate specific menus with locations within our themes, we need to register these locations. Otherwise, we won’t know which menu goes where. There are two functions we can use for this:
Registering a single menu for a theme (theme location)
In this example, we’ll register a single menu called Primary Menu from our theme’s functions.php file. (To edit this file, visit Dashboard | Appearance | Editor and then select the functions.php file)
add_action( 'init', 'register_my_menu' );
function register_my_menu() {
register_nav_menu( 'primary-menu', __( 'Primary Menu' ) );
}
In this example, primary-menu is the *slug* we will use to identify the menu in the theme files (in a future step). We could have called this anything. And Primary Menu will be the label we use to identify the menu in the admin area. Again, name this whatever makes sense to you. Once this functions.php file is saved, WordPress now knows you intend to use a navigation menu that is customizable.
If you are planning to use multiple navigation menus, (and why wouldn’t you since they are so easy?), then you need to use this instead. This will allow you to create an array (A fancy way of saying a *set* of something that are alike) that holds the menu slugs and names.
function register_my_menus() {
register_nav_menus(
array(
'primary-menu' => __( 'Primary Menu' ),
'secondary-menu' => __( 'Secondary Menu' ),
'sidebar-menu' => __( 'Sidebar Menu' )
)
);
}
This completes the setup for the process. Basically, what we have done is “register” the menus with the theme so WordPress knows we are going to allow it. Pretty simple so far, right?
Now, we have to update the theme so it will know where to display these fancy new menus. In your current theme, you probably have something like <?php wp_list_pages(“depth=1&exclude=61&title_li=”); ?> where the theme is to display your pages and <?php wp_list_categories(‘sort_column=name&title_li=’); ?> where your theme displays your categories. (Please note, yours might be different depending on the options you added.)
What we are going to do, is just replace those two WordPress code snippets with one that will display the menu(s) we registered.
By the way, most of this is in the header.php file as mentioned above, however, it is possible there are other locations in your theme that display menus.
The easiest and most simple method for calling the new navigation menu is…
<?php wp_nav_menu(); ?>
That will load the first menu created or force WordPress to fall back on the standard “page list” if no menus exist. However, we can have a bit more control over that by passing in information with parameters. For example, let’s specifically call our secondary menu (created earlier).
<?php wp_nav_menu( array( 'theme_location' => 'secondary-menu' )); ?>
And if this were enclosed in a div tag with styling rules assigned, we would be done at this point.
Some of the additional parameters that allow even more control are:
By default, WordPress will give you a simple menu widget (once you have registered at least one menu) that will allow you to select any of your custom menus to display. All you need is a widget-ready theme.
Visit Dashboard | Appearance | Widgets and locate the new Custom Menu widget. You will have two settings you can adjust. The first is title. What do you want to title your new widget? The second is a drop down that will let you select the menu (from the array you created earlier) that you want.
Easy peasy.
Please note that you can stop right here if you want. In fact, on two of my blogs, I did only the minimum. I inserted the registration to the functions.php file and inserted two calls to the wp_nav_menu() function… one for the primary and one of the secondary. However, if you want to go a little deeper, then keep reading.
WordPress has a conditional tag called has_nav_menu() to check if a menu has been set to a specific theme location. In other words, suppose we are creating a container with a menu and a search form. But, if no menu is set for the theme location, we don’t want either to appear.
When you call your menu by theme location, you can first check to see if a menu is associated with the location. Note that we’re checking the theme location slug and not a menu name or ID.
<?php if ( has_nav_menu( 'primary-menu' ) ) { ?>
<div>
<?php wp_nav_menu( array( 'theme_location' => 'primary-menu' ) ); ?>
<?php get_search_form(); ?>
</div>
} ?>
When developing themes, it is sometimes handy to be able to test for a condition, such as If a specific menu is present. You can check by ID, name or slug in your PHP code like this.
if ( is_nav_menu( 'menu-slug' ) )
/* Do something if the menu exists. */
else
/* Do something if the menu doesn't exist. */
While this isn’t meant to be a be-all-end-all tutorial, you should be able to retro-fit your theme with a basic version of the menu system, and insert a new menu within the dashboard. Just remember, drag and drop into the correct order. And if you want to layer the items under one another, drag a little to the right (or left) of the position. The dashed line will show where the new item will appear in the menu hierarchy.
(Please note, if the drag and drop stuff doesn’t want to work for you, you have a plugin that is conflicting. Just disable all plugins, drag and drop to your hearts content, then re-enable the plugins again.)