I have written several posts regarding the use of the wp_nav_menu() function. I have written about its uses, its implementation, and even an older post regarding (some of) the CSS classes it generates. This post continues with an idea for extending the wp_nav_menu() function by adding additional items to the menu list with code versus the user interface found in the Administration Panels, such as automagically adding a self-propagating list of categories.
This idea is not necessarily new but finding an example may be a bit more difficult. Let’s have a look …
First off, there are several sources of information regarding wp_nav_menu() to take into consideration:
- The WordPress codex reference.
- The “core.trac.wordpress.org” reference.
- This web site’s references.
Each of these links will open in a new tab/window for convenience purposes.
Now that we have a list of reading material we should actually take a look at it …
- The first reference leads to the WordPress codex and provides the standard parameters that can be used with wp_nav_menu().
- The next reference and the experience that was offered by Ian Stewart from ThemeShaper.com is the real key to solving this little puzzle.
- The last reference simply leads to the wp_nav_menu() tag archive here.
I would suggest at least having a quick look at those pages before carrying on to the next page, especially the one referencing the wp_nav_menu() function in the “core”, or primary code base of WordPress, as you will find a very relevant comment there.
Let’s start by focusing on the following code snippet as found in the “core” reference:
// Allow plugins to hook into the menu to add their own <li>'s
$items = apply_filters( 'wp_nav_menu_items', $items, $args );
$items = apply_filters( "wp_nav_menu_{$menu->slug}_items", $items, $args );
$nav_menu .= $items;
The beauty of this little snippet is it shows, with the use of the wp_nav_menu_item filter, you can add specific items to the menu output if the end-user has chosen to create a custom menu. Let’s look at an example that will allow you to add a “Home” page link to the beginning of the menu.
If you add the following to your ‘functions.php’ template file it will add a home link to your wp_nav_menu() output:
// Filter wp_nav_menu() to add additional links and other output
function new_nav_menu_items($items) {
$homelink = '<li class="home"><a href="' . home_url( '/' ) . '">' . __('Home') . '</a></li>';
$items = $homelink . $items;
return $items;
}
add_filter( 'wp_nav_menu_items', 'new_nav_menu_items' );
The basic premise of the function is:
- Assign your desired output to a variable
- Concatenate the output variable with the $items variable
- Return the $items variable so it can be used in the filter
- Add the results of the function to wp_nav_menu_items with an add_filter() function
If you wish to use this when a custom menu is not being used just add the following (or similar) filter after the above code:
add_filter( 'wp_list_pages', 'new_nav_menu_items' );
But what if we wanted to add something to the end of the menu output, such as a RSS feed link, or maybe just some random text or a static URL link. Let’s look at the following example which expands upon the code above to do just that.
// Filter wp_nav_menu() to add additional links and other output
function new_nav_menu_items($items) {
$homelink = '<li class="home"><a href="' . home_url( '/' ) . '">' . __('Home') . '</a></li>';
$feedlink = '<li class="feed"><a href="' . get_bloginfo_rss('rss2_url') . '">' . __('RSS') . '</a></li>';
$random_text = '<li class="rainbows"><a href="#">OMG ... Double Rainbows!</a></li>';
$items = $homelink . $items;
$items = $items . $feedlink;
$items = $items . $random_text;
return $items;
}
add_filter( 'wp_list_pages', 'new_nav_menu_items' );
add_filter( 'wp_nav_menu_items', 'new_nav_menu_items' );
There always seems to be some new way to add more uses to the core functions in WordPress and I like to find, explore and write about them. I often implement them in the First Aid Theme, as I have done by using the above example code to add a “Home” link to the menu. On the next page I will leave you with one more example, the one I referred to in the opening paragraph.
Although this was a bit more involved it really did not make that much of a difference in the case of implementing this in a custom menu so without further ado here is the code snippet:
function new_nav_menu_items($items) {
$cat_menu_list = wp_list_categories( 'echo=0&title_li=&child_of=124' );
$items = $items . $cat_menu_list;
return $items;
}
add_filter( 'wp_nav_menu_items', 'new_nav_menu_items' );
If you are trying this at home make back-ups of your files, just in case you want to revert your edits. Your category list hierarchy may need to be noted as well.
The key to this snippet is the wp_list_categories() by default will echo its results to the screen, you will have to set the parameter ‘echo=0′ to turn off this default behavior.
As for using this technique for categories with a non-custom menu I will leave that as an exercise for those looking for a challenge … Enjoy!

