WordPress: Dynamic Sub-Page Navigation

Filed as Features, Guides on July 26, 2007 11:44 am

The more and more I study the WordPress architecture, the more and more convinced I become that WordPress is a great choice for use as a feature rich Content Management System (CMS). Basically, WordPress can be used, not only as a blog platform, but as software to manage the content of any website, with or without a blog. Because WP added the ability to use “Pages” to hold relatively static content, and because WP includes functions to call and display the content of those pages just about any way you can think of, all it takes is a good WordPress theme to get the job done.

But where WordPress lacks as a CMS is the ability to further exploit the sub-page system. Not so much in their use, but in their application to the actual website design.

However, this plugin did wonders for people looking to take advantage of the hierarchal structure of pages and sub-pages by allowing only the “parent” pages to be displayed on the homepage. And if a “parent” page has children, and that page’s link is clicked, then the child pages will “fold” down, displaying “deeper” options (much like the features of the more mainline CMS out there).

But There’s a Problem

I’m not here to just give props to a cool plugin. You see, I had a client who wanted the original “parent” list across the top of the page (just under the header image) and when one of the “parent” page links was clicked, he wanted the “sub-pages” to display as a list in the sidebar. As far as I could tell, there was no way to do that with the Fold Page List plugin. So, I went searching. I promise, if I could find the original website I got this from, I’d give a link. As it turns out, I can’t find it. Sorry :-)

First thing to do is just list your pages. Be sure to make it top-level only!

<?php wp_list_pages('title_li=&depth=1'); ?>

Then, I used the code I found (with a few modifications, I’m sure):

<?php
global $wp_query;

if( empty($wp_query->post->post_parent) ) {
$parent = $wp_query->post->ID;
} else {
$parent = $wp_query->post->post_parent;
} ?>
<?php if(wp_list_pages("title_li=&child_of=$parent&echo=0" )): ?>
<div id="submenu">
<ul>
<?php wp_list_pages("title_li=&child_of=$parent" ); ?>
</ul>
</div>
<?php endif; ?>

Without getting too technical, I’ll explain roughly what all that means.

if( empty($wp_query->post->post_parent) ) {
$parent = $wp_query->post->ID;
} else {
$parent = $wp_query->post->post_parent;
}

This code checks to see if the current page (the active page) as a parent. If it does NOT have a parent … it assigns the current page ID as the “parent”. If it DOES have a parent, it assigns the parent ID as the “parent”. The reason this is necessary is for top-level parents. If we simply used the parent ID to assign the “parent”, then if a top-level parent was active, the “parent” variable would be empty and we wouldn’t get our sub-page list.

<?php if(wp_list_pages("title_li=&child_of=$parent&echo=0" )): ?>
<div id="submenu">
<ul>
<?php wp_list_pages("title_li=&child_of=$parent" ); ?>
</ul>
</div>
<?php endif; ?>

This last part is pretty simple. All it checks for is IF there are any sub-pages (in a very rudimentary way). If it does have sub-pages, then it lists them (along with a title and some div wrappers for style).

One Limitation

I didn’t spend too much time doing research on this, but as far as I can tell, this only works 2 levels deep (top-level and 2nd level). If you have 3 levels of sub-pages, this won’t work (or at least won’t work like it’s supposed to). Sorry, but all I needed was 2 levels, so that’s all I developed it for :-)

Download the Source

Click Here to download the source for this script

So, if you are looking for a quick and dirty way to use WordPress as a CMS, this little bit of code can go a long way. I’ve used it several times since the time I developed it, and I plan on using it many times in the future!

Next week, I’m writing a tutorial on how to do the same thing we did here, but with categories and sub-categories. Don’t miss it!

Tags:

This post was written by

You can visit the for a short bio, more posts, and other information about the author.


Submissions & Subscriptions

Submit the post to Reddit, StumbleUpon, Digg or Del.icio.us.

