Curated by Carsonified

Learn with Treehouse

Accessibility, CSS3, Design, Django, HTML & CSS, HTML5, JavaScript, jQuery, NoSQL, PHP, Responsive Web Design, Ruby, Ruby on Rails, Tools, UX, Version Control, WordPress, iOS and more

Article 55

Getting Started with WordPress Custom Menus

By

15 July 2010 | Category: Uncategorized

Perhaps one of the biggest holes in WordPress prior to version 3 was the lack of custom menu support. Menus often had to be hand coded into header.php and, whilst they could be 'smart', it often let the client needing a PHP savvy developer to make alterations to the setup.

That was then. Now, at (long) last, we are able to give some of this control back to the client. Or, if you're using WordPress for your own site, you're able to take control of your menu system with a wonderful new drag-and-drop GUI rather than diving into the code.

New Menu System

The menu system is based on WooNavigation, a custom menu system used by the ubiquitous WooThemes in the latest versions of their custom framework. Although much of the code was rewritten for WordPress 3, the similarities are still clear.

Adii Pienaar from WooThemes recently told me:

“The new menu system that WooThemes contributed is firstly long overdue and is a massive benefit to every single WordPress user. In essence, this is such a basic feature of any CMS, but due to it being a benefit to all WP users, I think this is a significant new addition.”

Chris Coyier from CSS Tricks agrees:

“Personally I think this is a big step forward because, together with Custom Post Types, it is migrating WordPress towards a fully fledged CMS. The more power we can give the end user, the easier it is for developers and designers with an understanding of PHP to use WordPress as a content management solution.”

So, without further ado, let’s take a look at how it all works. Grab yourself a WordPress 3 install with a bunch of pages and a refreshing beverage. It’s thirsty work.

Activating a Custom Menu

If you’re using WordPress 3 with the (brand new) default Theme TwentyTen installed this next bit won’t apply, because it’s already set up to use custom menus, so let’s assume you’re working with an older theme or perhaps even building your own. When you log into WordPress, go to Appearance > Menus.

If your current theme doesn’t support custom menus you’ll see this error message:

This means we need to head over to functions.php and get our hands a little dirty with some code. Open up functions.php and add in the following code:

add_action('init', 'register_custom_menu');
 
function register_custom_menu() {
register_nav_menu('custom_menu', __('Custom Menu'));
}

register_nav_menu has two parameters here, the first is the slug we’ll use in our code and the second is the name our menu will have in the WordPress admin area.

Now before we head back over to the menu screen, let’s stay in the source code and tell WordPress wear to put this menu. The most likely place will be in header.php, but of course there is no reason you can’t put a menu anywhere on your page. To keep things simple for our first menu let’s open header.php and, at whatever point makes sense in your theme, add the following line:

<?php wp_nav_menu(array('menu' => 'custom_menu')); ?>

With just the default ‘About’ page in our theme, if we look at our site we’ll see the following in the source code:

<div>
<ul>
<li><a href="the-link-in-here" title="About">About</a></li>
</ul>
</div>

And that’s all there is to it! Of course, we can add in a bunch of options into that array. You can check out the details over at the WordPress codex and here are a few of the more important ones explained:

  • menu – which menu to call. In our example we only have one but you can set up as many menus as you like
  • container – what element is wrapped around the menu. The default is a standard <div> but if you’re playing with the new kids over at HTML5 you could always change this to <nav>
  • container_class – the css class given to this container, helpful for custom styling
  • menu_class – the css class given to the <ul> that is rendered. The default is ‘menu’, and again this is helpful for custom styling.
  • depth – How many levels should the menu display. The default is 0′ which means all levels, but you can set this to perhaps 1′ or 2′ to limit how far a drop-down menu will render. Handy stuff!

That’s probably enough for our purposes, but it’s definitely worth checking out the WordPress codex because there are many options you can set, like adding text before and after menu items and links.

Using the GUI

So let’s get cracking with the user interface, where much of the magic happens.

The first thing we need to do is create our first menu (remember, we can have multiple menus) so I’ll imaginatively create one called ‘Our First Menu’. Type that in to the Menu Name field and hit the Create Menu Button.

Did you spot the check-box ‘Automatically add new top-level pages’? Well, do you?

Normally I don’t, because I figure if we’re going to the trouble of making a custom menu we probably don’t want it doing anything automatically. After all, we want complete control over our menu, so I don’t want WordPress dropping in a new page every time we create one. Maybe you do, and that’s okay with me too :)

Excellent! Our first menu is empty but we’re well on our way. Over on the left we’re told that our theme currently only supports one menu so we best make sure we’re using ‘Our First Menu’. Select it in the drop-down, and click Save.