22 Responses
20 Comments
2 Pingbacks
Sounds interesting, but you lost me at the end of page one. Paged articles get me pressing Ctrl+W…
@Stephen – Yours is not the only comment I have received regarding articles being paged. I will be going back and removing the page breaks momentarily. Thanks for the input.
hi i would like to add a css rule only to this single li tag
class=”menu-item menu-item-type-post_type menu-item-655″ id=”menu-item-655″><a href="#" LINK</a
how can i do? thanks
@Sergio – Would you not just want to style this element:
#menu-item-655 { ... }Doc – Making specific menu items do specific things is always a challenge.
Your reply above to @Sergio was brilliant.
I needed to add both a Home and a Table of Contents link to my site nav, and started off with adding this to my functions.php, as you indicated:
function new_nav_menu_items($items) { $homelink = '<a href="' . home_url( '/' ) . '" rel="nofollow">' . __('Home') . '</a>'; $toclink = '<a href="/table-of-contents/" rel="nofollow">Table of Contents</a>'; $items = $toclink . $items; $items = $homelink . $items; return $items; } add_filter( 'wp_nav_menu_items', 'new_nav_menu_items' );(Note that I had to add the
$toclinkfirst as the home link had to appear before it, left-most on the menu. Comical and counter-intuitive.)Unfortunately, this added the links in question to both the primary and secondary navs.
I was in the midst of trying to target a specific wp_nav_menu with your function when I read the above; now all I needed was this in my style.css:
#menu-item-61 a { color: #F3EB7B; } #nav2 #menu-item-61 a:hover { color: #F3EB7B;Same effect, less code…
Much appreciated.
@Michael – Glad to be able to help. I always prefer a bit of CSS over code if its possible; it’s much easier to maintain in most cases, too.
Thank you a lot! Looking for such an article for hours.
@Markus – I’m glad you found the post; I hope you find it useful, too.
Filters seem pretty powerful, can they change the default output that WordPress generates?
I’m a bit of a PHP n00b, I’m wondering if it’s possible to give each level of navigation a different UL class than just .sub-menu. Eg. could the third level be .sub-menu2.
Kind of like if there was a sub_items_wrap paramter in the codex.
@Arley – Although it may be possible to filter the specific item you are looking for, it may be more feasible to address the CSS generated by the menu as I am guessing you are looking for a specific element to style.
Actually, I am using a snappy little jQuery script that is hunting for .sub-menu and applying some effects to the drop down. It’s applying this unwanted style to the UL UL UL as well. I might try to tinker with the jQuery instead.
@ArleyM – I’d be interested in what you come up with … might make for a good follow-up post.
Hi! Thanks for this post, this helped me a lot!
But, Here is the thing, I have 4 menus (menu01, menu02,…).
And now all of then have the “home” link.. but, what if I want only in one of those menus, like “menu02″?
@Luis – As this method uses a filter it will apply to all instances of the default navigation menu … it may be simplest to use a Custom Menu for the exception(s).
I see! Thanks! And I used the custom menu as you told. Now, only the “menu02″ have the link home.
Thanks a lot for answering! I just discovered your site these days and it’s really awesome!
Thanks dude =)
You’re welcome!
Hello Doc,
Excellent publication, thanks for sharing!
I have only one question?
If I add, let’s say Home link with your method I will filter all menus called with wp_nav_men().
Can you tell me how can filter only one menu.
I’m using twice wp_nav_menu and I want to add custom links after items only in one of them.
My English is not perfect, hope You understand me and can help me.
Thanks in advice!
@Bogdan – As noted above, and you have noted as well, this method will add these items to all instances of the `wp_nav_menu` function call; I would suggest as I did above, it may be better to use multiple custom menus.
Hi Doc and thanks for response,
Yes I’m using custom menus. The problem is that I want to add language flags from WPML language switcher to the end of one of this two menus.
In WPML there is option to include languages in wp_nav_menu, and they give me to choice in which menu. But it includes flags plus language names and client wants only flags.
So I started to look how to realize this and came to your publication.
Now I just need to find how to filter specific menu – by name or by ID and make your function more specific.
Any way Your publication is excellent.
Thank You again.
Regards.
[...] This post was mentioned on Twitter by Ian Stewart, Simon Prosser, Paun Eugen, Tutoriale WordPress, TampaBay WordPress and others. TampaBay WordPress said: RT @iandstewart: Extend the WordPress Menu http://bit.ly/cEc5Uu [...]
[...] under my nom de plume for that blog of The Doctor. The gyst of the article was how to Extend the WordPress Menu, referring to adding content to the wp_nav_menu() function output. I started writing the post on [...]