How to add support for navigation menus to your WordPress theme

Tagged WordPress

The new navigation menus system in WordPress 3.0 looks promising, but in my opinion it’s not very usable yet. Anyway, here’s one way to add navigation menus to your theme while maintaining backward compatibility:

In your theme’s functions.php add something like the following code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function mytheme_addmenus() {
	register_nav_menus(
		array(
			'main_nav' => 'The Main Menu',
		)
	);
}
add_action( 'init', 'mytheme_addmenus' );
 
function mytheme_nav() {
    if ( function_exists( 'wp_nav_menu' ) )
        wp_nav_menu( 'menu=main_nav&container_class=pagemenu&fallback_cb=mytheme_nav_fallback' );
    else
        mytheme_nav_fallback();
}
 
function mytheme_nav_fallback() {
    wp_page_menu( 'show_home=Start&menu_class=pagemenu' );
}

In line 1 we add support for the navigation menus. The mytheme_nav() function is what you will use in the theme to display the menu. Inside that function we check if wp_nav_menu() exists, that means if we’re running WordPress 3.0 (or later). If not we’ll use the fallback function mytheme_nav_fallback().

Notice that the fallback also gets called if no navigation menus have been created in the admin area. That’s what the fallback_cb parameter on line 4 does.

To keep the HTM markup and the CSS consistent you’ll have to use the container_class parameter on wp_nav_menu but the menu_class parameter for wp_page_menu.

In your template use the following code to use your new custom function:

<?php mytheme_nav(); ?>

Resources

Ramblings

What’s good about the new menu system:

  • Total control over what appears in the menu
  • You can add posts, pages, categories and tags in the menu
  • Very nice drag and drop interface

What’s bad:

  • You will have to teach your users how to use the system properly.
  • If you create new pages they won’t be added to your existing menu (except for top level pages).
  • You can not control your page menus through the navigation menus interface. I think it is… very very odd that WordPress doesn’t have a simple drag-and-drop interface to arrange pages.
  • The previous point means that the new menu system is useless unless you update your theme.
  • The wp_nav_menu() call is inconsistent with the existing wp_page_menu() function.
Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • Blogplay

Related posts:

  1. Creating a valid WordPress theme
  2. Very simple Typo3 navigation
  3. Typo3 and the YAML vertical navigation

