As a theme developer, most of the support questions I get are about configuring menus. If you’re also a theme developer, you have probably run into the same questions I have.
The trouble is that a large majority of users want custom menus and no two menus are the same. There are tons of plugins that fix this problem in their own way. Even some theme developers have integrated menus systems into their themes.
Unfortunately, all of these solutions are different. We haven’t had a standard to go by, at least until now. WordPress 3.0 will introduce a new navigation menu system. Sure, there are some limitations with this system. However, with a set standard, new plugins will likely emerge to fill in the gaps.
In this tutorial, I’ll walk you through the features of the new system and how to build this into your theme if you’re a developer.
What the menu system offers
In WordPress 3.0, you’ll gain another admin screen under your Appearance menu called Menus. In the screenshot below, I’ve highlighted four key elements of the page.
- Theme Locations: If your theme supports nav menus, it’ll register new locations for you to add your custom-created menus.
- Individual Menus: This is where the names of your menus will appear after you’ve created them. (Note that the “+” sign will create a new menu.)
- Add Menu Items: There’ll be several meta boxes containing pages, other post types, categories, other taxonomies, and custom links to your menus.
- Menu Items: Once you’ve added menu items to your menu, they will appear under the menu for your configuration.

Each menu item can has its own configuration section too. Once the item has been added to the menu, you can open it and edit its attributes, which are standard things you might want to change about any menu.
- URL
- Navigation Label
- Title Attribute
- CSS Classes
- Link Relationship (XFN)
- Description
- Link Target (Please note that a kitten dies every time a link is opened in a new window/tab.)

Registering a menu for a theme (theme location)
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:
register_nav_menu(): Registers a single theme location.register_nav_menus(): An array of locations we want to register.
In this example, we’ll register a single menu called Primary Menu from our theme’s functions.php file.
add_action( 'init', 'register_my_menu' );
function register_my_menu() {
register_nav_menu( 'primary-menu', __( 'Primary Menu' ) );
}
primary-menu is the slug we’ll use to identify the menu in code. Primary Menu is the label we’ll use to identify the menu in the admin.
Building off that example, we’ll create multiple menus, which is not much different than registering a single menu.
add_action( 'init', 'register_my_menus' );
function register_my_menus() {
register_nav_menus(
array(
'primary-menu' => __( 'Primary Menu' ),
'secondary-menu' => __( 'Secondary Menu' ),
'tertiary-menu' => __( 'Tertiary Menu' )
)
);
}
Displaying a nav menu
There are two ways to display a nav menu. One is by calling wp_nav_menu() within a theme template file. The other is by using the Navigation Menu widget.
Displaying a menu within a theme template
Most themes will call a menu from their header.php template, but menus can be placed anywhere. The simplest form of calling a nav menu in a theme will look like this:
<?php wp_nav_menu(); ?>
That will load the first menu the user created or fall back on a standard page list if no menus exist.
We want to have a bit more control than that though. Let’s call our menu from the previous section (Primary Menu).
<?php wp_nav_menu( array( 'theme_location' => 'primary-menu' ) ); ?>
You’re allowed even more control. wp_nav_menu() has several parameters you can use when displaying a menu.
theme_location: The menu to call that is associated with the specific theme location.menu: Call a specific menu ID, slug, or name.container: The element that wraps around the list. The default isdivbut can be changed tonavif you’ve moved on to HTML 5.container_class: The CSS class of the container.menu_class: The CSS class given to the unordered list. This defaults tomenu.fallback_cb: A function to call in the event that no menu items have been given. By default,wp_list_pages()will be called.before: Text that is displayed before the link text but within the link.after: Text that is displayed after the link text but within the link.link_before: Text that is displayed before the link.link_after: Text that is displayed after the link.depth: How many levels the menu should display, which is useful for things like drop-down menus. This is set to0(any level) by default.walker: Allows a custom walker PHP class to be defined to create the menu.echo: Whether to display the menu or return it for use in PHP. This defaults totrueand displays the menu.
Displaying a menu using the Navigation Menu widget
By default, WordPress will give you a simple menu widget that will allow you to select any of your custom menus to display. All you need is a widget-ready theme.
Since using widgets is fairly self-explanatory and the new widget is simple, I’m going to use this opportunity for a little shameless self promotion.
For those of you that use my Hybrid theme, you know you have the coolest widgets ever because they give you complete control. Version 0.8 will have a much more advanced Navigation Menu widget that overwrites the WordPress default. Here’s a look at what controls you’ll have.

Styling nav menus
I won’t be covering how to style menus here. That’s a tutorial in and of itself, and there are tons of different ways to style menus. I do have a couple of tips though.
Use the current-menu-item class to style a menu item whose page is currently being viewed. This will allow you to highlight the item so the reader will know which page they’re on. Here’s an example from one of my style.css files:
#primary-menu li.current-menu-item a {
background: #fff url(images/primary-menu-active.png) repeat-x 0 0;
border-top: none;
border-bottom: 2px solid #fff;
}
A solid base to start with is the Superfish jQuery plugin. It allows some subtle, but cool, JavaScript functionality and fixes drop-downs in Internet Explorer 6 without having to resort to hacks.
Here’s a screenshot of a menu I’ve been working on for a new theme.

At this point, you should know everything you need to know about handling menus in WordPress. But, if you continue reading, I have a few more tips that you can use.
Collapsible menus
Let’s suppose you only want a menu to appear when a user has added menu items. This can allow for a variety of layouts. In the screenshot below, I’m using two menus. But, this allows for up to four different layouts.

