Here is a common navigational scheme, with parent pages on top and child pages (if they exist) on bottom:

We’ll need code to help us: 1) query the page, 2) determine if there are child pages, and 3) properly highlight both the .current_page_parent and .current_page_item links.
Here is the PHP:
<ul id="nav">
<?php wp_list_pages('title_li=&depth=1'); ?>
</ul>
<?php if($post->post_parent)
$children = wp_list_pages("title_li=&child_of=".$post->post_parent."&echo=0"); else
$children = wp_list_pages("title_li=&child_of=".$post->ID."&echo=0");
if ($children && is_page()) { ?>
<ul id="subnav">
<?php echo $children; ?>
</ul>
<?php } else { ?>
<?php } ?>
And here is the CSS:
* {
margin:0;
padding:0
}
#nav {
background:#577da2;
border-bottom:1px solid #FFF;
height:32px;
}
#nav li {
margin-right:25px;
}
#nav li, #subnav li {
float:left;
list-style:none
}
#nav a, #nav a:visited {
color:#FFF;
text-decoration:none;
font-weight:bold
}
#nav a:hover, #nav a:active,
li.current_page_parent a,
li.current_page_parent a:visited,
#nav li.current_page_item a,
#nav li.current_page_item a:visited
{
background:#295887
}
#subnav {
background:#e6eef7;
border-top:2px solid #577da2;
border-bottom:2px solid #cad8e6;
height:28px;
}
#subnav li {
border-right:1px solid #295887;
padding:0 7px;
}
#subnav a, #subnav a:visited {
color:#295887;
text-decoration:none;
font-weight:bold
}
#subnav a:hover, #subnav a:active,
#subnav li.current_page_item a,
#subnav li.current_page_item a:visited {
text-decoration:underline
}
That’s it!
If you’re wondering why the CSS seems overly verbose, it’s to make sure the :active and :hover states display correctly whether or not subpages exist — if they do, the primary nav uses current_page_parent, if they don’t, it resorts to simply current_page_item.
10:29 am
Cool, helps a lot, this is by far the best solution, just one q:
does it work with category children as well?
12:43 pm
I was wondering about categories too. I’ve tried replacing posts with categories everywhere in the code but that did not work. Any ideas or solutions? Thanks.
10:46 pm
Yes, This is really nice.
Especially it is completely php driven, and no javascript.
But it would have been complete if it could do the same for WordPress categories as well..
Anybody figured out how to do it?
12:20 pm
Should i use a javascript just like superfish in premium news theme? Or only the script aboves? Thanks before darren. Ops, when mimbro pro will be release? I’ve take a look several premium news theme, but i thought mimbo has a unique value, very very user friendly.
10:08 pm
The one area I struggle with is the whole navigation for WordPress (as stated in my blog) and how it can be integrated as a CMS properly. So what do we do back-end for the two-tiered conditional navigation to work? Do we organise it by the page parent or page order?
Thanks and sorry if this seems a little off topic or simple question
11:00 pm
So what do we do back-end for the two-tiered conditional navigation to work?
Simply create pages (and subpages) and the nav code from the article will scale accordingly — that ease of use is what makes WP a great CMS for small and medium sized sites.
7:08 am
Great trick. Thank you…
8:37 pm
Hi Darryn
Thanks for the code, great stuff.
Just would like to know how to make the php code return a three tiered navigation.
Once again, thks heaps for your tutorials
Regards
Said
8:39 pm
Opps for the type on your Name
Regards
Said
11:38 pm
Wow!! Amazing tip :)
mmm… it’s possible the same thing with categories and subcategories?
7:15 am
Great tutorial,thanx
9:39 pm
Thanks Darren. This is a superb tip. I wanted to do the same for my categories list.
Is there a way I can change the code to display categories instead of pages as mentioned in this post.
Would really appreciate it if you could suggest something as I am not too good at php and cant really make out how to display categories instead of pages. Also, what corresponding changes would take place in the CSS code?
Thank you!
2:16 pm
Was thrilled when this worked! Great Stuff!
Sadly it turns out I also need this to apply to the Categories and Sub-Categories rather than Pages….grrr
Did anyone find a solution I’ve been looking for ages now?
Thanks
10:05 am
Hi Darren – Using your generously supplied code, I have a problem where the second level of navigation is displayed on the 404 and search results pages where there were no successful results for a search. Any ideas on why that might be happening? Any insight into how it might be remedied?
1:43 am
Hi Liam, Your question is pretty old, but I’m wondering if you were able to solve the problem. I’m experiencing what I believe is the same thing. On a 404 page, the entire navigation (parents and children) are being jammed into the sub-navigation. Any help would be appreciated!
Thanks
2:35 am
Yeah, I’m having the same problem. If it’s a 404 or a search page with no result it breaks and lists all the pages.
5:42 pm
Did anyone figure this one out?
6:33 am
I know this is some time ago but thought I’d just share my answer to this.
If you modify the line:
if ($children) { ?>
to be:
if ($children && is_page()) { ?>
it seems to work. Hope that helps.
2:28 am
Thanks for this great plugin. Facing the same problem as Liam Dempsey. Any idea how this can be solved? Additionally, possible to make the subpage appear on hover?
Thanks
8:55 am
Hi, i know this is going to sound stupid, but where in the template do i place the above php? Thanks for your help.
2:42 pm
In the header.php I suppose
8:23 am
Keep up the good work mate :)
thanks .
12:56 am
my blog theme has the header script looking like this
<meta http-equiv=”Content-Type” content=”; charset=” />
» Blog Archive
<meta name=”generator” content=”WordPress ” />
<link rel=”stylesheet” href=”" type=”text/css” media=”screen” />
<link rel=”alternate” type=”application/rss+xml” title=” RSS Feed” href=”" />
<link rel=”pingback” href=”" />
<body >
<a href=”/”>
<a href=”/”>Home
not sure what to change.
12:58 am
what do i change in the below code to get this to work.
<meta http-equiv=”Content-Type” content=”; charset=” />
» Blog Archive
<meta name=”generator” content=”WordPress ” />
<link rel=”stylesheet” href=”" type=”text/css” media=”screen” />
<link rel=”alternate” type=”application/rss+xml” title=” RSS Feed” href=”" />
<link rel=”pingback” href=”" />
<body >
<a href=”/”>
11:24 am
Hi, great tutorial –
was just wondering how you managed to get it so that the dividing rule between links on your secondary navigation is omitted after the final link (in this case ‘Locations’)?
Thanks!
7:53 pm
Where do I put this code?
Thanks,
Ben
1:46 pm
Thanks for the php etc.. installed and worked first time…
was wondering how to have a third tier???
4:13 pm
Great sharing of code, thanks so much. I made one little addition because my pages were no longer showing in the correct order. I changed this code…
…to this…
Hope that helps others:)
3:32 pm
i was wondering …is there a way to get your code to put image for the right end and left end and middle ? I could not figure out how to get it to look that way with images.. .or where to put that in the CSS.
this is what i am trying to do ..thanks
http://www.cg-hq.com/navbar.jpg
4:16 pm
…uh, the code tags appear to not be working as expected….let’s try again…
I changed this…
(‘title_li=&depth=1′);
to this…
(‘sort_column=menu_order&title_li=&depth=1′);
4:50 pm
Great post, Darren! You just helped me out of a jam. Thank you!
3:11 am
Can the same menu effect be achieved with categories, maybe using get_category_parents?
What I would like to achieve is a menu style similar to the JoomlaPanel menu at http://joomlapanel.com/, but with categories rather than pages.
6:29 am
I can’t seem to make it work. It doesnt become 2-tier but 1-tier where the subpage link appeared next to the parent page.
I have this code in the header.php .
<a href="" title="" id="home">Home
Where do I modify to become the 2-tier code?
Thanks for any help. Your response greatly appreciated.
6:31 am
<a href="" title="" id="home">Home
6:32 am
The code doesnt appear in my comment here: Try again.
<a href=”" title=”" id=”home”>Home
1:18 am
great article, thx for your tips!
9:47 pm
Hey -
Loved this tutorial…and it works perfectly! However, when I tested it in different browsers (ie – Safari) the parent page didn’t stay highlighted. Any ideas?
Thanks!
11:52 am
Really nice tutorial to implement navigational menus just like a full blown CMS. If used correctly with proper CSS, no one find the site is based on wordpress. I was thinking about switching to joomla just for this type of navigation. But it is not a blog engine. So I hesitated. Today I found this post. I’m already started changing my blog navigation. I know it can be done, but going thru all wodepress codex and API will be highly time consuming for a seasonal developer like me.
3:34 am
how to keep from listing child pages of index page?
5:51 pm
Nice code, thanks :)
is there a way to center the text in the bar? have tryed different types of code in the css but no luck.
Regards
12:28 am
thank u
3:57 pm
Hey Darren,
Is it possible to create a two-tiered navigational menu in wordpress where the parent is a page and the children are specific categories?
Thanks.
3:30 pm
That was too easy. Thanks!!
5:42 pm
This worked very nicely for me – thanks for sharing!
10:43 am
This is fantastic. Works awesome for what I was trying to emulate.
Quick question. My “parent” links are in the header, while my “child” links are in the sidebar. Works fantastic. My one question was if there is a way to get the “parent” link also in the sidebar so that if they want to get back to the parent page they don’t have to click on the links in the header. Does that make sense?
Here is the site I am working on.
http://ccsf.calvaryprescott.com
10:51 am
I’m releasing a project (“framework”, I guess) in the next couple weeks that includes nav code that also pulls the parent link with the rest of the sidenav. Stay tuned.
3:06 pm
Darren,
Did you release this project? Working on something that it is more crucial on, hoping that you posted it and I missed it. Thanks.
Jonah
3:51 am
Let’s say I’m trying to make this work with Mimbo 3.0… what exactly should I NOT change to maintain the built-in dropdown menu?
2:29 am
Thanks so much for this, super simple to understand and a cinch to implement. I really appreciate it!
5:40 am
Great post, thanks so much, just what I’ve been looking for
4:27 pm
D~
Thanx for increasing my understanding of how to initiate navigation for child pages.
I did not code character for character but used only those parts for the result I wanted.
Your tut was very helpful.
~DT
3:32 pm
It simply doesnt work for me. I have copied and pasted the code exactly and am getting duplication of the parent pages in both tiers of the navigation. Any Ideas?
2:48 am
Superb thinking of giving it a try soon. found it at the right time.
6:25 am
Good!!! But for the categories ????
We can to see the code for the categories,please
Thank you
9:53 am
hi
great menu system — just one query — how do you CENTER the top and submenu items in the horizontal list rather than being left aligned?
also – instead of a background colour used to highlight the selected parent link – -how do you use a colour for the link text instead which stays with that same colour even if a child link is selected?
thanks
phil
2:41 am
Hi,
Can you help me how the create the same menu for category & sub category……
Regards,
SaiSat
7:51 pm
Thanks for the tutorial. It seems like this type of navigation is becoming pretty common on various websites and blogs.
3:53 am
thx for this, but it seems like the subnav breaks for me. Cant see why :S
What year was this tut posted?
5:03 pm
i am wondering if you have some tips for drop down thesis nav bar too? i am searching it from past few days ..dint find any single easy post
1:10 pm
Hi,
Currently there are ( “current background color” and “current parent background color” ) that works with Thesis 1.8 menu and WP-menu(3.x) for the top level Tabs, That’s all.
For my test site (http://pierrecote.fondationcem.org/) I have achived that using the ” WordPress nav menu ” and 6 lines of CSS.
First (1) level highlighting ( white ). Second (2) level highlighting ( yellow ). Third (3) level highlighting ( orange )
1 – Highlighting the ( top categories Tabs ) while on a “single post” of my top categories.
.current-post-ancestor a {background: #FFFFFF;border-bottom-color:#FFFFFF;}
2a – Highlighting the ( subcategories ) while on a “single post” of my child/subcategories.
.sub-menu .current-post-ancestor a {background:#F0EEC2;}
2b – Highlighting the ( parents and child/subcategories ) while on a child/subcategories. ( need to define a category for the appropriate posts )
.cat_galerie-2010 .current-menu-parent a {background:#F0EEC2;}
.cat_galerie_2011 .current-menu-parent a {background:#F0EEC2;}
3 – Highlighting the ( parents and child/subcategories ) while on a “single post” of my child/subcategories. ( need to define a “CSS Class” (post edit) for the appropriate posts ) – here I target a “CSS Class” and it’s appropriate menu-item created by WordPress )
.postgalerie2010 .menu-item-776 a {background:#FFD596;}
.postgalerie2011 .menu-item-785 a {background:#FFD596;}
This does not play well with IE.
Thesis generates ” cat-item-X “, “children”, “current-cat”, “current-cat-parent”, but I could not achived anything with those, and, anyway I wanted to organise my pages/categories my way.
Pierre
3:01 pm
Nice, that’s the simplest way of doing it I have seen so far.
1:17 pm
Thank you thank you thank you! I was struggling for about an hour thinking about how to do this sub-navigation and your article was perfect. Thank you!
2:38 am
Thanks This helped me
5:29 pm
Just wondering if anyone ever found out how to resolve the issue with the menu being duplicated when you make a search for something that is not on the site. Any help would be appreciated.
J
4:48 am
Thanks for this tip. I’ll have to try this later
4:44 am
This is great menu for a PHP, not a manually customized java. Thanks for the input.
8:09 am
Ooh thanks for this post, the php has helped me no end!
9:34 pm
Maybe a solution to the problem that Liam Dempsey asked about.
Change the code at line 8 from
if ($children) { ?>
to
if ($children && !is_404()) { ?>
Seems to work fine for me now.
Cheers
9:43 pm
Thanks, that works great for 404 pages. How do you do that for empty search results as well?
5:39 pm
Hi I’m having the same problem, Search pages are duplicating the menu items. Some help on this would be great…
Thanks
6:06 pm
Just figured it out.
replace the line with
if ($children&is_search()&is_404()) { ?>
Matt
6:52 pm
Hi :)
I’ve got a problem with this method :P
If i write a news thread on my “test_a” category i doesn’t see the “test_a” category same with the thread on my “navi” i’ve got just the “home” option in category
//
i got 3 category to try :
1.Home
2.test_a with two sub category : test_a1 and test_a2 with a small text
3.test_b with two sub category : test_b1 and test_b2 with a small text
do u know this problem ? :)
12:20 pm
thank you man! bright solution
3:27 am
Thanks for this – very helpful in making the site that much more refined :)
6:39 pm
Creating Two-Tiered Conditional Navigation in WordPress was a very helpful post. I’ m wondering if there is a way to do this with categories? I know how to get the top level parent categories the top row, but I’m unsure how I might have only child pages show in the second line – if there are child pages as you’ve done for pages here.
7:30 am
Hi,
@sophie i tried this code for “Categories” and it seems to work.
<?php
$current_category = single_cat_title("", false);
$category_id = get_cat_ID($current_category);
if(is_category($current_category))
{$children = wp_list_categories("title_li=&child_of=".$category_id."&echo=0");}
//else {$children = wp_list_categories("title_li=&child_of=".$category_id."&echo=0");}
if ($children && !is_404()) {
if($children!="No categories”){
?>
Thanks for this wonderful post :)
Ravi
1:26 am
Has anyone found a working solution for this with categories rather than pages?
6:42 pm
Very useful resource, thanks for sharing. Im trying to create a bespoke menu system on a wordpress platform, this will definatley set me on the right track, Thanks!
12:35 am
Thanks for this little bit of golden code. I have it working almost perfectly… with one exception.
I’m using along with the “a page of posts” template found here:
http://codex.wordpress.org/Pages#A_Page_of_Posts
This allowed me to filter out posts based on a “category” field that was assigned in the custom fields of the page. In short, I can assign posts to a specific category, and those post will only show up a pages that also have the same category assigned.
All works well, until you click on a single post, then the navigation defaults back to home. It there anyway to have the nav stick to the categories that the post is assigned to?
Thanks…
5:01 pm
Great article Darren,
Just wondering is there going to be any update on how to create a 3 tier dynamic navigation?
Cheers,
10:18 am
Thanks for the great work! Helped me alot to solve that problem quickly!
4:03 am
A long time ago, say 2005 I integrated a WordPress blog into my existing hand coded site which had tabs along the top. At the time WordPress was 1.something and I created my own theme that left the static navigation at the top, there are only three sections with 3 to 5 subsections but there are lots of sub-pages after that. I created my blog at blog.muschamp.ca and have been updating it for five years now. I recently upgraded to WordPress 3.0.1 and then while looking around at tips and what not found your site. How much work do you think it would be to convert all my static site to be inside WordPress now that it is a more full featured CMS?
Secondly how bad would the redirects be from blog.muschamp.ca/everything… to whatever the new URL would be, I guess I’d have to move my installation. It seems like too much work, but I’m glad you through this example up. I also have another subdomain or two further complicating my life.
Cheers,
PS Everything is easier starting fresh, my own site and theme give nothing but headaches… Currently BirdFeeder has busted my feeds again…
3:35 am
What a f**kin ledgend! This works like a charm!
9:00 am
Great tutorial and method!
Any chance of telling us how to apply this to a vertical nav where subpages appear below each parent page – I have applied the above method but the subpages appear below the entire menu…. tried tinkering with php but with no luck
Any help would be HUGELY appreciated….
10:40 am
Hi Darren,
Brilliant tute. I’m wondering if theres an easier way to do the above, as I think i’m already using a script similar to the one above, but have added an exclude statement to not have certain pages in the dropdown.
Without continually going into the code everytime a new page is created, is there a way that an unexperienced person can exclude pages?
i’m soon to hand over the project on completion and want to know if the client can do this…
I look forward to your response. Thanks!
1:06 am
Super easy, thanks. I was trying to figure out how to do this with WP’s new menu…old school is sometimes better.
2:59 pm
If I want the Homebutton to be a part of the menu as well, any ideas?
11:37 pm
@Mangew
you can try this
<a href="” title=”">Home
wp_list_categorie(‘&title_li’);
11:39 pm
sorry the tags got stripped
check here:
http://codex.wordpress.org/Function_Reference/bloginfo
see the example for “Show Blog Title in Link”
4:25 am
Thanks, worked just fine! The only problem is that the home link wont be set as current page when. Do you know?
5:15 am
its answered here.
you can add ¤t_cat=1 to the wp_list_categories arguments
it might work.
If there is still highlighting problems you can refer here:
http://wordpress.org/support/topic/wp_list_categories-highlight-current-category-when-viewing-single-post
3:54 am
Beautiful, I’m totally new to this and it worked easily!
12:03 pm
hi Darren
I was wondering how to point a TOP LEVEL nav item to a SUB MENU page? the two tier system is working great but I would like to have TOP level buttons which when clicked go to the 1st of the CHILD pages that are associatd with thta particular Top Button.
So the Top Button has no active page of it’s own – it merely points to the first Child Page — how do I do that?
thanks
Phil
1:59 pm
Edited to get a thrid tier.
post_parent;
$parent = get_post($parent_id);
if($post->post_parent){
if($parent->post_parent){
$child = wp_list_pages(“depth=1&title_li&child_of=”.$parent->post_parent.”&echo=0″);
$child2 = wp_list_pages(“depth=1&title_li&child_of=”.$parent->ID.”&echo=0″);
} else {
$child = wp_list_pages(“depth=1&title_li&child_of=”.$parent_id.”&echo=0″);
$child2 = wp_list_pages(“depth=1&title_li&child_of=”.$post->ID.”&echo=0″);
}
} else {
$child = wp_list_pages(“depth=1&title_li&child_of=”.$post->ID.”&echo=0″);
}
if($child){
echo “”.$child.”";
}
if($child2){
echo “”.$child2.”";
}
?>
2:00 pm
sorry bad copy&paste
$parent_id = $post->post_parent;
$parent = get_post($parent_id);
if($post->post_parent){
if($parent->post_parent){
$child = wp_list_pages(“depth=1&title_li&child_of=”.$parent->post_parent.”&echo=0″);
$child2 = wp_list_pages(“depth=1&title_li&child_of=”.$parent->ID.”&echo=0″);
} else {
$child = wp_list_pages(“depth=1&title_li&child_of=”.$parent_id.”&echo=0″);
$child2 = wp_list_pages(“depth=1&title_li&child_of=”.$post->ID.”&echo=0″);
}
} else {
$child = wp_list_pages(“depth=1&title_li&child_of=”.$post->ID.”&echo=0″);
}
if($child){
echo “”.$child.”";
}
if($child2){
echo “”.$child2.”";
}
9:46 pm
Where does this code go into?
I am new to wp and php (have sufficient html and css experience).
does it replace the original two tier code, come after it or something in between?
tried various variation..none worked. (the code was showing on the site and the menu was still working as 2 tier).
regardless, thanks for both the original and the edited version.
6:11 pm
First off, I am loving this code! Works perfectly.
I noticed in the other comments someone else mentioned this and I didn’t know if there was a workaround to showing the subnav when you hover over the main page link. Works for me right now but I have this strong, strong feeling the client will want it to display on hover.
Thanks ahead of time for any help!
5:47 am
Dear,
I followed exactly your code but I don’t know why I could not do it.
Please kindly advise me.
Regards
3:28 pm
Is there any way to make the parent page show up in the navbar only as link text, but without there being a link?
ie, in your example, say if I wanted “about us” to show on the menu, but not be “clickable” as a link?
9:38 pm
Thanks so much! I installed it and it worked like a charm. Great suggestion!
5:17 pm
This is exactly what I would like to do. Forgive me, but where do I edit the php?
Thanks,
J
7:26 am
WOW !!! After 5 hours of massive struggles this finally worked!! YAY!!! :D
2:20 pm
Hi. Which CSS command is that for defining the colour of the dropdown menu- mine also has a strange feather effect I’d like to get rid of, but if possible I don’t want to replace the whole Nav CSS with this one, because I’d have to go through it all recoding all the colour.
3:24 pm
This rocked the perfect amount of rocking that I needed. Thanks.
5:12 pm
Good Morning All There
Thanks very excellent work, but i have a problem for you genius guys and laddeis i am using custom menu on my WP site and this script is not working with custom menu i want the same result for my web site navigation menu please can you provide me the exact script to achive this.
Thanks
2:43 pm
Is it possible to show only “child level 2″?
As it is now my “child level 3″ also shows and I don´t want it. How can I fix it?
Thanks for a nice solution!
Thomas
10:10 pm
Is it possible to position the sub nav “centered” underneath the top level / parent menu. I am looking at a main menu which has a left margin of around 300px, so I have room here to position the sub menu underneath each top level item. Thanks, great tut.