Get Ancestor featured image

I’ve been trying to get the ancestors post ID to show its featured image on all sub pages, but I can only ever get combinations that work as top level and sub page, never a third page down.

The setup is currently:

Page 1

  • Sub Page 1
  • Sub Page 2
    • Sub Sub Page 1

I want the featured image on Page 1 to display on page 1, sub pages and sub sub pages.

This one is straight out of the codex which says:

global $post;
$parents = get_post_ancestors( $post->ID );
/* Get the ID of the 'top most' Page if not return current page ID */
$id = ($parents) ? $parents[count($parents)-1]: $post->ID;
if(has_post_thumbnail( $id )) {
    get_the_post_thumbnail( $id, 'thumbnail');
}

But like all my other attempts it’s only working with a direct parent (e.g Page 1 and Sub Pages, never Sub Sub Pages).

How can I get a third level page pick up the ancestors featured image?

1 Answer
1

Given this hierarchy:

  • Page 1
    • Page 2
      • Page 3
        • Page 4

This line, where $post represents Page 4:

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

Will return 3 IDs, for these pages, in this order:

  1. Page 3
  2. Page 2
  3. Page 1

So this line:

$id = ($parents) ? $parents[count($parents)-1]: $post->ID;

Is the equivalent of:

$id = ($parents) ? $parents[2]: $post->ID;

Which means that it will only check whether page 1 has a post thumbnail. It will ignore pages 2 & 3. Because array indexes start at 0, count($parents)-1 means that $id will always be the last item in the list, which will be the top-level page.

What you want to do is loop through $parents, from immediate parent, to grandparent, to great grandparent, until a thumbnail is found. Then break the loop and return the thumbnail:

$thumbnail=""; // We will replace this if/when we find a thumbnail.
$parents   = get_post_ancestors( null ); // null will get the current post.

foreach ( $parents as $post_id ) { // Loop through parent pages.
    if ( has_post_thumbnail( $post_id ) ) { // Check if this ancestor has a thumbnail.
        $thumbnail = get_the_post_thumbnail( $id, 'thumbnail' ); // If it does, get it...
        break; // ...then stop looping.
    }
}

echo $thumbnail;

The problem with this code is that if the current page has a thumbnail, it won’t get displayed, because we’re only looping through parents. The simplest way to get around this is to add the current page ID to the list of IDs we’re looping through:

$thumbnail=""; // We will replace this if/when we find a thumbnail.
$parents   = get_post_ancestors( null ); // null will get the current post.

array_unshift( $parents, get_the_ID() ); // Add the current page to the list of pages we're checking.

foreach ( $parents as $post_id ) { // Loop through parent pages.
    if ( has_post_thumbnail( $post_id ) ) { // Check if this ancestor has a thumbnail.
        $thumbnail = get_the_post_thumbnail( $id, 'thumbnail' ); // If it does, get it...
        break; // ...then stop looping.
    }
}

echo $thumbnail;

Leave a Comment