The trick here is to make sure there’s no fallback called. Let’s return to our original menu (Primary Menu) and the code for it.
<?php wp_nav_menu( array( 'theme_location' => 'primary-menu', 'fallback_cb' => '' ) ); ?>
What I’ve done is simply tell WordPress that I don’t want my menu to fall back to another menu if the user hasn’t given the menu any items.
Checking if a theme location has a menu
Update: Props to Andrew Nacin for adding the has_nav_menu() function after reading this section of the article.
WordPress currently has no conditional tag to check if a menu has been set to a specific theme location. WordPress has a conditional tag called has_nav_menu() to check if a menu has been set to a specific theme location. Let’s suppose we’re 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.
In the screenshot, you can see that neither appear in one scenario and both appear in the other.

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 class="nav-container">
<?php wp_nav_menu( array( 'theme_location' => 'primary-menu' ) ); ?>
<?php get_search_form(); ?>
</div>
} ?>
Allowing more menu containers
The menu system will only allow for <div> and <nav> as a menu container by default. This is likely all you’ll ever need. If for some reason your menu needs to be wrapped by something else, you can allow for new containers.
add_filter( 'wp_nav_menu_container_allowedtags', 'my_menu_allowed_tags' );
function my_menu_allowed_tags( $tags ) {
$tags[] = 'p';
return $tags;
}
Note the the <p> tag isn’t something I’d recommend using to wrap a list. It’s just an example.
Getting a list of all theme locations
If you need to list your theme’s menu locations, use the code below. It will return an array of the locations.
$locations = get_nav_menu_locations();
Creating a menu
Most theme authors shouldn’t have a need to use this function, but there may be cases when it’s needed. In most situations, you should use the theme location feature (register_nav_menu()) rather than this. But, if you need to programmatically create a menu, do so using the wp_create_nav_menu() function.
wp_create_nav_menu( 'Menu Name', array( 'slug' => 'menu-slug' ) );
Checking if a specific menu exists
This is another function not likely needed by theme developers but may come in handy. It allows you to check if a menu exists by ID, name, or slug.
if ( is_nav_menu( 'menu-slug' ) )
/* Do something if the menu exists. */
else
/* Do something if the menu doesn't exist. */
Have fun with your menus
While there are certainly other features I love about WordPress 3.0 more, the new menu system is the feature that’ll help me the most as a theme developer. There’s also a ton of stuff you can do with menus that I couldn’t possibly cover in this tutorial. I’m going to leave that up to your imagination.
I do have one request from any plugin developer that’s up for a challenge: a “menu logic” plugin akin to Alan Trewartha’s awesome Widget Logic plugin.