Did you like it? Then subscribe to our RSS feed!



  1. By Jermayn Parker posted on July 27, 2007 at 12:56 am
    Want an avatar? Get a gravatar! • You can link to this comment

    That is great and what I need for an up and coming website using WP.

    I remember mentioning in a previous blog that this was one of the very few limitations for WordPress to become a fully top notch CMS system.

    Looks like my dreams have come true, thanks :D

    Reply

  2. By Michael Clark posted on July 27, 2007 at 9:28 am
    Want an avatar? Get a gravatar! • You can link to this comment

    I run a website on WordPress (ShowBizRadio.net), and tried using WP as the CMS. Unfortunately, after adding around 750 pages, WP couldn’t cope. The Manage Pages functionality bogged down. I had to raise my server’s memory limit for PHP. And adding new pages started taking longer and longer, to the point that the browser would timeout while working. So while I *love* the idea of using WP as a full CMS for pages plus blog posts, I don’t think it is there yet. Hopefully a few releases from now the memory management of the PAges system will be much improved.

    Reply

  3. By Jonathan Wold posted on August 1, 2007 at 5:33 pm
    Want an avatar? Get a gravatar! • You can link to this comment

    Your timing, my friend, is awesome :). A client of mine asked for the very same thing. With a little variation and experimentation, you saved me quite a bit of headache.

    Keep up the excellent work Mr. Rice,

    -Jonathan

    Reply

  4. By Michael Wender posted on August 9, 2007 at 2:09 pm
    Want an avatar? Get a gravatar! • You can link to this comment

    If I’m not mistaken, I believe the widget that I’ve written replicates the same functionality as your technique. Plus, my widget will display at least a page that is three levels below the main page (I have an example at my site).

    For those interested, you can check it out here:

    Subpages Widget

    Reply

  5. By Axel posted on August 16, 2007 at 10:33 am
    Want an avatar? Get a gravatar! • You can link to this comment

    Hi Nathan,

    sounds exactly like what I need. If I understand it right, it turns the menu-itmes of a top-level navigation in the header into a drop-downs. Is that right? I’m an absolute beginner with WP and I’m not sure where to put that could. Does that go into header.php?

    cheers, Axel

    Reply

  6. By Renzo B. posted on November 8, 2007 at 2:31 am
    Want an avatar? Get a gravatar! • You can link to this comment

    Grazie Nathan, (thanks)
    Dopo settimane (weeks) di prove e mal di testa (headache) questa è la soluzione a tutti i miei problemi (sounds exactly like what I need).

    Grazie. Renzo B,

    Reply

  7. By Sarah Lewis posted on November 28, 2007 at 11:59 am
    Want an avatar? Get a gravatar! • You can link to this comment

    Thanks, Nathan! This was exactly what I needed and it saved me a lot of trial and error. :)

    Reply

  8. By Nelson posted on February 26, 2008 at 1:17 am
    Want an avatar? Get a gravatar! • You can link to this comment

    Great post, one suggestion in case anyone is having problems with this not showing up with custom plugins, just precede the entire block with:

    rewind_posts();

    I’m new to WordPress, but I came across that pretty easily. Thanks again!

    Reply

  9. By Charity posted on April 16, 2008 at 10:00 am
    Want an avatar? Get a gravatar! • You can link to this comment

    I’ve been searching in vain for a way to do exactly what this article describes, and I found a snippet right in the WP codex for it. It’s very similar to the code you’re using Nate and in fact it looks great throughout the theme except for one caveat… it goes kaput if I load up a 404 page or an erroneous search results page (entering a term I know won’t produce any results). This is regardless of whether I try the script you posted or the one on the codex. Has anyone else actually tested this on those page templates by chance?

    I’m going nuts trying to figure out this bug. The templates I’m using are pretty much just like those of the default theme, and do nothing more than call the header as any other page would. Stands to reason if it works on every other page it would work on those two, but it isn’t for me… :(

    Reply

  10. By Yoris posted on May 7, 2008 at 1:53 pm
    Want an avatar? Get a gravatar! • You can link to this comment

    Charity,

    I found a partial solution to your problem on the wordpress support forums, http://wordpress.org/support/topic/169603

    Reply

  11. By Cliff posted on August 5, 2008 at 4:46 pm
    Want an avatar? Get a gravatar! • You can link to this comment

    This sounds like exactly what I am looking for, but how do I implement it? Where exactly do I place this code?

    Reply

  12. By Lorelle VanFossen posted on August 5, 2008 at 7:10 pm
    Want an avatar? Get a gravatar! • You can link to this comment

    The code goes into your page.php custom Page template file. If you are unfamiliar with PHP and WordPress template files, you should get help from the WordPress Support Forum and , the online manual for WordPress Users.

    Reply

  13. By Reino posted on September 13, 2008 at 4:08 am
    Want an avatar? Get a gravatar! • You can link to this comment

    This is a great way! Simple but effective, i’m searching for this for hours! There are a lot of plugins like this, but none of them are showing the subpages when your on a subpage. This one does! Thank you very much!

    Reply

  14. By Tien Hoang posted on December 7, 2008 at 9:08 pm
    Want an avatar? Get a gravatar! • You can link to this comment

    It’s great, I appreciate you help, Thanks you very much and more!

    Tien Hoang

    Reply

  15. By Rob Schumann posted on December 28, 2008 at 10:57 pm
    Want an avatar? Get a gravatar! • You can link to this comment

    Hi,

    I’m the author of the Fold Page List plugin mentioned in your article. The ability to determine a complete ancestral hierarchy for any page in the site has been included since the beginning, just not documented.

    There is though now a brief description of how the _wswwpx_page_get_ancestor_ids internal function may be used to obtain an ancestral array (of ids), and that this then provides you a means of building multi-layer page menus without any depth limitation within your wordpress site.

    The only proviso would be that you need to call Fold Page List once for each navigational menu you need to include… but that’s also true of wp_list_pages.

    Reply

  16. By Alistair posted on December 31, 2008 at 2:38 pm
    Want an avatar? Get a gravatar! • You can link to this comment

    I installed the plug in as above, a few days later I found this widget that works well for wp 2.7, saves adding any code, just install the plugin and add the widget to the sidebar…

    http://wordpress.org/extend/plugins/flexi-pages-widget/

    hth,
    Alistair

    Reply

  17. By i. posted on February 23, 2009 at 8:05 am
    Want an avatar? Get a gravatar! • You can link to this comment

    Thanks! Good Hint.

    Reply

  18. By Sam posted on February 25, 2009 at 2:20 pm
    Want an avatar? Get a gravatar! • You can link to this comment

    Where do I put this code?

    Reply

    • By Lorelle VanFossen posted on February 25, 2009 at 2:57 pm
      Want an avatar? Get a gravatar! • You can link to this comment

      You follow the instructions in the article and place the code where you want the navigation within the WordPress Theme, be it the header, sidebar, or footer template files.

      Reply

  19. By Sam posted on February 25, 2009 at 3:36 pm
    Want an avatar? Get a gravatar! • You can link to this comment

    Ok Thanks Lorelle..

    Reply

  20. WordPress: Dynamic Sub-Page Navigation | The Blog Herald « wp-popular.comJuly 2, 2009 at 7:03 am
  21. By G Srinivas Reddy posted on July 10, 2009 at 5:50 pm
    Want an avatar? Get a gravatar! • You can link to this comment

    Best script no need for plugin

    Reply

  22. By thesunz posted on July 26, 2009 at 1:27 am
    Want an avatar? Get a gravatar! • You can link to this comment

    nice plugins ! thanks for sharing…. i trying to use it on my site..

    Reply

  23. By Jacob posted on October 1, 2009 at 4:20 pm
    Want an avatar? Get a gravatar! • You can link to this comment

    BRILLIANT! Thanks a million!

    Reply

  24. By Jacob posted on October 1, 2009 at 4:26 pm
    Want an avatar? Get a gravatar! • You can link to this comment

    Yep..absolutely brillitant.. Thanks so much!

    Reply

  25. By exizt posted on October 20, 2009 at 7:08 am
    Want an avatar? Get a gravatar! • You can link to this comment

    Thank you very much for your post. It was very helpful, especially since there were no examples given on the plugin page.

    Reply

  26. By pantone204 posted on November 17, 2009 at 6:44 pm
    Want an avatar? Get a gravatar! • You can link to this comment

    Any idea how I could keep the other “main” links from showing? Once I drill down, I don’t want to see the other sections.

    Reply

  27. By Sebastian R. posted on January 21, 2010 at 3:21 pm
    Want an avatar? Get a gravatar! • You can link to this comment

    Thank you so much! I badly needed this for my first template in WordPress.

    Reply

  28. By gabrielle posted on September 27, 2010 at 9:12 pm
    Want an avatar? Get a gravatar! • You can link to this comment

    This was very helpful, thanks so much!

    Any idea on how to add an ‘active’ state to the menu??

    Reply

    Your words are your own, so be nice and helpful if you can. If this is the first time you're posting a comment, it might go into moderation. Don't worry, it's not lost, so there's no need to repost it! We accept clean XHTML in comments, but don't overdo it please.

    Current ye@r *