Subnav menu – adapt to show the same on parent, child & grandchildren pages?

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!!

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

Related posts

Leave a Reply

3 comments

  1. https://gist.github.com/3853924

    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;
    $nav->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(); ?>

  2. 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 ?>
                            <li>
                                <div class="widget">
                                    <h2><?php the_title(); ?></h2>
                        <?php } else { //puts topmost parent page title
                            $parents = get_post_ancestors( $post->ID );
                            echo '
                            <li>
                                <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
                    if(!$post->post_parent){
                        // 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) { ?>
                        <ul>
                            <?php echo $children; ?>
                        </ul>
                    <?php echo '</div></li>'; } ?>