Another excellent article as always! Thanks Justin
Excellent post. Thanks!
Thanks for the tutorial, it’s very helpful for me!
Hooray can’t wait! This and new post templates will certainly convince me to utilize Wordpress more than Joomla moving forward. The world is changing so fast and so GOOOD for web developers! Matthew Orley, Peninsula, OH
“The world is changing so fast and so GOOOD for web developers!”
I would say: “The WORD is changing so fast and so GOOOD for web developers!” =)
thanks for the write up Justin!
was the new theme Twenty Ten based on similar theme as justinadlock.com is? or justintadlock.com using the twenty ten?
Both my theme here (Kirby Junior) and Twenty Ten were based off Ian Stewart’s Kirby theme. You can read more about this in Introducing Kirby Junior.
Thanks Justin to round-up the menu system. WordPress 3.0 menu system just looks amazing.
Hi Justin,
I like
is_nav_menu_active()and we’re likely going to add it to core. Do you think you could prefix it in your tutorial?Also, get_nav_menu_locations() returns an array in the form of
$locations[$location] => $menu_id, so the the argument should be$locationinstead of$menu.We recognize that the terminology used in function names may be confusing at first, as a theme registers a “nav menu” but really you’re just registering a location. If you have any suggestions, let us know.
Nacin
After bouncing around a few ideas, looks like we’re going to go with
has_nav_menu( $location ). You’ll see it in trunk soon.http://core.trac.wordpress.org/changeset/15091
Awesome. That’ll save me some extra code.
Superb!
Incredible work once again, Justin
Cheers Justin for the thorough review – I also get lots of support requests about creating custom menus, so this new update is going to make things much easier.
Hey Justin, that’s a really detailed article that will help many for sure.
I have a question though. Do you think is possible to show sub-pages only for the current parent page, in the sidebar for example. The sub-pages for the other parents will colapse.
I wrote an article about this method, but it needs an outdated plugin to work and is not tweaked to work for categories.
http://bit.ly/csLd4L
Some insight on this would be appreciated by community as it is very popular in larger websites navigation.
I see that as something outside the scope of nav menus. That’s more of a page-listing function. I definitely consider it plugin material.
Great overview, this will be very helpful!
[...] post online talking about the new menus feature in WordPress 3.0. The post title says it all. Goodbye, headaches. Hello, Menus!. As I have reviewed numerous commercial WordPress themes along with a few free ones, I’ve [...]
Hey Justin, we have sidebars for widgets and we can drag widgets around to rearrange them. What are the areas called that house menus? Simply nav containers? Or Navigational sidebars? Also, is there any similarity between the widget system and how menus work outside of rearranging stuff?
Menus house menu items. This is like sidebars holding widgets.
The biggest similarity I see is the ability to have containers that hold editable items, things that the end user can configure easily. Underneath it all, there’s a big difference. For example, one thing I failed to mention in the post is that the menu system is using the post type API for saving and getting information.
very detailed tutorial. I’ll bookmark it for the future.
thanks Justin
Awesome article Justin. Very, very detailed. I’ve saved it to delicious, shared it via twitter and am going to go over all of this for my themes. I’ve got the basics down for the menus, but this is definitely a step up from where I am at right now with them.
[...] Goodbye, headaches. Hello, menus! [...]
Great writeup! Of course, if you don’t see it coming, let me be the first to offer: Child Menus – It could happen
It seems like the new has_nav_menu still has problems after menus are deleted. On my test blog the function return true although no menus are left. I already filed a ticket at the Trac.
I’ve since closed your ticket with a fix.
[...] headaches. Hello, menus! junho 1st, 2010 | Category: Sem [...]
Great tutorial! This deserves to be bookmarked because it is really helpful in a lot of ways.
[...] Goodbye, headaches. Hello, menus! Here is a great summary of all the new features now available with WordPress 3.0, by Justin Tadlock. (tags: menu wordpress tutorial development) Leave a Reply Click here to cancel reply. [...]
Wonderful article. All information about the new menu system is gathered here. Thanks for sharing.
I’m using 3.0-RC1-15092.
I currently have the follwoing options for menu items:
* URL
* Navigation Label
* Title Attribute
I don’t have the following that are shown in your screenshot:
* CSS Classes
* Link Relationship (XFN)
* Description
* Link Target (Please note that a kitten dies every time a link is opened in a new window/tab.)
CSS Classes would be amazingly useful. Do I have to turn this functionality on or is it not available in my release?
Really helpful post.
they’re hidden in the ‘Screen Options’
Awesome thanks saved me a lot of frustration!
Thanks @kucrut for that tip! been looking all over for that
Just found that I can turn these options on using the Screen Options panel.
Many thanks.
[...] Justin has a nice theme developer orient… Justin has a nice theme developer oriented review of the nav menus. [...]
Thanks Justin for your ongoing work and help.
Your theme framework hybrid is great. I read about your article about the small things that matter and I found tons of those fantastic small details inside your theme.
Everytime I wanted to add new functionality to my own theme I found that you already implemented this in hybrid.
I hope you don’t mind, that I added some code to the new version of my theme. I really liked the way you named your hooks and I thought it is a good decision not to reinvent the wheel again (who wants to have square wheels when he can have round ones).
Your site is already inside my readme.html inside the themes folder and I won’t stop to praise your knowledge.
[...] For More Details on Custom Menus, I suggest reading tutorial by Justin Tadlock. [...]
Just found out that it’s kind of impossible to get a valid markup with the current implementation of wp_nav_menu. If you try to add the same item (eg. page) to more than one menu and display those menus on the same page, you’ll get duplicate IDs.
Is there any workaround for this or could this be considered as a bug?
This has already been addressed in more recent revisions of trunk.
Thank you for the info.
Fantastic post. Thanks for your clear, understandable, tutorial-like information.
It helps a lot in understanding WP-menus.
Thanks for the tutorial, looks like you got all the “How-To´s” for menus in WP3.0 down in one post-excellent!
Not too sure about the Kittens Dying though – personally speaking I prefer it when a link opens in a new tab.
This is indeed a very nice 3.0 feature. I’m working on this at the moment.
Does anyone know how to show only the childs of the active parent, for instance in the sidebar?
[mainmenu] = only level 1 items
[submenu] = only show level 2 of specific level 1 parent
I’ve been looking al over for this, but can’t seem to find it.
It should be possible, since it was possible with ‘wp_list_pages’.
Hope someone can help me out!
I was trying to tinker with the menu system in the wordpress dashboard and was quite thrilled about the output. Simple for the user but a tad bit of hard work for those behind wordpress 3.0. Welcoming the new version of wordpress!! Cheerios!
I really like how you have elaborated on the menu system in the new wordpress.
Excellent post again Justin
This is awesome feature and there’s so many other cool features upcoming so i really hope Wordpress 3.0 os being released soon.
2.9.2 works perfectly fine. Little in the new package has any useful value for us.
Never mind the 100s of bug fixes.
And never mind the new features that streamline development and save countless hours of hacking, or the fact that with this release WordPress can finally be called a CMS out of the box.
And just to dog pile Mr. Steve a little bit further…
Mr. Steve: Please do NOT use the word us when expressing something which is solely your own opinion—especially when it’s an unpopular one. Thanks!
Thanks Justin, I’m a Wordpress newbie but confident that with resources available like this I can only keep improving. I’m particularly interested in the collapsible menus but probably need to focus more on some of the basics first. I’ll be vistiting again!
[...] Character-Illustrationen in Webseiten. Die Kalte Muschi und Produktnamen im Marketing. Menüs in WordPress 3. Die Chrome Developer Tools für den Google-Browser. Sagenhafte fast 10 Millionen Menschen aus [...]
One thing I’d love to be able to do is use the description text you can define for each link and have it rendered inside a span tag within the link. So far no luck at all. Has anyone else succeeded with this?
Also on the version of 3.0 I’m playing with, using using “after” as an array puts text after the entire link, not within it but after the link text.
Thanks Justin, I’m just looking at how best to implement v3 menus so this post is timely and very much appreciated..
How you are getting the #primary-menu CSS ID to show up? All I’ve been able to get working there is class names.
[...] Shared Goodbye, headaches. Hello, menus!. [...]
Hi Justin,
Thanks for this great preview.
I’m wondering if you happen to have seen any examples of the following:
1) A “Walker” class
Its great being able to call one, but if we could see one in action or a tutorial anywhere or on the codex, it would make life alot easier.
2) The ability to call certain levels of a menu separately/specifically
When using “wp_list_pages( $args );” we can specify DEPTH and CHILD OF.
Effectively allowing us to call out a sub menu for display somewhere else.
I’m confident both of these are around somewhere, i’m sorry, i just can’t find any info on them myself. I’d appreciate any information anyone has.
Thanks
Kev
I haven’t seen #1 done yet, but I have seen someone do #2. I just can’t remember the link to it. If I come across it again, I’ll post it here.
[...] Goodbye, Headaches. Hello, Menus! [...]
Fantastic!
Very much looking forward to WordPress 3.0!
[...] Goodbye, headaches. Hello, menus! [...]
[...] BloggingWordPressMicrosoft & WordPress – Good Work MS!Improving The WordPress Support ForumGoodbye, headaches. Hello, menus!A Sample WordPress Theme Options PageTechnologyChina aims to become supercomputer [...]
Not sure if anyone else has had issues with
register_nav_menus()andwp_nav_menu()or not but here’s my rant…In my
functions.phpi have:in my
header.phpi have:And i have the menu set to the appropriate location in the admin dashboard.
My issue is that i do not get the child pages rendered out to the page. The ul/li combo is only for top level pages only. Even if i use
'depth' => 3in thewp_nav_menuarg array it still fails to show children.Any ideas? I’m using 3.0-RC2-15161
Thanks.
Sorry, my previous post should have read…
in my
header.phpi have:[...] Goodbye, headaches. Hello, menus! By Justin Tadlock [...]
[...] in the release candidate stage, and it has a menu system that I am eyeing. I’m excited about this tutorial on the menus system, but I’m still concerned that access to the menus feature is not available to authors (time to [...]
This is fantastic, thanks!
Two questions for anybody generous enough to respond:
1) I want to use accordion menus, where the accordion ‘tabs’ are UI only, and do not link to anything – just click and the menu’s sub-items fold out. Any better way to do this using the menu system than to create blank top-level pages or setting the URL of these menu items to ‘#’?
2) Is there a way to promote the menus option to a top-level item in the admin area? I would like most users to be able to modify the menus (WP working as a CMS in this case), but I do not want them to see all the Appearance options.
Thanks again for a fantastic explainer for this new feature!
Playing with WP 3.0 RC1, I found that when adding a Custom Post Type, I was able to include these on the new Menu, which was very cool. However, since then, I have started the site I was working on with a fresh database (dropped the database tables) and now the Custom Post Type items aren’t available for my new Menu. Everything seems to be the same, so I am sure I have missed some step somewhere. Do you have any insight on this?
Ed
Hi Justin,
I am glad to find your blog.
I believe your blog will help me to improve my blogging skill .
Thank you.
Regard,
Aurel Wong
OMG! I just found this… I knew I wasn’t loosing it!
When you are on the Custom Menu page in the admin, clicking on the Screen Options in the top right corner allow you to include more options with your Custom Menus. Included in this was a checkbox for my new Custom Post Type, along with Posts, Link Targets, CSS classes and descriptions!
NOW THAT IS COOL!
Hi guys, what options are available for the ‘fallback_cb’ =>” function?
I would like my sub-menu to load up if no menu found instead of “wp_page_menu”
Thanks!
You can call any function you want, even custom functions. All it does is “callback” the given function if no menu items are found.
Im looking to do the same thing. Did you get this to work?
Im using a child theme of twenty ten.
[...] comprehensive post by Justin Tadlock, Goodbye, headaches. Hello, menus!, covers the new menu system in WordPress 3.0 in depth. I’ve been using the new menu system on [...]
I’m glad that nav menus are being addressed. A welcome upgrade.
The only think I don’t like about Justin Tadlock is that he doesn’t publish WordPress 3.0 stuff every day of the week. Because when he does, it is well thought out and documented.
Too bad WP is open-source, else Ma.tt ought to hire Justin to do the WP documentation.
I am so glad I found this site months ago. I have been experimenting with a lot of different tricks from justin and they are working great. Thanks J
Don’t be to exited about the new menu system. It is is intentionally incomplete.
For example there is NO filter to filter the generated array of menus items. So, say goodbye to sub-menu and portions of menu display, you won’t be able to do it with a powerful wordpress filter.
Why? Because the wordpress dev team has refused to include ONE more line of code and delayed it to WP 3.1.
You should be thankful that the menus are as advanced as they are in 3.0 and that they even made it into the release.
“As advanced”? I think they are pretty much useless if you cannot even specify to display children of a certain parent page only. I am now forced to create separate menu’s for all the pages I want to show only the children of.
And if it is really only one more line of code I would love to know why this was left out?
Yes, “advanced.” If some people had their way, the menu system wouldn’t be half as feature-filled as it is right now.
You are not “forced” to do anything. That’s a bit of a stretch. You don’t even have to use the menu system at all. A function does exist that will allow you to do that. It’s called
wp_list_pages().No, it’s not one more line of code to add this functionality. It’s one more line to add a filter hook.
Seriously, you guys need to quit complaining and just enjoy life a bit more.
Hello everyone!
Is it possible add link to home page? I use multilanguage plugin and have 2 home pages (“/” and “/ru/”), so I can not add link with static URL… all working very good with pages and categories, but I also need home page link
This has been added since the release of 3.0, but it’s a bit hidden. In the new ‘Menus’ section of WP, click the ‘View All’ tab on the ‘Pages’ box. You should see a checkbox for ‘Home’.
My website is based on wordpress them. I need to add this.Thanks man
I’m wondering if it’s recommended to use this new feature to control a site’s main navigation menu or only for creating smaller, secondary menus. I would imagine it is since nobody wants to use plugins or forwarding if they want to have links to non-pages such as category indexes or other sites. When creating a main navigation menu then, it would be nice then if there were a way to select all pages and add them to a menu such that their order and parent/child structure were preserved.
Other than that, all praise to the WordPress development team for a great new feature!
Is there a way to get the “Menu name” in the same fashion you use title_li= with wp_list_pages() …
Or you will have to use Static name above the menu.
For example a sidebar menu.
Anyone have any idea on how to do a quick export/import of custom menus?
I’m using a framework for multiple sites and it would be nice to do an easy import/export for each site instead of recreating them each time.
Thanks,
~Kyle~
@kyle – Did you find a plan for this? I’m looking for the same functionality. Thanks.
Hey Justin,
thanks for this great article and overview. I tried to use theese functions for my template but I got the issue, that the wordpress won’t save the assigments I create in the admin panel. After choosing which menu is located in the theme and pressing save, everything seems all right, but on the site he simply shows the menu with the lowest ID. After refreshing the apperance/menu site the assigment is lost again. When I use the twentyten theme it works nicely and I can not figure out my misstake. Any suggestions?
Im running WP3.0 RC3 and here is my code:
http://nopaste.php-q.net/296509
thanks and best regards
stephan
[...] Goodbye, headaches. Hello, menus! – Justin Adlock Another awesome tut from Justin Adlock on the new menu system. Again, this is a must read! [...]
[...] Goodbye, headaches. Hello, menus! [...]
Thanks for the post, but one problem that I notice or unless I am doing something wrong is that a custom created link doesn’t get the current-menu-item class if it is the active link.
Anyone else experience this?
I think you have to add a trailing
/after the URL or remove it. One or the other; I can’t remember.This didn’t work for me. =( I’m just trying to get a Home button in the menu with a current-menu-item state. >.<
Can’t wait until I start using this enhancement.
I just upgraded to 3.0 and I do not have Menus in Appearance menu is there anything I need to do to get it there.
[...] WordPress 2.9. Here is a tutorial on how to include them with the rest of the newly thumbed posts.Goodbye, headaches. Hello, menus! – Justin Tadlock – Justin breaks down the details in the new customizable menu system in WordPress 3.0, [...]
[...] Goodbye, headaches. Hello, menus! WordPress 3.0 allows themes to create custom navigation menus. (tags: wordpress css) [...]
Thanks for the article. Have you been able to figure out how to display things like the custom description?
[...] Informative article on nav menus by Justin Tadlock Ramblings [...]
[...] 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!. [...]
Hi Justin,
I am wondering if you know why I am now longer able to add my single posts to the nav bar. Is there a support function I need to add for this now. It works in the beta versions. I have my featured image showing in the navigation via the nav-menu-template.php file. Since posts are no longer supported the functionality stopped working. When I add a custom link it also doesnt work. Is there a quick fix or support function for this, or do you have any ideas for an alternative way to show the featured image from a custom link added in the nav. Thanks very much
Troy
I should have read for a minute longer. Thanks Ed.
Ed Nailor
June 8, 2010 at 2:27 pm | Permalink | Reply
OMG! I just found this… I knew I wasn’t loosing it!
When you are on the Custom Menu page in the admin, clicking on the Screen Options in the top right corner allow you to include more options with your Custom Menus. Included in this was a checkbox for my new Custom Post Type, along with Posts, Link Targets, CSS classes and descriptions!
NOW THAT IS COOL!
I’m also experiencing the problem of the ‘current-menu-item’ class not working. I’m not sure if it’s supported using the new menu system as it’s not in the source code?
Hopefully I’m wrong and someone has a solution…
I had the same thing and it turned out to be a conflicting style from my css. If you can then use FireBug to find out what style is naturally being applied to the unselected navigation items. If its something like this:
#nav ul li a {}
then a simple .current-menu-item {} will not work. You have to target it in the same way as the pre-existing style, like this:
#nav ul li.current-menu-item a {}
Hope this helps.
I think you have the after and link_after (also the before) backwards, but looks like you wrote this in beta, so that could be it. I am using ‘link_after’ = | and my pipe is showing after the text but within the link. >a<Text|>/a< (Hopefully that HTML went through). I use ‘after’ to put my string after and outside the link element.
Also do you know if you can not show the ‘after’ on the last link? I looks silly as I am trying to using my pipe string as a link delimiter.
A nightmare to maintain, spaghetti bowl of desynchronization, is what these new menus are. They statically replicate what we already had dynamic widgets for. In database lingo, they violate third normal form.
Post and page descriptions are computed from the page content AT ADD TIME; if you update a post or page, its description is not updated, so you have to remember to manually edit each menu entry each time you edit something. Adding pages, or changing a page’s Order, or changing a page’s Parent, does not change the menu, you have to manually go replicate all your changes in two places.
Nor can I find any way to write a widget that creates menu items, like my http://wordpress.org/extend/plugins/hierarchical-pages/ , which would solve the above problems by creating menus on the fly, based on your current page location, the N latest posts, or other inputs.
In short, the new menus should have been a widget, that could be inserted anywhere, instead of a whole new structure. What a mess.
They’ll probably do just fine for all the folks that are raving about them, just as long as they avoid the handful of people that are whining.
If you honestly feel this passionate about menus, there’s not a thing in this world that should stop you from either helping to make the system better or creating something else.
I’ve created a user with role set as Editor and he can’t see Appearance->Menus.
I want that he could edit the Menus.
How could I let him see the Appearance->Menus button?
The role would need the
edit_theme_optionscapability for this in WordPress 3.0.Thanks for the article. I think Wordpress 3.0 is one of the greatest things that ever happened to blogosphere, or even to the world! Hey, I’m not exaggerating. It’s really cool.
Hi, could you give us a tip how to make the submenu horizontal instead of the dropdown? Can’t find any code for that anywhere. Is it possible using tme new 3.0 menus?
Thanks in advance
That’s outside the scope of this tutorial. There are thousands of tutorials (I’d guess) available around the Web on this. Just run a search for horizontal menu style. You’ll find plenty of helpful tutorials.
First Justin, thanks for being a leader in website development across the Internet. I’m not sure you hear that enough:)
I’m a little surprised by this first implementation of menus to the Wordpress core, which is long overdue given menu prevalence in website accessibility. And yes, that is a swipe at the Wordpress community.
Several things seem extraordinarily short sighted. First, The wp_nav_menu() call is inconsistent with the existing wp_page_menu() function. Why is that?
Second, why not build in automatic inclusion of sub-pages? That alone is going to cause incredible amounts of administrative time and confusion, etc.
Third, there is no shortcode or other easy, theme independent method to embed the menus in pages and posts. Why not? It would seem this capability is one of the most common needs of end users (witness all the plug-ins), and one of the easiest to implement.
I’m not ranting, just expressing surprise at the current implementation to one of the gurus of Wordpress, who in my view always develops with vision. Thanks man.
You probably wouldn’t be surprised at all if you’ve followed the development of the feature over the last few months. I see a lot of extra features that were added despite this being version 1.0 of the menus. Check out this interview of Jane Wells on WordPress 3.0, which might help explain it a bit.
As a developer, you realize that not everything but the kitchen sink needs to be added from the beginning. There’s a process to it. Your first priority is to get the underlying structure working. From there, you incrementally add new features, trying to perfect the functionality as much as possible. If you try to throw too much in at once, you end up with bugs and delayed released dates. Too many bugs can destroy the platform from a user experience perspective. Release dates shouldn’t be delayed too much — release early and often.
wp_nav_menu()is whatwp_page_menu()should’ve been.wp_page_menuwas essentially a useless wrapper function forwp_list_pages()with a few extra features (though it was easier to use). The two have nothing to do with each other, and I don’t see in what ways they need to be consistent.Automatic inclusion of top-level pages was a last-minute feature that was added. I agree that if they added this, all pages should’ve been auto-included. Of course, this may have taken more development time. I didn’t look too closely at the implementation of this method, so I can’t say.
I’m indifferent to the feature. I wouldn’t want any pages auto-included anyway. I have the menu interface to organize my menus.
I do disagree that this will cause incredible amounts of confusion. Users will learn how the menu system works, and most will understand that they have control from the interface over what’s added. I wouldn’t underestimate WordPress users that much.
After running theme support forums for a few years, I’ve rarely seen a case where menus are needed within a post/page. You’ll likely find that this will be marked as plugin territory. In fact, the next version of my Template Tags Shortcodes plugin will have a shortcode for this if you do need this feature.
[...] Padilla has a great tutorial for how to create menus that have customize labels and images.Justin Tadlock covers how to implement custom menus into your themes and gives some styling tips and [...]
Thanks, I am upgrading my website for 3.0 right now so it helped out a lot!
Keep up the good work!
Hey Justin,
THAT is a great article on Wordpress 3.0 and it’s awesome menu management!
But I’ve got one little question: Has anyone tried to display the “description” attribute? I’m running into heavy problems with it and there is no documentation about it, searched Google up to page 50 but nothing showed up.
Thanks in advance,
Dennis
Menu item descriptions aren’t shown with the basic
wp_nav_menu()function. Right now, you’d have to write a custom function or class to handle its display.Any clues on how to do this exactly? The documentation on wp_nav_menu isn’t too helpful. Do I just model it after http://core.trac.wordpress.org/browser/tags/3.0.1/wp-includes/nav-menu-template.php but include calls to get the description? Seems like they are an empty feature as of now. They say that your theme has to incorporate the descriptions, but there is no indication as to how for a theme builder. Thanks!
Hi Justin,
Absolutely fantastic article as usual.
However, I think it would be worth you pointing out to your readers that if a) a theme is used by other people and if b) some of those people may be on earlier versions of WordPress, then you really need to check if the register_nav_menu function exists before calling it. Otherwise you get a fatal error. It’s a similar story with wp_nav_menu.
I’ve written about this in my Practical Theme Support For WordPress 3.0 Menus post, if people want to see how to do it – or maybe you could update this post to mention it?
Regardless, thanks for an excellent post – this is where I learned how to support menus in the themes I’m working on.
Actually, I purposely left that out. I don’t add backwards compatibility in my themes or plugins for WordPress. I’m a big believer in making sure everyone’s running the latest version of WordPress. I’m just doing my part by making sure folks upgrade if they want to use my themes/plugins. It just makes sense for me to carry that philosophy over into my tutorials.
You know what 90% (guestimate) of my users have in common?
Now, I just need to get around to following my own advice and update my blog.
Fair enough – I know where you’re coming from – although fatal errors are pretty bad for the users and to be avoided if possible. Personally, I’d add a couple of lines of code to stop that from happening. I wouldn’t go out of my way to support versions that are too old, but I think at this stage it’s realistic to expect some users are still going to be on 2.9.2.
I guess as long as you’re clear that your themes / plugins require 3.0 there’s no problem – but in my experience people don’t always read those very clear requirements.
Where one person sees something as bad, another sees it as a learning experience. I try my best to keep users updated and informed. I’d honestly rather have them get a fatal error at least once so that they will learn how to avoid it in the future. Obviously, there are other ways of learning, but I’ve yet to find a better substitute for experience.
Aside from my personal philosophy on the issue, I’d still not add it to a tutorial. If that were the case, I’d have to spend time writing about the same thing in every tutorial I write.
I assume two types of people are reading this tutorial though: 1) WordPress end user and 2) WordPress developer. Users can clearly see that this is a WordPress 3.0 feature, so there’d be no need for backwards-compatibility checks since they’d be using 3.0 at the time of implementation. Developers shouldn’t need to be told this in every tutorial they read about a new function.
[...] more so I could have found it when I was working on this recently – but there's some additional reading here on how to set all this up (it's a lot more in depth than I got into – I guess my version is the "Cliff [...]
[...] proud of this addition. There’s a great guide to utilising the Wordpress 3 Custom Menus on Justin Tadlock’s blog. Check it [...]
[...] actually found that it wasn’t too difficult to add custom menu support to my existing themes using this tutorial. All you have to do is add a few lines of code to the theme’s functions.php file in order to [...]
Just lost quite a bit of time figuring out a little issue I just came across, and thought this info might come in handy for someone. I have been following and developing with all of the new 3.0 features since they began and have yet to see it mentioned or documented anywhere.
(note: Justin, it would be great if this info were added to the post where you go over adding custom post types with pre_get_posts )
If you are using the new nav_menu features, even straight out of the box from twenty ten, and you also have custom post types that you would like to add to the $query to show up conditionally i.e. ( if is_author ), and you run the pre_get_posts function to add them, if you do not include nav_menu_item as one of the post types to return, your navigation menu will no longer show up on, for example in this instance, your authors.php remplate.
It is important to be aware that nav_menu_item is now a registered core/builtin post type.
Hope that saves someone else some time lost
thanks, the @Angelia ‘nav_menu_item’ was what i needed. Just now to get rid of the Warning: Illegal offset type in isset or empty in /home/public_html/wp/wp-includes/post.php on line 736
Thanks for this! I love tinkering around with the code of Wordpress; totally geeky, but I feel like I get to let out a little bit of creativity on each of my blogs
Hooray!!! This is great news. I will look more into it and probably upgrade.
Has anyone figured how to insert a separator, like ” | “, btwn links
wp_nav_menu? Adding parameter'after' => ' | 'results in a trailing pipe:Link1 | Link2 | Link3 |
I could grab menu html before the
echo()and do atrim(), but wondering if there’s a mo’ better way?(I now see Darrell asked this above, but no harm re-querying.)
You could always do this with classes if there is no current support for this. You could either use ‘li’ separators or ‘background-image’ and position to get the look and feel you need.
Forgot to mention you could use a ‘last-child’ / ‘first-child’ class to avoid displaying the unwanted separator at the beginning or end of your menu. (only as a last resort! please do post up an answer to this if you find one)
You could do this with CSS. Just run a Web search on styling navigation menus. There’s tons of information out there on the subject.
this does a good job of approximating a | separator:
thanks, all, for the suggestion.
How can I use superfish with nav_menu ?
It’s no different than any other menu. Just follow the setup instructions from the Superfish site.
This interface needs dramatic improvement… it’s really a nightmare to create menus on WP installations that have large, complex page structures. The search function doesn’t appear to work… it appears to be searching page bodies, not titles.
I hear Rome wasn’t built in a day either.
[...] pages, categories, etc, can all be dragged and dropped around to create a menu hierarchy. And it is incredibly easy to code in to a [...]
[...] Goodbye. headaches. Hello, menus! [...]
I’m making changes to my business’s blog and will definitely pass this on to my developer. I know he had some questions in this area and hopefully this will take care of his confusion. Thanks.
hi justin!!
in the ‘theme_location’ iside php arraya we must change to the same name that exists in the ‘tab’ theme location, or this param id fix, i must remain this text ‘theme_location’. im testing but i have not sucess.
thanks!
Huh?
Any idea how to get menu item title attribute to be displayed as link_after ? or any other posibilities to have individual link_after text for each menu item ?
Using the
titleattribute in that way would be incorrect, but I hear what you’re saying. You probably couldn’t easily do with the basewp_nav_menu()function, but I’m sure it’s possible with a custom menu function using some of the other parts of the API. Nevertheless, that’s another tutorial for another day.Thanks for this Justin,
Could you expand on how you have added the sub menu indicators in your example menus? there isn’t a class or markup added to li’s that contain a child list to style, how did you do that? for example, superfish requires a sf-sub-indicator class i think.
Thanks
Will
I used Superfish. The Superfish site has a CSS file that you can download, which shows how to do this.
Wordpress 3.0 has been great. They really set a standard for keeping updated.
Thank you! This was what I needed to start implementing the new menus in my custom theme.
I’m trying to create WordPress 3 menu programmatically.
Here is the code that I wrote to make it:
and now I want to assign the $menu_id to “Primary” navigation location. I already looked into the source code in wp-includes/nav-menu.php and wp-includes/nav-menu-template.php and so far I haven’t found a function that achieves that goal.
So, do you know how to assign a menu id to “primary” navigation location programmatically in WordPress 3.0?
Finally I found the answer for my question above. I already wrote the answer here as the answer to my own question in WordPress forum: http://wordpress.org/support/topic/419242?replies=2.
Awesome. I had someone else ask me about this today and haven’t had the time to look into it. Thanks for following up.
Great information.
I love the idea of this but am unsure how much control of the menu you can do with it. I tried it on a project I am working on where if you are on a ‘book’ single post I need the menu to highlight book and if on ‘blog’ post highlight blog. I cannot see how I would attain this using the menu.
In 2.9 I would use wp_list_categories and use a function for the highlighting like this: http://paste-it.net/public/o76011d/
Is this doable with 3.0 menus?
Thanks,
Karl
Thanks for your good works.
Anyone know how ‘description’ works? I cant print with custom menu…
in “custom url” the menu dont get the “current-menu” class, how in your example – the “home” is show as active?
(sorry og my english)
oops… you are right, in custom url – the wp tray to find if it is the currnt page- but in my case it have a little bug! the function tray to compare the “custom url” with
$_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']and in my case I dont gave the slash in my home page custom url – and the result is that it not get the
current-menu-itemclass.my wp-home -url:
localhost/wordpressmy custom menu url:
localhost/wordpressI get open a ticket in wp-trac…
(sorry of my english)
[...] http://justintadlock.com/archives/2010/06/01/goodbye-headaches-hello-menus [...]
it sloved : http://core.trac.wordpress.org/ticket/14208
hey , justin pretty neat article there , but i kind of am facing a altogether new issue , i want to remove the container itself
i found something on the wordpress codex
Removing the Navigation Container
but cannot seem to figure out how to use it
Hi, I only want to ask why the new menu system supports only 16 items? Tanks in advance.
I am having trouble just showing children of a section in a sidebar. What can I do just to show the dropdown children in the sidebar? Been looking everywhere, can you help?
@Barrett Golding
your li:first-child tidbit is a GODSEND. thanks man.
cheers!
Hi Matt,
Just so you know the :first-child selector is a CSS2.1 pseudo-class, and isn’t offically supported in all the browsers. Be careful when relying on them for fancy or vital formatting
This is a great tutorial. It was very helpful. I went nuts adding menus to a theme I’m playing with – what fun!
One question: do you or anyone know why the menus option might not display on a WordPress 3 installation? The owner installed WP 3.0 and the 3.0 themes now work, but he can’t add menus as there is no “menu” option under appearances. Back to Google I go.
Great post, very easy to add menu support to my custom theme. Thank you.
I hadn’t heard of this before thanks , this is quite useful.
[...] an excellent description of the new navigation template tag, see Goodbye, headaches, Hello, menus! from Justin [...]
With the introduction of Menus in WP 3.0, this has superseded the old codex wp_list_pages(). However, this has brought about a coding problem for the navigation menu when dealing with Private pages.
Whenever there are Private pages present, the Menus (in Admin >> Appearance) doesn’t list them. This requires a search first before they can be added onto the Menu. Unfortunately, when one’s logged out, the Private pages are still shown on the navigation menu and not hidden.
I believe it’s something to do with the WP 3.0 codex wp_nav_menu().
Any ideas to fix this?
Thanks for putting this information down, it’s helped me to integrate menu support properly.
I’ve seen early screenshoots where you can add “Posts” to menu. But categories and pages are available now.
Is there any way I can add specific “posts” to menu ? Also Specific page of custom post type? I think there is code for it already in core, but not sure.
It would be nice if there was a function akin to “get_menu_items” that returns an array of objects for each menu nav item, similar to get_posts or get_pages. This would allow developers to be able to directly access the data which has a plethora of advantages, including more control over display or working with other applications. In the meantime I’ll probably just query the database.
Also a great Post… Wordpress 3 is much better than the vers. before.
Extreme SEO Google Internet Marketing.
I don’t know why wordpress does not add the menu function by default to the main admin menu? we must register it to the theme for it
[...] Tadlock has a thorough post on how to integrate this functionality in all sorts of creative ways. But it may be too confusing [...]
Hey all ,
How do we go about adding the “home” link via Custom Link from the new WP3 menu builder but also have it assigned a “current_menu_item” class when we are viewing the index page. What is the best way to append a “home” link to these new menus? Thank you.
I found that it worked when you created a custom link WITH the trailing slash. It wouldn’t work without it, however if you do include the trailing slash (http://theblawblog.com/ in my case) it works.
ONE Word : I LOVE YOU
___________
(Yeah it’s 3)
Is it a bug or a feature that the following doesn’t work without a menu created?
I want to include this function in a basic html5 framework theme, but if no custom menus are created yet and it falls back to a standard page list it doesn’t change anything…. it’s still an unordered list wrapped in a div with class=”menu”.
'container' => 'false'doesn’t remove the wrapper div as expected either.Ok, I see now that it is a feature.
It falls back to
wp_page_menu()So you can either filter that function or create your own function and change
Yeah, I’d consider it a feature. It allows you to define a custom menu without having to worry about extra HTML added by the function.
[...] [...]
I’ve been searching for an example of the echo option. I want to use the new menu structure (I have it in place), however I am using wp-ecommerce, which I can’t seem to get the product categories added to the new 3.0 structure. I want to return the menu, then test for a certain page, so I can output my own menu in php.
Can someone either help me insert the product categories (not manually) into the main menu, or understand how the menu is returned when echo is false.
(I’m using latest version of wp-ecommerce and wp 3.0)
Thanks so much, Robin
Never mind, being a dummy. It’s the same as wp_list_pages() echo it returns a string.
Hi, i’m a begginer, so can somebody explain how to make primery menu? i should edit functions.php file. and this file is at host server? ishould paste
to the end of file functions.php?
Put it between the opening
<?phpand closing?>tags in your functions file.Very informational post Justin. I’m also really glad to see the custom Menus in WordPress 3.0. I have finally had an opportunity to experiment a bit, and I have been very pleased. However, I have come across my first problem. I want to apply a class to the actual link anchor, but the class I specify in the “CSS Classes” field is applied to the list element. I am currently trying to work around this, but I was just curious, what is your take on this?
Ouch.. *informative
There’s no need to add the class to the link element. You can give the class to the list item and style the link.
For example:
[...] you updating your theme in order for it to work with these menu management.WordPress 3.0 Menu UpdateGoodbye, headaches. Hello, menus!Making Themes Ready for WordPress 3.0 MenusAdding Backwards Compatible WordPress Menus To Your [...]
By changing line 163 in “wp-includes/nav-menu-template.php” from:
to
the args list is passed along to wp_get_nav_menu_items (which already has a filter). it was pretty simple to use that filter, check for a “child_of” arg (which is now passed through from our “wp_nav_menu” call) and call a custom function based on the wp_list_pages filtering:
That’s worked great to allow retrieving a sub-nav section of my menu while only changing one line of the WP core.
I’m sure there is a better way but this was the simplest for my WP-noob brain and didn’t require a bunch of hacking.
Great article, as usual. However the term Theme Location I think needs some further explanation. For example why there appeared a need in such a thing at all. Why not just define individual menus directly?
Fewer hassles. Theme authors can just register a location and call it. They don’t need to worry about creating a menu. This also allows users to create menus however they want and assign them to whatever locations are available, even switching them out if they want.
Hi Justin,
Do you know how to differentiate a ‘li’ which has children items and a ‘li’ without ones?
For example, here is my list:
-Home
-Products
– Product #1
– Product #2
- About
What I want is the ‘Products’ will have an arrow, or styled differently since it contain children while other ‘li’s don’t.
Thanks for great article btw.
Duy
What advice could you offer for an attempt to style a menu with children as a dynamic submenu (following the approach described at http://www.triah.com/2010/01/09/color-menu-with-dynamic-submenu-using-css/) rather than nested drop-downs?
Seems to me that the catch comes in wrapping parent links in one div and all child-links in another. Is there anyway to do this using one menu as opposed to creating a menu for parents and each child?
I can’t for the life of me get posts to list under the new nav function. Can anyone give me a hand?
Just like the navigation on THIS site… Writing -> Fiction -> *list of posts*. This is exactly what I’m looking to do.
Not sure where you find the time to compose such detailed posts, but thank you heaps. I’m a WordPress newbie and the CMS and how to use it does overwhelm me sometimes. Your tuts make WordPress life a little easier…:)
A great article that helped me understand applying the new wp_nav_menu.
I have one question that has me stumped after a far bit of research.
I am trying to extract the menu name a user may create and then attach to a menu region, I realise that the menu assigned to a particular region is not apparently the business of nav-menu.php ?
I can access two arrays $_wp_registered_nav_menus() , and wp_get_nav_menus() for all the regions and menu objects yet I can’t find a means to correlate the two sets.
For example I want to create a label from the menu name a user creates .
I can’t know in advance the menu name or to what region the user assigns a given menu.
I need to be able to do something along the lines of ‘If this region give me the menu parts assigned to just this region’.
Not sure if that makes a whole lot of sense but any thoughts or pointers in the right direction would be hugely helpful.
‘depth’ is not working for wp_nav_menu?
I have a parent category with a handful of subcategories, and I thought I will be getting this in a nested unordered lists that would allow me to style a dropdown menu:
Parent menu
-Sub menu 1
- Sub menu 2
Instead I am getting this:
Parent menu
Sub menu 1
Sub menu 2
My post in WordPress forum
http://wordpress.org/support/topic/wp_nav_menu-not-displaying-subcategories
I need help with something that I haven’t found an answer to.
I have one business with three storefronts. Each storefront has a website. I have not yet used MU, but am in the process of figuring how to set that up now. (Thanks for your help!) Related to that:
I am not blogging on these three sites, but will within a few months. For now, my issue relates to Pages on my WP website.
The three websites (one for ea storefront) will be identical. All three storefronts will share some pages. Each store, however, will have a couple of unique pages. I want to be able to update the shared pages and have all three websites update. HOWEVER, I want each store manager to be able to update their own unique pages. I don’t want managers to have access to another store’s pages. I don’t want the managers having access to the pages that span all three stores.
Can this be done? If so, how?
Thanks.
Justin,
Great article, and thanks for being so good about responding to peoples’ questions.
I’m currently scratching my head over the Classes settings. A client wants me to create a wordpress theme and gave me an xhtml template and CSS2 stylesheet with the following navigation styles defined.
Now, these are CSS ids, so I converted them to classes by removing the # and replacing it with a .
But, when I put “nav2 navHome” in the Classes setting, the menu items don’t style correctly. The rendered source shows up like this: Home but the design falls apart and is just linked text without the nav1.jpg button graphic.
What am I doing wrong?
Thanks.
Oops. just realized the code i pasted in my comment for the rendered source actually got rendered in the browser as a link.
Here it is with a the pre tag wrap, hoping that will display the code. Otherwise, just view source, I guess. Home News
Hi. my menu doesn’t appear in the Appearance -> Menus panel.
I’ve tried with the default code from http://codex.wordpress.org/Navigation_Menus, i’ve tried my code, nothing works.
The menu still doesn’t appear in the Appearance -> Menus panel.
If someone knows what’s the problem, please share.
Thanks.
I figured out why it’s not styling. The classes are for the anchor tag but the menu system applies the class name to the list, not the anchor. Any way around this or will I need to revamp the CSS and template link code to resemble a list?
Great article! Thank you!
Can you also tell us how to access and display “description”? I’m trying to find such function but I can’t get it anywhere.
If you could help those seeking for such function (I noticed a few people asking for that on this page) that would be awesome!