WordPress How To – Show Child Pages Only

I’ve recently finished my new re-design for my main site, and am now converting it over to a WordPress theme. It occurred to me that one of the snippets of code I’m using might just help someone else also.

For my new theme, I needed to get only the child pages of a current page to display in my sidebar. However, I also wanted those child pages to show, regardless of whether or not I was actually ON a child page also.

An example hierarchy might work like this:

  1. About (Parent Page #2)
    1. My City (Child Page #8)
    2. My Bio (Child Page #4)
    3. My Photos (Child Page #3)

Now the tricky part is that it involves a few things there aren’t quick WordPress tags for.

  1. I want to list all the child pages in my sidebar.
  2. I want the child pages to show even while on another child page of the same parent page.
  3. And I want to control the display order through the admin menu order tool, not have it be alphabetically ascending.

So, first I need to find a way to display the child pages persistently, while on a child page or a parent page of the same section. So, I want to see those same sidebar links whether I’m browsing the main ‘About’ page, or reading the ‘My Bio’ page.

To achieve that first part, you need to use this little snippet of code that can be found on the WordPress codex:

<?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>
<?php echo $children; ?>
</ul>
<?php } ?>

Copy and paste that where your child pages should display.

So now the child pages are showing persistently, whether browsing on the parent page or one of the child pages (and they change if the parent page changes). But now, I need to deal with the order.

I want to be able to control the order through the admin screen without having to mess with the template, but I do not want it to have to be alphabetical. You can reset the order of any page by going to your WP-Admin and doing the following:
Manage -> Pages -> Edit (the page you want to change) -> Page Order (change the number)

When you change the Page Order value, you move the page to a different spot in your page list. Say you have 18 pages, and you want your page 2 at the top to be at the bottom, you could change the page order to 19. In any event, you can see the exact page order when you look at the Page management screen.

So, that’s how I want to control those child pages, but this snippet of code will default them to their current order.

I need to add one small change to fix that.
(Edit: Fixed a small error in not putting the sort_column on both lines.)

<?php
if($post->post_parent)
$children = wp_list_pages("sort_column=menu_order&title_li=&child_of=".$post->post_parent."&echo=0"); else
$children = wp_list_pages("sort_column=menu_order&title_li=&child_of=".$post->ID."&echo=0");
if ($children) { ?>
<ul>
<?php echo $children; ?>
</ul>
<?php } ?>

The underlined portion should be added, and now it is controlled by however I order it in the menu.

Hope it helps someone!

~Nicole

32 Replies to “WordPress How To – Show Child Pages Only”

  1. Finally I can ditch the useless plugins and the extra bloaty sidebars I created for parent page templates I made. Thank you for this :o)

  2. @Larry:

    I’m glad you have it working, and there is definitely an easy way you can fix the problem going on.

    In the code I posted, you can find these lines here at the bottom:

    [some code above that must stay]
    <ul>
    <?php echo $children; ?>
    </ul>
    <?php } ?>

    You can add to that section of the code there if you like. So, in your case (and I hope you don’t mind me using your code as an example), you could put this instead:

    [the code above that must stay]
    <li id="Child Links">
    <h2>Additional Links</h2>
    <ul>
    <?php echo $children; ?>
    </ul>
    </li>
    <?php } ?>

    That should now only show that section if the check to see if there were child pages proved true, or if it is a child page.

    Hope that solves it for you 🙂

  3. I have that line in the code already. I guess I don’t understand what should be changed. Here is the code I have, so where should the change be made?

    Additional Links

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

  4. @Larry:

    The only problem is that the part of your code that creates the ‘additional links’ heading is actually happening before it checks to see if it has child pages or is a child page.

    So, full working example for your site would be moving it down to where the section header happens after the check, like this:

    <?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) { ?>
    <li id="Child Links">
    <h2>Additional Links</h2>
    <ul>
    <?php echo $children; ?>
    </ul>
    </li>
    <?php } ?>

    Let me know if that works for ya 🙂

  5. Awesome, thanks very much for this, its exactly what I was needing as I’m using wordpress to do a ‘feature’ section and this obviously gets updated and has its own sidebar layout and wanted each new feature to just automatically jump in there.

    Perfect!

  6. I just cannot get this to work right. I’m working on a site for a community space where our partners who rent office space want to have areas of the website for their use. I experimented with all kinds of plugins and code snippets from the codex, but I must be missing something.

    Right now I’m trying to get the area up and running for the Sustainable Health Choices group. That address is here: http://gsohive.org/partners/sustainablehealth. The code snippet above just outputs the child links for the “Partners” page, not the “Sustainable Health Choices” (SHC) page. The map looks like this:

    Top
    -Partners
    –Sustainable Health Choices
    —Child Pages

    What am I doing wrong or just missing that is outputting the child links of the Partners page on the SHC page INSTEAD of the child pages for the SHC? Thanks in advance for the help!

  7. hi – here’s hoping you can help with this one…i’ve been digging for days and can’t find the answer!

    I’m using your snippet of code to show child pages on my site at http://blog.hernandoluxuryhomes.com . If you are on the home page, you can see there are several child pages (Featured Listings, Mission Statement, Etc). On the Featured Listings page, I have it pulling from a different template because i want a loop to show on that page but not on the others…but when i have it working with a different template, it loses it’s parent page and thus loses it’s child menu…. any help??? I’m completely stumped!

    Thanks,

    Josh

  8. Do you know how to solve this problem:
    Website Hierarchy:
    Home
    About Us
    Services
    – Food
    – Sports
    — Football
    — Soccer
    – Sleeping
    Contact Us

    I used your code above, but when I go to the, say Soccer, page, I only have Soccer displayed in my navigation. But when I am at Sports page, I have Food, Sports (with child pages), and Sleeping displayed (this is what I want).

    So what happens is that when I am on a third level child page (Soccer) only that link is displayed. How can I have it so all links at the 2nd Level (Food, Sports (with child pages), Sleeping) be displayed?

    Thanks

  9. This is a great startingpoint, however if you have subpages of subpages, then the menu does not display correctly anymore. To work around this one should place something like this to get the top item:

    while ( $postParent = $post->post_parent ) {
    $getChildrenOf = $postParent;
    }
    $children = wp_list_pages("title_li=&child_of=".$getChildrenOf."&echo=0");

    Do not know if this is valid PHP (I am a perl and python hacker), but something like this should get a Submenu for all subpages and subsubpages …

  10. @Patrick

    At a glance, that code looks like it should work. If someone wants to check it, feel free to leave notes on that here. It’s definitely a good idea to grab the parent in a variable so you can have access to it easily.

  11. this is not working for me, does postParent need to initially be defined?
    If possible can you include full code?

    thanks!

  12. Hello Nicole.

    Thank you for posting such an easy and non-plugin-needed way to add this to your sidebar. Wow!

    I searched the whole net for almost 2 days now, tried 5 different code ways and one plugin but all didn’t get me the result i wanted to have.

    Thank you again!

  13. Maybe I should clarify my question. The code is working beautifully in the sidebar on regular pages. However when I access a page using a template that includes post excerpts below the page content the menu disappears. Any clues how to fix this?

  14. John,

    Sounds like your special template page with the post excerpts has some other conditions it follows to make that page different. Or, perhaps your sidebar.php has a section in it that shows different content if it’s the sidebar of one of those special pages.

    Would really have to see the code for those to be able to tell.

  15. Thanks Nicole,

    Here is the code that’s pulling in the excerpts


    have_posts()) : $recent->the_post();?>
    ID, "thumb", true) ): ?>
    <a href="" rel="bookmark"><img style="float:left;margin:0px 10px 0px 0px;" src="/tools/timthumb.php?src=ID, "thumb", $single = true); ?>&h=&w=&zc=1" alt="" />

    <a href="">
    <a href="">Read more

  16. Thank you SO MUCH! I’ve been looking for a way to do this for hours, and this is absolutely perfect!

    One question: The children do show when their parent is clicked or when they themselves are clicked, but in the latter case, the menu is displayed twice. Any idea why that’s happening? I don’t know if I can include a link here, so I won’t try, but I’d be happy to send one if anyone can help.

    Thanks for a fabulous script!

  17. I’m a bit late to the party here, but here goes. Thanks SO much for this article, really helped a lot. I was wondering if you knew of a way to display the page titles as a list of numbers, as opposed to their titles?

    Thanks again!

  18. This bit of code is almost exactly what I need. But can anyone help with this? I have my top level pages which have children and those children have chldren. This code seems to show all 1st and second level child pages. I would like it to only display the 2nd level child pages of whatever child page I happen to be on and not the other child pages’ children. Also if I am on a top level page I would like its 1st level children displayed but with no 2nd level children.

    Does that make sense, brcause I think I’m confused now.

  19. Hi, thanks for this wonderful code. I impletement the code in one of my project and it work’s like the charm.

    I just wanted to know how do i get the title as the current page for example.

    post_parent)
    $children = wp_list_pages(“sort_column=menu_order&title_li=&child_of=”.$post->post_parent.”&echo=0″); else
    $children = wp_list_pages(“sort_column=menu_order&title_li=&child_of=”.$post->ID.”&echo=0″);
    if ($children) { ?>

    You see here ” ” I want the title to be the current page for parent page and parent page for child page.

    Thank you

  20. Sorry for the last post the code got chopped off.

    post_parent)
    $parent =
    $children = wp_list_pages("sort_column=menu_order&title_li=&child_of=".$post->post_parent."&echo=0"); else
    $children = wp_list_pages("sort_column=menu_order&title_li=&child_of=".$post->ID."&echo=0");
    if ($children) { ?>

    Here in this code I wanted the title to be current page for parent page and to be parent page for child page.

  21. Did anyone figure out how to use this code when you have child pages that go deeper than two levels deep?

    I tried to use the while loop presented by @Patrick, but unfortunately it isn’t working.

    Thanks a lot.

Comments are closed.