Until the release of WordPress 3.0 due out later in the year, creating a sub navigation is still a somewhat obscure and tricky task. To hopefully shed some light on how to create a Sub Navigation for your own needs I am going to walk-through how you can output a pages child or sub pages. In simple terms how to display a second level navigation in your sidebar.
How to get Sub Pages
In WordPress the easiest way to get the a page’s child pages is to use the get_pages function. This function allows you to specify that you want the children of a page by using the child_of and parent parameters. When called this function returns an array that you can utilize to iterate over and output the child pages.
$child_pages = get_pages('child_of='. $post->ID; . '&parent=' . $post->ID;);
The $post variable is used in WordPress templates to denote the current post or page. We utilize the ID property to specify we want returned all pages that are children of the current page.
How to output the pages in a list
To output a list of the sub pages we can iterate over the children and output the page titles and links in a list by using the get_page_link function and the ID and post_title properties of the returned Page object.
echo '<ul class="subNav">';
foreach( $child_pages as $c_page ) {
echo '<li><a href="' . get_page_link($c_page->ID) . '">' . $c_page->post_title . '</a></li>';
}
echo '</ul>';
The full example
Using the above code we will be executing the code on all website pages including posts and categories. To limit the execution to only pages we can utilize the is_page function. As we want to display the secondary navigation when we are on the parent page or child page we will need to check the current page to determine if we are on a root page or child page by using the post_parent property. Using this we can determine if we need to get the children of the current page or the children of the page’s parent. Doing so allows us to consistently output a Sub Page Navigation as can be seen here.
if( is_page() ) {
$the_ID = $post->ID;
$i_page = $post;
if( $post->post_parent ) {
$the_ID = $post->post_parent;
$i_page = get_page($the_ID);
}
$child_pages = get_pages('child_of='. $the_ID . '&parent=' . $the_ID);
if( count($child_pages) > 0 ) {
echo '<li class="widget"><h2><a href="' . get_page_link($the_ID) . '">' . $i_page->post_title . '</a></h2><ul>';
foreach( $child_pages as $c_page ) {
echo '<li><a href="' . get_page_link($c_page->ID) . '">' . $c_page->post_title . '</a></li>';
}
echo '</ul></li>';
}
}
get_page, get_pages, How To, is_page, Tutorial, Wordpress
In addition to using the wp_get_archives function to display archives, WordPress provides a multitude of other functions that you can use to suit your navigational needs. Two similar functions that come to mind are get_posts and get_pages. The get_posts function returns all the posts that match your criteria while get_pages returns pages.
To illustrate how these 2 functions work lets do a couple basic examples.
Example 1: Showing a Recent Posts links limited to a category
For this example lets assume we have a movie review website that posts reviews as well as news and updates on upcoming releases. In this site we have decided we want to display the user with an archive containing the 5 most recent movie reviews we published. To accomplish this task we would use the get_posts page with the category__in and number_posts parameters. We can specify in the category__in parameter the Movie Review category and set the number of posts to 5 in number_posts. The code would look similar to:
<h2 class="recentposts"><?php _e('Recent Reviews'); ?></h2>
<ul class="nav">
<?php
$reviews = get_posts( array('category__in' => array(60), 'numberposts' => 5 ) );
foreach($reviews as $review): ?>
<li><a title="<? echo $review->post_title; ?>" href="<?php echo get_permalink( $review->ID ); ?>"><? echo $review->post_title; ?></a></li>
<?php endforeach; ?>
</ul>
Example 2: Segregating your pages into a main nav and footer nav
With a website you typically have multiple navigation elements the most common being a main navigation on the left or top of your site and a footer (utility) nav on the bottom of the site. To manage the content that appears in these navs you can use the get_pages function to include/exclude content. Lets assume our site has 3 pages we want to display in the footer but not the main nav then we could exclude them from the main nav by:
<div id="navbar">
<ul>
<?php
$pages = get_pages('exclude=5,19,20');
foreach ($pages as $pageInstance) {
$link = '<li><a href="'.get_page_link($pageInstance->ID).'" target="_self">';
$link .= $pageInstance->post_title;
$link .= '</a></li>';
echo $link;
}
?>
</ul>
</div>
And include them in the footer nav by:
<?php
$pages = get_pages('include=5,19,20');
foreach ($pages as $pageInstance) {
?>
|
<?php
$link = '<a href="'.get_page_link($pageInstance->ID).'" target="_self">';
$link .= $pageInstance->post_title;
$link .= '</a>';
echo $link;
}
?>
These are two basic examples of what you can do with the get_pages and get_posts functions. To see a full listing of the options you can pass to them check out the WordPress Codex.
Resources
custom archive, custom navigation, get_pages, get_posts, Tips & Tricks, Wordpress