Darfuria
Darfuria

Reputation:

WordPress - list multi-level parent pages when on a 3rd level child page

I'm working on a website at the moment, and the navigation works as follows (by client specification).

Underneath the header there is a horizontal navigation listing the top level pages, clicking on one of these takes you to page.php, which has a vertical navigation in the sidebar listing the sub-pages of that particular page like this:

2nd level - 3rd level - 3rd level - 3rd level 2nd level - 3rd level - 3rd level - 3rd level

and so on, and so on.

This is the code I am currently using in the vertical navigation:

$children = wp_list_pages('title_li=&child_of='.$post->ID.'&echo=0');
if ($children)
{
    <ul>
        echo $children;
    </ul>
}

What I would like to be able to do is continue to have the same vertical navigation, regardless of the current page level. I'm finding it hard to list the sub-pages of a 1st level page when you're on a 3rd level page.

Any suggestions greatly appreciated.

Upvotes: 2

Views: 7710

Answers (3)

Tom Auger
Tom Auger

Reputation: 20101

Once you're inside The Loop, it's very easy to pull up a reverse history of all page ancestors.

<?php
    // It's not necessary to globalize $post if you're doing this inside your page.php
    // but if you're in, say, sidebar.php, then you need to declare the global variable
    global $post;

    // We have to reverse the array so the top link is the topmost ancestor
    $history = array_reverse( array_map( 'get_post', get_post_ancestors( $post ) ) );

    // And if you want to add this page to the list as well, push it onto the end
    $history[] = $post;
?>

<ol>
<?php
    // Now, loop through each page in the list
    foreach( $history as $page ){
         echo "<li><a href='" . get_permalink( $page->ID ) . "' />" . get_the_title( $page ) . '</a>';
    }
?>
</ol>

The key line of course is $history = array_reverse( array_map( 'get_post', get_post_ancestors( $post ) ) ); This does two things:

  1. It maps the IDs returned by get_post_ancestors() to actual WP_Post objects (which, isn't strictly necessary, since all we really need are IDs to pass to get_permalink() and get_the_title())
  2. It reverses the array order, since get_post_ancestors() puts the immediate parent at the top of the list, and we probably want it at the bottom.

Upvotes: 0

rbncha
rbncha

Reputation: 922

I think this can be of your help. I had same issue. I had to show up parent page's layout stuffs (everything) in child page.

add_action('wp_head', 'init_stuffs');
function init_stuffs(){
  if( is_page() ){
    $parents = get_ancestors(get_the_id(), 'page');
    if( count( (array) $parents ) >= 2 ){
      //now you can use $parents[1] as parent
      registry()->setParentPageId($parents[1]);
    }
  }
}

In my case I had to load blurbs of parents. I used Wordpress Registry plugin to store $parents[1] id. Then I fetched the blurbs of parents by simply passing parent page id in the function where blurbs data are fetched.

function fetchBlurbs($parentId = null){
  if(is_null($parentId)){
    //fetch blurb for the page
  }else{
    //fetch blurb of parent page
  }
}

Upvotes: 0

Kevinleary.net
Kevinleary.net

Reputation: 9670

Try using get_post_ancestors. This approach seemed to work for me in a similar situation:

<?php
global $wp_query;
$post = $wp_query->post;
$ancestors = get_post_ancestors($post);
if( empty($post->post_parent) ) {
    $parent = $post->ID;
} else {
    $parent = end($ancestors);
} 
if(wp_list_pages("title_li=&child_of=$parent&echo=0" )) { ?>

<ul id="secondary-nav">
    <?php wp_list_pages("title_li=&child_of=$parent&depth=1" ); ?>
</ul><!-- #secondary-nav -->

<?php } ?>

Then I used this to target the current nav states with CSS:

#secondary-nav li a:hover,
#secondary-nav li.current_page_item a,
#secondary-nav li.current_page_ancestor a {
    background:#fcb701;
}

You'll probably need to remove the depth parameters to show you're 3rd level pages.

I hope this helps!

Upvotes: 3

Related Questions