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) { ?>
<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?
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.
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:)