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