Adding Pages to our Menu

So we’ve created a place in our theme for the menu, and now we’ve created the menu itself. Trouble is, there’s probably nothing in it. WordPress gives us three easy ways to add content to the menu, and the great news is that it doesn’t have to be content that sits in the WordPress site. For example, the first box on the left you’ll see is for Custom Links.

You could perhaps link to your twitter account like I have in the screen-shot above, and just click ‘Add to Menu’. It might be your portfolio, which you’ve hosted elsewhere, or links to live client sites. It might even be links to your favourite news sites. Whatever you choose, it’s great to know your menu can take your visitors anywhere.

The second (and probably most often used) way to add content to the menu is in the Pages’ box, under ‘Custom Links’.

As you can see, I’m working on a fresh install of WordPress 3 which gives me just two pages – Home, and About. Now ‘Home’ strictly speaking isn’t a page in the default configuration (although you can change that). For me, ‘Home’ is whatever resides at and in index.php.

Notice the tabs at the top of the ‘Pages’ box, which allow you to hunt around through content rich sites for exactly the pages you want. If you’re setting up your menu for the first time you might want to look in the ‘View All’ tab, or if you’re just adding in a page you might want to ‘Search’ for it.

I’m going to select both Home and About so I’ve got something to play with. If I hit ‘Add to Menu’ you can see that my menu is really starting to shape up.

Finally we have the ‘Categories’ box, which acts in much the same way as the ‘Tabs’ box. Again, as this is the default install of WordPress I only have one category, the much maligned ‘Uncategorized’.

I’m going to select it (most of my posts often accidentally end up in uncategorized!) and ‘Add to Menu’. This is what we now have:

Now before we move on you need to ‘Save Menu’, so go ahead and click it.

To prove that this has worked we can load up my simple blog (which has the TwentyTen theme installed) and marvel at it’s glory.

Menu Hierarchy

That’s cool but it’s also only the beginning. The next thing to look at is ordering your menu hierarchy. So far the menu items have just appeared in the order we added them, but we probably want to change this. The good news is that this the whole system is drag-and-drop, so go ahead and move things around.

What you’ll also notice is that you can create a hierarchy by dragging items onto other items. I’ve added a few more pages and created something that looks like this:

You can see I’ve created a hierarchy of pages as indicated by their indents, and I’ve also changed the name of ‘uncategorized’ to ‘The Blog’. If we whizz on over to the actual site, we can also see that WordPress has created a funky drop down menu for me.

Now it’s worth noting that TwentyTen is designed to style the menu as a drop-down, and that the actual HTML WordPress generates looks like this:

<div>
<ul id="menu-our-first-menu"><li id="menu-item-5"><a title="The home page" href="http://localhost/">Home</a></li>
<li id="menu-item-6"><a href="http://localhost/?page_id=2">About</a>
<ul>
<li id="menu-item-23"><a href="http://localhost/?page_id=9">Our Company</a>
<ul>
<li id="menu-item-21"><a href="http://localhost/?page_id=13">The Team</a></li>
</ul>
</li>
<li id="menu-item-22"><a href="http://localhost/?page_id=11">Our Products</a></li>
</ul>
</li>
<li id="menu-item-20"><a href="http://localhost/?page_id=15">Get in Touch</a>
<ul>
<li id="menu-item-19"><a href="http://localhost/?page_id=17">Office Locations</a></li>
<li id="menu-item-4"><a href="http://twitter.com/richardshepherd">My Twitter Stream</a></li>
</ul>
</li>
<li id="menu-item-8"><a href="http://localhost/?cat=1">The Blog</a></li>
</ul>
</div>

A Few More Options

You should also be able to see in the Menus admin that each menu has a drop-down arrow. Click on it, and you’ll see there are a few things you can tinker with.

  • URL - The url which the menu item links to
  • Navigation Label - What it will actually say in the menu
  • Title Attribute - Useful for making your menu accessible, and you could also use some jQuery to grab this and create a piece of ‘description’ text
  • Remove/Cancel - No prizes here

Menu Widgets

There’s one more thing we’ll look at in this introductory tutorial, and that’s the menu widget. So far all we’ve done is actually create a menu in our header and stick ‘Our First Menu’ into that hook. There is one other thing Custom Menu’s do out-of-the-box. In the WordPress admin head on over to Appearance > Widgets and we can take a look at the Custom Menu Widget.

It should be sitting under Available Widgets, so drag it over to one of your widgetized areas and let’s take a look at the options:

