How to build sequential navigation in WordPress

What is exactly ’sequential navigation’? From the navigation point of view, imagine category which has ‘n’ number of sub-categories and each of these sub-categories may have ‘n’ number of sub-sub-categories…etc. From programmer’s point of view it’s a nested list whose list item may contain another nested list and so on. Personally, I’m not a fan of nested list, it makes the site ugly. Branched or multi-level drop-down menu is OK, however it keeps child categories/pages always hidden.

And here it comes sequential navigation as quite handy solution. I like to use it in conjunction with breadcrumbs so there’s no chance site visitor gets ‘lost’. As you know, in WordPress categories and pages can have ‘children’, up to 999 levels – as I recall – please correct me if I am wrong. Of course, you’ll never need so many navigation levels but I’m sure 3 are quite often.

Before showing the code, I would like to explain the logic behind sequential navigation. Here’s an illustration – just to show you what we are up to.
sequential_navig

Our goal is to display only the first level children of selected category, no matter how ‘deep’ we are.

Parent category (or page) will always be displayed as a title, indicating current menu set. Hopefully it does make sense to you. It doesn’t? Later you will be able to read how easily is to implement it into your own site…

The code

Code is well commented so there shouldn’t be a problem to understand the logic…


<?php
	// is there a page or category? both may have childeren
	if( is_category() ) {
		// if this category has childeren
		$categ_object = get_category( get_query_var( 'cat' ), false );
		$list_subcats = wp_list_categories( 'title_li=&depth=1&echo=0&child_of=' . (int)$categ_object->cat_ID );
		// wordpress never returns null or empty string. If children, <a> tag will be found, otherwise string is returned.
		preg_match_all( '|<a.*?href=[\'"](.*?)[\'"].*?>|i', $list_subcats, $m );
		if( !$m[ 1 ] ) {
			// there are no subcategories. Why?
			// this is either the last child or this category really doesn't have subcategories
			// last child must have a parent, right?
				if( (int)$categ_object->category_parent > 0 ) {
					// we'll need parent category name for the title, extract name via category ID
					$parent_cat_name = $wpdb->get_var( "SELECT name FROM $wpdb->terms WHERE term_id=" . (int)$categ_object->category_parent );
?>
					<div class="box">
					<h1><?php echo $parent_cat_name; ?></h1>
					<ul class="subnavigation">
					<?php wp_list_categories( 'title_li=&depth=1&child_of=' . (int)$categ_object->category_parent ); ?>
					</ul>
					</div>
<?php
				} // else...no else! This category really doesn't have child categories.
		} else {
			// ohoho! ...but here are some. List them all...
?>
			<div class="box">
			<h1><?php echo $categ_object->cat_name; ?></h1>
			<ul class="subnavigation">
			<?php wp_list_categories( 'title_li=&depth=1&child_of=' . (int)$categ_object->cat_ID ); ?>
			</ul>
			</div>
<?php
		}
	}
	// almost the same for page hierarchy.
	if( is_page() ) {
		// here we go...just do the same job
		$page_object = get_post( get_query_var( 'page' ), OBJECT );
		$list_subpages = wp_list_pages( 'title_li=&depth=1&echo=0&child_of=' . (int)$page_object->ID );
		// wordpress never returns null or empty string. If children, <a> tag will be found, otherwise string is returned.
		preg_match_all( '|<a.*?href=[\'"](.*?)[\'"].*?>|i', $list_subpages, $ms );
		if( !$ms[ 1 ] ) {
			if( (int)$page_object->post_parent > 0 ) {
				$parent_post_name = $wpdb->get_var( "SELECT post_title FROM $wpdb->posts WHERE ID=" . (int)$page_object->post_parent );
?>
				<div class="box">
				<h1><?php echo $parent_post_name; ?></h1>
				<ul class="subnavigation">
				<?php wp_list_pages( 'title_li=&depth=1&child_of=' . (int)$page_object->post_parent ); ?>
				</ul>
				</div>
<?php
			}
		} else {
?>
				<div class="box">
				<h1><?php echo $page_object->post_title; ?></h1>
				<ul class="subnavigation">
				<?php wp_list_pages( 'title_li=&depth=1&child_of=' . (int)$page_object->ID ); ?>
				</ul>
				</div>
<?php
		}
	}
?>

And this is it; save, and see how it works. You may want to replace style/class name for div in ‘navigation.php’ but this should be an easy part.

Share with others...

deliciousdiggreddittechnoratifacebooktwittergoogleyahoowikioblinklistsimpyspurl
Comments (3)

Track comments via RSS 2.0 feed. Feel free to post the comment, or trackback from your web site.

  • bas on Apr 29, 2010

    Thank u!

    I’ve been looking for this, soooo long :D

  • khanh on Jun 12, 2010

    Thanks, I’ve been searching forever for this, but perhaps because I always typed in “show subcategories” in google.

    There is one problem from keeping me from using the code though. When you click on a single post from one of the subcats, the subcategories disappear.

    Do you know to solve this?

    For example:
    http://aext.net/2010/05/quick-tip-highlight-current-category-menu-item-for-wordpress-single-post/

  • WordPressハッカーズ on Jun 13, 2010

    How to build sequential navigation in WordPress – tips and tricks…

    この記事は以下サイトに掲載されています。 This article has been featured on WordPressハッカーズ…

Leave a Comment

Latest comment by WordPressハッカーズ

How to build sequential navigation in WordPress - tips and tricks... この記事は以下サイトに掲載されています。 This article has been featured on WordPressハッカーズ...

Search

Advertisement

GraphicRiver ThemeForest