Often when working with pages in WordPress you’ll need to get the ID of the very top parent in a hierarchy of pages. This could be useful for many reasons, but I run into the need most often when I need to list out multiple levels of children pages on the sidebar for a given section of pages.
When you are on a parent page life is easy because listing its children pages on a sidebar is simple as this:
<ul>
<?php wp_list_pages("child_of={$post->ID}&title_li="); ?>
</ul>
*In this case “child_of={$post->ID}” simply means get all children pages of the current page.
Now that’s great, but when you navigate to one of those child pages, or even worse a third-level child page, you’ll quickly realize that “$post->ID”, no longer refers to the very top parent, but to the page you are on and therefore the function doesn’t work as intended.
The solution is actually pretty simple. Instead of using the current page ID as a parameter in wp_list_pages(), you simply create a new function to always return the very top parent page ID and use that.
Here’s a very simple function that will accomplish that. Drop this in your functions.php file..
function get_top_parent_page_id() {
global $post;
$ancestors = $post->ancestors;
// Check if page is a child page (any level)
if ($ancestors) {
// Grab the ID of top-level page from the tree
return end($ancestors);
} else {
// Page is the top level, so use it's own id
return $post->ID;
}
}
And then update your code in your template to look like this…
<?php $parent_page = get_top_parent_page_id($post->ID); ?>
<ul>
<?php wp_list_pages("child_of=$parent_page&title_li="); ?>
</ul>
Thanks for this not-so-obvious trick, took me a while to google it out.
Best,
Jordan
Works great; very useful. Thanks so much!
Thank you for this simple, yet effective trick. Just what I was looking for!
this is a very good post.
thanks.
The “$id” parameter is useless since it’s using the global $post variable… change the top of the function to look like this:
function get_top_parent_page_id() {
global $post;
or this:
function get_top_parent_page_id($id) {
$post = get_post($id);
I fail to see why you’re passing the page id in as a parameter if you’re not using it. Is this a typo, or is there something magical happening here?
Thanks Dallon and Andy…was a typo. Has been fixed.
hey , it worked perfectly for me..
Thanks a lot…
_thank you_
Perfect! Thanks so much for posting this.
2 years later still very useful. Thanks a lot!
In WP 3.5, I received an error notice in row 9, but if you replace the:
return end($post->ancestors);with
return end( get_post_ancestors($post) );it works. At least for me.
Here is an explanation and an additional solution. A prettier updating of the function for WP 3.5:
http://wordpress.org/support/topic/new-error-notice-for-wp_postancestors-in-35
@Rammarera…thanks for pointing that out! I’ve updated the code with the provided fix so it doesn’t throw error notices for WP 3.5.