2

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

2

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;
1
  • 1
    That's a great answer Jacob, I appreciate the explanation, I understand it much better now.
    – Justin
    Commented Oct 4, 2019 at 7:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.