28 Comments

  • [...] How to add support for navigation menus to your WordPress theme [...]

  • Posted by Lox on 12. June 2010 at 20:29.

    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.

    • Posted by nicolas on 12. June 2010 at 21:02.

      Yeah. I’m really disappointed by the menu system. I’ve worked with it for maybe 30 minutes and found several flaws and omissions. The method I describe in the post is useful because users who want to use the nav menus can, but they don’t have to.

    • Posted by MichaelH on 14. June 2010 at 23:22.

      Lox – I believe the developers addressed that isssue in 3.0.

      • Posted by nicolas on 15. June 2010 at 10:32.

        Yeah, I think this is the relevant last minute changeset.

        It’s not like somebody is intentionally trying to make the nav menu system imperfect ;-)

  • Posted by yalamber on 21. June 2010 at 15:02.

    How can we get the menu array or object to customize it the way we want. like we could do get_pages() to get pages is there any function like get_nav_menu().??

    • Posted by nicolas on 21. June 2010 at 17:27.

      wp_nav_menu() can return instead of printing. If you’d rather get some data structures, a quick look at the source seems to indicate that one of the wp_get_nav_menu*() could do what you want.

  • [...] How to Add Custom Menus to your WordPress 3.0 Theme [...]

  • Posted by John Crumpton on 30. June 2010 at 09:39.

    add_theme_support( ‘nav-menus’ );

    has changed to

    add_theme_support( ‘menus’ );

    • Posted by nicolas on 30. June 2010 at 10:36.

      Thanks John! Looks like this has changed before the 3.0 release. I updated the article. nav-menus still works but it apparently has been removed from the docs.

  • Posted by LoneWolf on 3. July 2010 at 13:36.

    Do you have links to a better description of add_theme_support () — i.e. information about where this actually is useful?

    Can we add our own functionality in here? For example, could a plugin define something and then check to see if the theme supports it?

    Also, using register_nav_menu () or register_nav_menus () call add_theme_support (‘menu’) internally.

  • Posted by WordPress 3.0 的menu功能 | Jinwen Say on 7. July 2010 at 12:05.

    [...] 中间我发现的问题是要怎样兼容3.0之前的版本,在官方CODEX 中有这样一篇推荐文章,说是能够解决新旧版本的兼容问题。我自己试了一下,但没成功;又看了一下3.0 上新的默认主题-twenty ten 上也没有这样考虑的。所以如果有谁知道如何兼容旧版本的话请告知一声,我也想看看。 [...]

  • Posted by holger on 13. July 2010 at 08:19.

    hi, very promessing! especially since i’m planning to call anchors with submenu items (which works in ten twenty).
    to get it into my theme didn’t work yet. i included what you say goes into the functions.php, after that the menu system shows up, but doesn’t work, what i create doesn’t show up, only the regular pages…?
    what did i forget?
    thank you
    holger

    • Posted by holger on 13. July 2010 at 08:31.

      i solved the problem: put this

      at place for menu

      • Posted by nicolas on 13. July 2010 at 09:50.

        Hrm. Sorry about this, but WordPress isn’t smart enough to encode tags in comments etc, it just deletes all of that silently :-(

        I’ll look into fixing that.

        • Posted by nkuttler on 13. July 2010 at 10:07.

          This is highly annoying. WordPress doesn’t simply hide tags it doesn’t like, it deletes them from the database as well. No way to recover your comment.

          Anyway, it should be fixed now <?php phpinfo(); // sue me ?>

  • Posted by Upgrade wp_list_pages() to wp_nav_menu() | WP First Aid on 17. July 2010 at 01:35.

    [...] Also consider setting the wp_nav_menu() fallback_cb option to 'fallback_cb' =&gt; 'wp_list_pages'. This backward compatibility may also be addressed with a custom function as posted by Nicolas Kuttler. [...]

  • Posted by Wordpress 3.0 主题的向下兼容问题 » Life Studio on 6. August 2010 at 14:14.

    [...]   看到一篇传说可以解决 WordPress 3.0 主题向下兼容以前版本的方法,不过明显作者在写代码的时候比较粗糙,并没有验证过(就算验证,也就是 WordPress 3.0 中作的测试),在我的 2.9 下还是行不通,仔细看了一下,也就是少了个判断,略加修改就可以使用了。 [...]

  • Posted by ian on 9. August 2010 at 11:26.

    Thanks Nicolas.
    It worked great for me … “straight out of the tin” and just what I was looking for. I was able to add a 2nd menu to the theme I was using in moments! I really appreciate the info!
    Ian

  • Posted by matt on 10. August 2010 at 01:01.

    Why won’t it work to simply have the wp_page_menu call after the else rather than a new function? I gave it a try and it doesn’t work. Can anyone shed light on this for me? Thanks…

    • Posted by nicolas on 10. August 2010 at 07:41.

      How does it not work? Also, the fallback is explained in the post.

      • Posted by matt on 10. August 2010 at 15:35.

        Oh, it is making the call to the fallback in the wp_nav_menu parameters. No problems with that then. The code works for me as it is. Was what I needed actually… thanks.

  • Posted by HemingwayEx v1.8 released « NULL.in on 29. August 2010 at 21:59.

    [...] the two columns. Setting up WP Menus was quite straightforward actually, based on information in Nicholas’s article. Then there was some work needed to show drop down menus and for that I chose to use the Superfish [...]

Leave a Reply

Your email is never shared. Required fields are marked *

*
*