What I would like to do is have my parent page’s featured images display, unless a child page has its own featured image, then I would like that image to become the featured image from that page and the rest of its children pages.

-Page 1
-Page 2
  -Sub Page 1
  -Sub Page 2
    -Sub Sub Page 1 
    -Sub Sub Page 2

So in the example above:
Page 1 and Page 2 would have a featured image set that would display in the header.
Sub Page 1 would inherit Page 2 featured image.
Sub Page 2 would have its own featured image, which sub sub page 1 would inherit.
Sub Sub Page 2 would have its own featured image.

I have tried placing this code in my header, where the image needs to go and it did not draw in any featured images, it just brought in the image slider.:

<?php if ( has_post_thumbnail($post->post_parent, 'pagethumb') ) {
                 echo get_the_post_thumbnail($post->post_parent, 'pagethumb');
                 } else {
                 echo do_shortcode('			
				
					
There is nothing to show here!
Slider with alias header-slider-bw not found.
'); } ?>

I also tested to make sure the image was there and working with this code (and it was):

if ( has_post_thumbnail() ) {
the_post_thumbnail();
} 

Does any one have an advice on how to make this happen? I appreciate any help. Thanks in advance!

1 Answer
1

This is my proposal, combine get_ancestors and a custom $wpdb query, to retrieve featured images.

An example custom function:

function inherited_featured_image( $page = NULL ) {
  if ( is_numeric( $page ) ) {
    $page = get_post( $page );
  } elseif( is_null( $page ) ) {
    $page = isset( $GLOBALS['post'] ) ? $GLOBALS['post'] : NULL;
  }
  if ( ! $page instanceof WP_Post ) return false;
  // if we are here we have a valid post object to check,
  // get the ancestors
  $ancestors = get_ancestors( $page->ID, $page->post_type );
  if ( empty( $ancestors ) ) return false;
  // ancestors found, let's check if there are featured images for them
  global $wpdb;
  $metas = $wpdb->get_results(
    "SELECT post_id, meta_value
    FROM {$wpdb->postmeta}
    WHERE meta_key = '_thumbnail_id'
    AND post_id IN (" . implode( ',', $ancestors ) . ");"
  );
  if ( empty( $metas ) ) return false;
  // extract only post ids from meta values
  $post_ids = array_map( 'intval', wp_list_pluck( $metas, 'post_id' ) ); 
  // compare each ancestor and if return meta value for nearest ancestor 
  foreach ( $ancestors as $ancestor ) {
    if ( ( $i = array_search( $ancestor, $post_ids, TRUE ) ) !== FALSE ) {
      return $metas[$i]->meta_value;
    }
  }
  return false;
}

This function takes a page id, a page object or nothing when in single page template, and return the featured image of the nearest ancestor.

(To be honest it works for any hierarchical post type, not only for pages).

You can use it in single page template like so:

if ( has_post_thumbnail() ) {
  the_post_thumbnail( 'pagethumb' );
} else {
  $img = inherited_featured_image();
  if ( $img ) {
    echo wp_get_attachment_image( $img, 'pagethumb' );
  }
}

This should work, however it’s a bit poorly perforant because requires 2 database queries and some additional work. So, probably, can be a good idea to use the function in backend, and when a page is saved, check if a featured image exists, otherwise inherit it.

If then you want to change it you can, of course…

add_action( "save_post_page", "inherited_featured", 20, 2 );

function inherited_featured( $pageid, $page ) {
  if ( has_post_thumbnail( $pageid ) ) return;
  $img = inherited_featured_image();
  if ( $img ) {
     set_post_thumbnail( $page, $img );
  }
}

This one will work, of course, for new pages or for pages that you will update after having inserted it, so you can use both previous snippets: in this way existing pages will inherit thumbnail on the fly.

Leave a Reply

Your email address will not be published. Required fields are marked *