Featured Image Inherited from Parent Page

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 Comment