get_post_ancestors()WP 2.5.0

Retrieve ancestors of a post.

Uses: get_post()
Used By: get_ancestors()
1 time — 0.001242 sec (very slow) | 50000 times — 0.33 sec (very fast) | PHP 7.2.5, WP 5.0.1

No Hooks.

Return

Int[]. Array of ancestor IDs or empty array if there are none.

Usage

get_post_ancestors( $post );
$post(int|WP_Post) (required)
Post ID or post object.

Examples

0

#1 Demonstration

Suppose page 30 is a child of 20, and 20 is a child of 10. That is, 10 is the top-level page and the order from top to bottom of the tree is 10 > 20 > 30.

Then:

$ancestors = get_post_ancestors( 30 );

/* Returns

Array
(
	[0] => 20
	[1] => 10
)
*/
0

#2 Display the header of the parent page itself

Let the structure of our pages be like this:

Page 1 (ID=611)
	- Page 1-1 (ID=613)
		- Page 1-1-1 (ID=615)
			- Page 1-1-1-1 (ID=617)
Page 2 (ID=712)
	- Page 2-1 (ID=755)
	- Page 2-2 (ID=781)

Get the header of the parent page itself:

// get an array with the id of all parents (pass the ID Page 1-1-1-1)
$ids = get_post_ancestors( 617 );

/* Returns

Array
(
	[0] => 615
	[1] => 613
	[2] => 611
)
*/

// take the last ID from the array - this is the ID of the topmost page
$id  = array_pop( $ids );

// Print the title of this page
echo get_the_title( $id ); // print Page 1
0

#3 Check if there is a child page

We have a nested structure of static pages and we need to check if ID 34 is the parent of page 12:

$ancestors = get_post_ancestors( 12 );
if( in_array( 34, $ancestors ) )
	echo 'post 34 is parent to 12';
else
	echo 'post 34 is not the parent of post 12';
0

#4 Get the top level page thumbnail

And display it:

<?php
global $post;

$parents = get_post_ancestors( $post );
$id = $post->ID;

// Get the ID of the 'top most' Page
if ( ! empty( $parents ) ) {
	$id = array_pop( $parents );
}

if ( has_post_thumbnail( $id ) ) {
	echo get_the_post_thumbnail( $id, 'thumbnail' );
}
?>

Changelog

Since 2.5.0 Introduced.

Code of get_post_ancestors() WP 6.0.1

function get_post_ancestors( $post ) {
	$post = get_post( $post );

	if ( ! $post || empty( $post->post_parent ) || $post->post_parent == $post->ID ) {
		return array();
	}

	$ancestors = array();

	$id          = $post->post_parent;
	$ancestors[] = $id;

	while ( $ancestor = get_post( $id ) ) {
		// Loop detection: If the ancestor has been seen before, break.
		if ( empty( $ancestor->post_parent ) || ( $ancestor->post_parent == $post->ID ) || in_array( $ancestor->post_parent, $ancestors, true ) ) {
			break;
		}

		$id          = $ancestor->post_parent;
		$ancestors[] = $id;
	}

	return $ancestors;
}