WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I found this very useful code at the wp codex, it basically lists out the parent, child and grandchild pages, I'm using it in my sidebar and it works well for the parent and children pages, but when you go to a grandchild page, the menu changes and it now only shows the child/grandchild, instead of the same menu on the parent & child pages. how can i make it show the same on all the pages?

Also i'd like the parent title to be an actual link rather than just text and I can't seem to figure that out. help is greatly appreciated!!

                if($post->post_parent) {
                $children = wp_list_pages("title_li=&child_of=".$post->post_parent."&echo=0");
                $titlenamer = get_the_title($post->post_parent) ;

                else {
                $children = wp_list_pages("title_li=&child_of=".$post->ID."&echo=0");
                $titlenamer = get_the_title($post->ID);
                if ($children) { ?>

                <h2> <?php echo $titlenamer; ?> </h2>
                <?php echo $children; ?>
            <?php } ?>
share|improve this question


This is a plugin I created and usually use for this type of functionality. The key is the little function down at the bottom of the file that searches for the top-level ancestor. There's also part of the code that will print out categories instead of pages when you're on a blog or search page; you can turn it off by commenting out line 43.

It will display as many levels of page hierarchy as you care to make, and it will always display the top-level parent page levels.

You can install it by downloading the file, adding it to your plugins folder, and activating. If you want to use it in your code rather than a widget area, you can do something like this:

$nav = new DTW_Navigation_Widget;

The pertinent part of the widget is this:

// Somewhere in your functions file
/** Find the top-level parent of this post */
function my_get_ancestor_id($post) {
    if ( $post->post_parent ) {
        $ancestors = get_post_ancestors($post->ID);
        $root = count($ancestors)-1;
        $parent = get_post($ancestors[$root]);
    } else {
        $parent = $post;
    return $parent->ID;

and this:

// Also in your functions file
/** Find the top-level parent of this post */
function related_pages() {
    // Where are we?
    global $post;
    $parent_id = my_get_ancestor_id($post);
    $title = get_the_title($parent_id);
    $link =  get_permalink($parent_id); 
    $title = "<a href='$link' title='$title'>$title</a>";

    if (  !empty($parent_id)  ) {
        $args = array(
            'title_li' => '',
            'child_of' => $parent_id,
            'echo' => 0,
            'sort_column' => 'menu_order'
        $nav = wp_list_pages($args);
    // Let's hide this if there aren't any sub-pages or sibling pages... it tends to break.
    if ( !empty($nav) ) {
        echo "<ul id=\"sidebar-subnav\">" . $nav  . "</ul>";

Then wherever you want to get a list of sub-pages/sibling pages: <?php related_pages(); ?>

share|improve this answer
thanks but i'd rather not use a plugin for this, i would like to learn the functionality and put it right in the code. thank you though. – jamie Oct 10 '12 at 21:12
No problem. That plugin has the solution in it, if you care to deconstruct it and just use the parts you need. I'll post a more complete answer with just those parts. – guiniveretoo Oct 12 '12 at 2:35
cool I'll take a look at it, because I'm still looking for a solution :) – jamie Oct 17 '12 at 18:20

The reason behavior changes is because that code only checks for immediate parent. So it doesn't go looking for parent of a child.

To go through whole hierarchy you would need to retrieve and process it with get_post_ancestors().

share|improve this answer
can you explain a little further how i would alter this existing code to use get_post_ancestors() please? – jamie Oct 10 '12 at 21:12
up vote 0 down vote accepted

I finally figured this out. I didn't want it to show up at all on pages without children, so the first if statement checks and only displays the menu if the parent has children. This menu stays the same whether you are on the parent, child, or grandchild page. :)

<?php if (  has_children() ) { //makes menu title only show up on pages with descendents ?> 

                    <?php if ( 0 == $post->post_parent ) { //sets parent page title ?>
                            <div class="widget">
                                <h2><?php the_title(); ?></h2>
                    <?php } else { //puts topmost parent page title
                        $parents = get_post_ancestors( $post->ID );
                        echo '
                            <div class="widget">
                                <h2>' . apply_filters( "the_title", get_the_title( end ( $parents ) ) ) . '</h2>';


                <?php } ?>

                <?php //shows children & grandchildren of page no matter what level you're on
                    // will display the subpages of this top level page
                     $children = wp_list_pages("title_li=&child_of=".$post->ID."&echo=0");
                 } else {

                    if($post->ancestors) {

                        $ancestors = end($post->ancestors);
                        $children = wp_list_pages("title_li=&child_of=".$ancestors."&echo=0");

                if ($children) { ?>
                        <?php echo $children; ?>
                <?php echo '</div></li>'; } ?>
share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.