As you can see, there aren’t many! You can give the widget a title (I’ve called mine ‘Our Menu Widget’) and then select which menu you have created to use. Now we only created one menu in this tutorial, but you could of course create a second and drop it in here. Click ‘Save’, head on over to your site and you should see something like this:

And that’s it! Great for a sitemap-like feature, just remember that if your menu doesn’t automatically update when you add new pages neither will this widget.

Just the Beginning

As you can probably tell, there’s a lot going on with the Custom Menu feature. I’ve tried to stick to the basics here and focus on the GUI, but there is a lot more going on under the hood that is also worth looking into. If you feel confident with PHP then start playing – there’s so much more you can do.

If all you are looking for is a simple way to create and manage menus for you and your clients, we hope this overview gets you started. As always, we welcome your comments and look forward to seeing Custom Menus on your WordPress sites!

Follow @thinkvitamin on Twitter Please check out Treehouse

Other Posts You Might Find Interesting

  • Sorry - No Related Posts Found

Comments

  • Steve

    On the whole, I love this new feature, but there are two things I haven’t been able to work out.

    First, is there any way to get rid of the ugly (and, as far as I can tell, useless) ID attributes on every LI cluttering up the menu markup?

    And it would be great to be able to add the other exciting new feature, custom post types, to the nav menu, just like you can do with categories, but this doesn’t seem possible at the moment. I’m sure a plugin will address this in due course.

    In any case, thanks for the great, simple intro, Richard!

  • http://dougdraws.com Doug C.

    Great walkthrough, Jon. The new menu system was indeed a huge plus for a complete code n00b like me (lol).

  • http://dougdraws.com Doug C.

    Oops, sorry…I meant “Richard”. It’s a Twitter typo, lol.

  • http://twitter.com/teddyzetterlund/ Teddy

    Great introduction to this new and highly desired wished-for functionality. In my quest for clean mark-up in my WordPress themes I ran into some issues, though, with all the IDs and Classes that it adds to the list and its list items.

    A solution for this is to write a custom menu function which gets rid of those with a small regexp. An example of this can be found at the very bottom of this file: http://github.com/made-byted/wp-gene/blob/master/functions.php

  • http://www.wearecondiment.com Chris

    Thanks for this, Richard.

    I adore WordPress. It’s such a great platform for rapid PHP development. And features like this will only help to make it a much more intuitive CMS for clients.

    Although giving some clients too much control over their website is an accident waiting to happen.

  • Chris

    Is it possible with the new custom menus to create a primary menu of just your pages and then directly below that put a secondary menu of your categories? That would be sweet!

  • http://www.videousermanuals.com/ Video User Manuals

    Great tutorial. I agree with Teddy, we have all been crying out for this functionality for ages!

    As developers, we were a bit perturbed because the Menus are only accessible from the Appearance menu, and given that the majority of developers give their clients editor only access, this was a problem.

    We produce the White Label CMS plugin, and yesterday released a new version of it which with one click allows you to give editors access to the Menus and widgets, but hides the switch themes option.

    Thanks

  • Tofi

    Does anybody know how modify this menu to view and close child sections by clicking on parent section?

  • http://dougdraws.com Doug C.

    Hmm, I left a comment. Where did it go?

  • Jonathan

    Thanks for the walk-through, helps a lot.

    I’m wondering if there is any integration between custom menus and custom post types? I would love for my users to be able to create a new post using a custom type, then add it to the menu as if it were a page. Otherwise, they’ll have to hardcode the links using Custom Links in the Custom Menu GUI, right?

    Thanks,
    JD

  • http://www.aligent.com.au Jonathan

    And now I have to answer my own question. Click the Screen Options tab in the top-right to allow Custom Post Types to appear in the options for links. Perfect!

    Cheers,
    JD

  • http://www.jtorbitt.co.uk Jonathan

    Loved teh tutorial, just wish I had read it a few weeks ago before I hand/hard coded the equivalent to this directly into the sidebar on a site I was working on!

  • http://www.ferryto.eu/ Ferry to Europe

    I’m loving the new menu’s, but is there a way to just add on category (or page) and then all the children of that category 9or page) will be automatically added to menu (one level down).

    For those of us who have many categories with duplicate names of some categories arranging manually can be difficult.

  • http://ramm.dessigual.com Ramm

    Nice!

    Good article, i needed to know all this.

    I’m starting to work with WP, i made my own theme and what i’m missing here is how to add my theme the ability to support menus.

  • Brian

    Same question as Ferry to Europe. I have 144 Pages, some with the same name it is very difficult to build menus using this system with the limited options on selecting. They need a search by page and then show children under it at a minimum.

    If any one knows of a solution I would love to hear it.

  • http://tighe.tk Tighe

    Thanks! You answered my question as well!

  • http://cwcage.com Chris

    Great intro to the new custom menus. Thanks for the walk-through. I’m looking forward to the flexibility this will give us going forward.

  • http://www.richardshepherd.com/ Richard Shepherd

    Absolutely! You just need to create two menus, and in header.php include both. Your CSS styling will do the rest.

  • Nicolas

    Great tuts, thank you.

    I was wondering if there was any way to add the ID of the page/post in the class of the LI. Currently it displays menu-item-### but where are these number coming from ?

  • Osu

    Just like Steve (http://thinkvitamin.com/dev/getting-started-with-wordpress-custom-menus/#comment-21755), I don’t understand why you can’t add a category-style listing of your custom posts in a menu.

    Is that possible at all?

  • Contact_me

    you saved my night. thanky you!

  • nomadone

    when you create pages, categories, posts etc in wordpress wp automatically assigns a category number based on the next available ID number so these are coming from those auto assign ID numbers. You can’t really pick them yourself as far as I am aware

  • http://twitter.com/dereckbester Dereck Bester

    Thank you,

    Just what I needed.

    Dereck Bester,
    http://dereckbester.co.za
    http://twitter.com/dereckbester

  • Mike

    Me, too. Thanks!

  • KD

    Hi. First off, great tutorial! I’m definitely putting it to use and I’m so glad this is integrated into WP finally. But what if you wanted to apply a CSS rollover menu using background: url(‘images…’) ? I am using a different image per menu item and I’m trying to do this while incorporating pages rather than creating an HTML menu inside header.php. How will you be able to identify each menu item so that each one has a different image (menu items are images)?

  • http://www.mikejongbloet.co.uk Mike Jongbloet

    Does anyone know the class name for the Custom Menu Widget?

    I’m trying to remove it and all default WP widgets, using

    unregister_widget(‘WP_Widget_Recent_Comments’);

    However, I can;t track down the class name for this widget?

    Any ideas?

  • Anonymous

    Wow, I cant wait to use this

  • http://frontrowspectator.com/ front row spectator

    I love this tutorial. I was able to set up my custom menu but now, the post that i linked through category to my custom menu, which so happens to be my last post, the header (or should i say title of the post?) is not displayed. I need help :(

  • Yaya

    thanks, that’s very useful and clear.
    how can i add a menu item that only opens it’s sub menu items without being linked to a page? like in your example the about won’t be clickable itself but would show the our company and our products options?
    thanks again!

  • Marc

    I’m looking for the same solution. Please post here if anyone knows how to do this. Thanks!

  • http://www.facebook.com/people/Pablo-Selin-Carrasco-Armijo/100001016473166 Pablo Selín Carrasco Armijo

    actually, I found that you have to call the menu using ‘theme_location’ instead of ‘menu’ if you want to use multiple locations for your menus, like this:

    wp_nav_menu(array(‘theme_location’ => ‘menu_name’));

    otherwise you will get only the first menu displayed…

    it’s a nice article anyway, just wanted to tell in case someone has a problem with that.

  • Clearbluesky

    Me too!

  • Fadillicious

    thx dude
    my problem solved

  • cangrejero

    This is the kind of tutorial that is dumb proof. Congratulations!

    Just one quick question. Let’s say that I want to exclude, or only show certain categories of posts in my “Home” Page. How do I accomplish that with “wp_nav_menu”?

  • cangrejero

    This is the kind of tutorial that is dumb proof. Congratulations!

    Just one quick question. Let’s say that I want to exclude, or only show certain categories of posts in my “Home” Page. How do I accomplish that with “wp_nav_menu”?

  • http://roopedog.com Roopedog

    3 steps and out… nice post… thanks for the quick code!

  • http://twitter.com/sagive sagive SEO -שגיב

    i love it man!! thanks.. been looking for some simple how to on wordpress menus

  • http://www.facebook.com/ScottTurkington Scott Turkington

    I thought your post may help me fix an issue I’m having but I couldn’t figure out my issue. I have a wordpress theme Boldy installed at http://www.whatintheworld.tv made by http://www.site5.com. For some reason it’s duplicating the second nav button “Hosts” again at the end. I used firebug and by deleting
    it appears correctly in firefox but I can’t narrow down what document contains this code. I’ve searched the source of every document associated with wordpress and it can’t find that line of code. I’m totally lost? Thanks for your help!

  • nanggroe

    thanks a lot for this article

  • http://chrisgreigphotography.com/ Chris

    This was actually what I was looking for and would have been helpful as a mention in the original post. Thanks Pablo

    Good article anyway.

  • Anil507

    Thanks for your details.. I fixed my problem and my sidebar looks crazy.
    http://funnyandspicy.com

  • Mmtahir

    Can we style this menu horizentaly in table-like format. I would love to hear fom somebody about css for this

  • http://bayansell.com/ BayanSell

    Thanks for this, however, it didn’t solve my problem. Perhaps you can answer? I want my Destinations menu to automatically add locations in its submenu. This happens using the standard menu, but not in the custom menu. Am I missing something?

  • Coolguy997

    This was actually what I was looking for and would have been helpful as a mention in the original post. Look at freelearn2fly.blogspot.com as well for more info. Thanks

  • Hieg

    This is great, thanks for the article! I’m using the new Network Sites feature and I’m trying to deploy a single theme across all of the Sites. I want the theme to have a common top nav. I’m using this method to create my custom nav but of course it’s site specific. Does anyone know a way I can use a custom menu from one Site in my network across all of the sites?

  • http://www.clemensplainer.com Clemens Plainer

    Thanks for that Comment. That’s what I really needed :)

  • http://www.thesecretofpersuasion.com/blog Vincent

    Thanks so much for this. A clear and concise guide which is so easy to follow. Solved my problem that was troubling me for an entire week.

  • Magicsun

    I use the “Ambrosite Unlink Parent Pages” plugin. It automatically replaced the url with a # so it won’t go to the page. You won’t have to do anything for it, just install the plugin and it does all the work. It only replaces when it has sub-menu’s. If it’s a single item, it will link to the page.

  • Magicsun

    I’m probably missing something, but when I create a parent menu item, and have the checkbox for new pages checked and everything it works fine. But when making a new page after that, it doesn’t automatically gets added on the right spot. It just gets added as a seperate parent item in the menu.

    It’s kinda weird, that a client has to actually drag the page to the proper spot, while he has chosen a “parent” page when making the new page.

    Does anyone get what I want? Am I missing something? I’ve now switched to the old style, that automatically uses the structure that I choose in pages. it would be really weird if this isn’t possible with the new system ..

    Thanks.

  • Magicsun

    I seem to found the solution to my own problem.

    http://wordpress.org/extend/plugins/gecka-submenu/

    it’s a plugin that allows to automatically add child-items to the menu. So for example, you have “About” and you have 3 pages that have “about” as parent. Then you only have to create an about menu item, and check the box for automatically add child-pages. It will create the submenu’s itself.

  • Magicsun

    Look in to this:

    http://wordpress.org/extend/plugins/gecka-submenu/

    It’s Gechka Submenu, and it adds a checkbox to your parent menu items that you can check to automatically add child-pages to the menu. So you only create “about” for example, and when you add 3 pages in your dashboard that have “about” as parent, it will automatically create those submenu items.

  • http://bayansell.com/ BayanSell

    Thanks! That’s exactly what I need.

  • http://alaure.com Alyssa

    Thanks! This solved the issue I was having :)

  • Danalorraine

    Any tips on how to get a menu to drop below the header? I’m using a custom menu in the Scherzo theme and getting a bit stuck with it. Thanks.

  • UKCaveDiver

    Hello,

    thanks for the great tutorial!

    I’m playing around with custom post types/taxonomies for a while now and I’m wondering that there is no support to add a menu entry in custom menus which resolves in a list of posts, that are e.g. from a certain post type and have a special value in a taxonomie!

    you can have either taxonomy-values (even hierarchical queries – great) as menue entries, which lists everything that matches, but no combinations of post-types and/or taxonomies?

    As I’m fairly new to the wordpress ecosystem I would appreciate any hints to a existing plugin that provides this kind of functionality or information how to develop such a plugin/custom menu extension.

    thanks in advance
    kind regards
    Klaus :)

Badges for Treehouse

Treehouse

Learn iOS, Rails, CSS3, jQuery, Node.js, HTML5, UX and more in less than 8 minutes per day. New videos added regularly. Sign up today and get a free Web Design Toolkit.

Ads Via The Deck

Think Vitamin Radio
Episode #34: Amazon Fire and Responsive Roundtable

Check out our bi-weekly radio show. Covering the hot topics on the web.

Audio clip: Adobe Flash Player (version 9 or above) is required to play this audio clip. Download the latest version here. You also need to have JavaScript enabled in your browser.

Download Podcast as mp3

Advisory Board

The Think Vitamin Advisory Board in place make sure that you receive the best content possible.