I enjoy simplicity, in everything. Unnecessary complexity is evil. Have a look at my WordPress plugins.

Dynamic custom menu’s in WordPress

Since WordPress 3.0 you can use custom menu’s in your themes, which is great because of how easy to use they are for you or (if you’re a developer) for your cliënts. You can register theme locations where menu’s can be hooked to, which is particularly useful for site-wide menu’s like a header menu. But what if you need to hook a menu to a certain page/post or maybe even multiple posts? I’ve looked around a bit and found no plugin yet that took care of this, while the coding part would be pretty simple. That’s why i’m going to walk you trough the necessary steps to implement this in your theme. But first, let’s talk a bit about the different functions that came with custom menu’s and which we are going to need.

wp_nav_menu() – This is the function that calls and echo’s the custom menu. You can specify many parameters but the ones we care about at the moment are ‘theme_location’ and ‘menu’. ‘theme_location’ calls the menu that is hooked to the given location, ‘menu’ calls the menu by ID, slug or name.

is_nav_menu() – This function checks if a given menu exists, again accepts (matching in order) ID, slug or name.

With these two functions we can check if a given menu exists and if it does call it, if not we can either do nothing, call a default menu or whatever you want to do when there’s no custom menu hooked to the current page.

Hooking a custom menu to a page or post

Like always, there are multiple ways to do this. We can look for $_SERVER['REQUEST_URI'] and use that as our menu name, however this comes with a big downside: we are limited to 1 page per menu. We won’t be creating a dynamic custom menu for EVERY page or post so this is probably not what you want. What we want is to create a one-to-many relationship between a menu and certain pages or posts. What about adding a post_meta value that holds the menu id or slug, whichever is easiest?

(Note: As of WordPress version 3.1, some screen options on the Post & Page edit Administration Panels are hidden by default. Custom Fields are hidden by default if they have not been used before.)

By specifying the menu slug as a custom field meta value we can call this from our template files from inside the loop by using get_post_meta(). Then we check if a custom menu with that slug exists, just to be sure. If it exists, output the menu using wp_nav_menu(). I’m not specifying a lot of parameters here, but of course you can just specify what’s needed inside the parameter array.

$menu_slug = get_post_meta(get_the_ID(), 'menu', true);

if($menu_slug && is_nav_menu($menu_slug)) {
	wp_nav_menu(array(
		'menu' => $menu_slug
	));
} // optionally, add an else to output something when no menu exists with the given meta value.

So there we have it, we hooked a menu to a post. Using the above method you can of course re-use the same menu for different posts or pages. Now, if we wanted to make things easier we would get all created nav menu’s with wp_get_nav_menus() and add a select box beneath the post editor where a custom menu can be chosen but that would be for another post.

In fact, I might create a WordPress plugin that does just that if it turns out people are actually interesting in such a thing. Are you? Let’s vote in the comments. When we reach at least 50 +1′s, I’ll build it.

Update (November 2013): The CE WP-Menu Per Page plugin seems to do just this.

Share this post: on Twitter on Facebook

23 Responses to “Dynamic custom menu’s in WordPress”

  1. I’m having a hard time finding a menu system that would make my existing menu look more professional.

    see here: http://localmiamiguide.com

    the theme does not support many of the plugins available out there and I know nothing of css or php ;-(

    how much would you charge me to create something nice for my site ?

    Kind regards,

    Jcolome

  2. Thanks, I used this code snippet in my WP 3.5 website with the 2011 Twenty Eleven theme, and placed the code inside header.php. My code is now:

    ID,’menu’,true);
    if(is_nav_menu($menu_slug)) {
    wp_nav_menu( array( ‘menu’ => $menu_slug ));
    }else{ wp_nav_menu( array( ‘theme_location’ => ‘primary’ ) ); } ?>

    The default menu is shown, unless a page has a property ‘menu’ with either a slug or a menu ID. Works like a charm!

  3. Um, HELL yeah! I’ve been searching high and low for such functionality, and am really surprised that no one has yet created it.

    I’ve come across tons of inquiries/posts/forums where users are also looking for such a plugin, so get to work! ;)

    Happy New Year!

  4. The above site is live. I am testing this on a local site.
    I set up a custom menu named Youth. On the page I want this menu to show on I set the Custom fields Name to menu and the value to Youth. I put this code in the header.php file:
    ID,’menu’,true);
    if (is_nav_menu($Youth)) {
    wp_nav_menu( array( ‘menu’ => $Youth ));
    }else{ wp_nav_menu( array( ‘theme_location’ => ‘primary’ ) ); } ?>
    When I click on the Youth tab in the menu I get this error: Error establishing a database connection

  5. @Ray: I think it’s important to learn to understand the meaning of ‘slug’ in WordPress sites. Also, you could invest in some PHP language markup, but that’s another thing. I personally don’t feel a WP user should have to invest in PHP, HTML or CSS, but that’s my viewpoint.

    You should do fine if you just use the code from this blog and my comment. So, let me ask you, do you have a menu by the slug (!!) ‘Youth’? And if so, can you try and replace your code by my code? Also, stay aware of lowercase/uppercase/CamelCase in your naming and thus slug naming.

    Hope this helps!

  6. hi, really good tutorial, it work fine! But i have a new trouble. I need to use dynamic custom menu’s like this post but in category main pages, any idea?
    thanks!

    • Hi Jaziel,

      Sorry, I have never found the time to develop this plugin. There’s just so many other interesting stuff to do, and then there’s work. I will take a look at the plugin you mentioned though. If it does the trick for you I’d say, use it! Most plugins are actually made up of many little hacks and then miraculously just seem to work…

      Good luck!

      Danny

    • Hi Jaziel

      How did you get this working, is there a short code i need to put on the page template? i have been struggling with getting this to work, theres no documentation on it :(

      thanks in advance

  7. Hello,

    The “CE WP-Menu per Page” seems to work good for me.
    To add the menu to the page, first install and enable the plugin, then create new menu from Appearance->Menus.
    After the menu is created, open the page that you’d like to add the menu and below the content editor, there is a tab: “Select a menu for this page”, from the drop down select the menu that you’d like to use and location (if available). Save ! Done!

Leave a Reply