Automatically set fallback featured image

Here are various ways to add a featured image. I am showing examples with setting the same image for all featured images, taking the first image in the post content as featured, defining specific images for categories and more.

Below the code I will also be showing a plugin approach.

Marks code – add first image in content as featured.

DRAFT TUTORIAL – Code snippets are being retested/reworked.
–> This tutorial is kinda left hanging for now.

Link to: https://gitlab.com/WPezPlugins

Here are various ways to set a featured image. The PHP code is added to the child theme functions file or even better a code snippet plugin.

Set the same image for all featured images

I went to the Media Library found an image I wanted to use. Clicked it and copied the URL. Pasted much of the URL below into the code.

/**
 * Filters the post thumbnail HTML.
 *
 * @param string       $html              The post thumbnail HTML.
 * @param int          $post_id           The post ID.
 * @param string       $post_thumbnail_id The post thumbnail ID.
 * @param string|array $size              The post thumbnail size. Image size or array of width and height
 *                                        values (in that order). Default 'post-thumbnail'.
 * @param string       $attr              Query string of attributes.
 */
add_filter( 'post_thumbnail_html', 'wpse_post_thumbnail_html', 10, 5 );
function wpse_post_thumbnail_html( $html, $post_id, $post_thumbnail_id, $size, $attr ) {
    return '<img src="/wp-content/uploads/Sun-gradients.jpg" alt="Sun">';
}

I found the code here:
https://wordpress.stackexchange.com/questions/295247/automatically-set-the-featured-image

Set the first image in post as featured

Code works fairly well.

// https://wordpress.stackexchange.com/questions/283546/default-featured-image-from-post-content/283741#283741
function setfirstimage( $html ) {

    // If there is no post thumbnail,
    // Return a default image
    global $post;
    $pID = $post->ID;
    $thumb = 'large';
    $imgsrc = FALSE;
    if (has_post_thumbnail()) {
        $imgsrc = wp_get_attachment_image_src(get_post_thumbnail_id($pID),$thumb);
        $imgsrc = $imgsrc[0];
    } elseif ($postimages = get_children("post_parent=$pID&post_type=attachment&post_mime_type=image&numberposts=0")) {
        foreach($postimages as $postimage) {
            $imgsrc = wp_get_attachment_image_src($postimage->ID, $thumb);
            $imgsrc = $imgsrc[0];
        }
    } elseif (preg_match('/<img [^>]*src=["|\']([^"|\']+)/i', get_the_content(), $match) != FALSE) {
        $imgsrc = $match[1];
    }
    if($imgsrc) {
        $imgsrc = '<img src="'.$imgsrc.'" alt="'.get_the_title().'" class="summary-image" />';
        $html = $imgsrc;
    }

    if ( '' == $html ) {
        return '<img src="' . get_template_directory_uri() . 'https://wp-6.0.dev.cc/wp-content/uploads/stack-of-pebbles-graphic.jpg" />';
    }
    // Else, return the post thumbnail
    return $html;
}
add_filter( 'post_thumbnail_html', 'setfirstimage' );

I found the code here:
https://wordpress.stackexchange.com/questions/283546/default-featured-image-from-post-content/283741#283741

Set the first image in post as featured

Sometimes it works other times not.

// https://gist.github.com/Tsunamijaan/4408d0f4680efcb5c11b51efff71583d
function auto_featured_image() {
global $post;
  
if (!has_post_thumbnail($post->ID)) {
$attached_image = get_children( "post_parent=$post->ID&post_type=attachment&post_mime_type=image&numberposts=1" );
  
if ($attached_image) {
foreach ($attached_image as $attachment_id => $attachment) {
set_post_thumbnail($post->ID, $attachment_id);
}
}
}
}
// Use it temporary to generate all featured images
add_action('the_post', 'auto_featured_image');
// Used for new posts
add_action('save_post', 'auto_featured_image');
add_action('draft_to_publish', 'auto_featured_image');
add_action('new_to_publish', 'auto_featured_image');
add_action('pending_to_publish', 'auto_featured_image');
add_action('future_to_publish', 'auto_featured_image');

Resources.

https://gist.github.com/Tsunamijaan/4408d0f4680efcb5c11b51efff71583d
https://gist.github.com/joychetry/400bfd919cac4a2c03e807b7ab665abf

From Marks plugin.

Use the first image from the content as a featured image.
https://gitlab.com/-/snippets/2410647

Works.
One needs to edit a post and upon updating/resaving the first content image is automatically added into the featured image box. (Made for Gutenberg/Block editor.)

// https://developer.wordpress.org/reference/hooks/wp_after_insert_post/

add_action( 'wp_after_insert_post', 'my_fn_wp_after_insert_post', 100000, 4 );

function my_fn_wp_after_insert_post( $post_id, $post, $update, $post_before ) {
    
    // If it's a revision, don't continue.
    if ( 'revision' === $post->post_type ) {
		return;
	}

    // What post types do you want to ignore?
    // Example: $arr_blacklist = array( 'page' );
    $arr_blacklist = array();

    // If it's a post type to be ignored, don't continue.
    if ( in_array( $post->post_type, $arr_blacklist, true ) ) {
		return;
	}

    // https://developer.wordpress.org/reference/functions/get_post_thumbnail_id/
    $int_thumb_id = get_post_thumbnail_id( $post );
	
	// If the post already had a thumbnail, don't continue.
	if ( false !== $int_thumb_id && 0 !== $int_thumb_id ) {
		return;
	}

    // No featured image, let's try to fix that.
    $the_content = $post->post_content;

    // we're looking for an image block.
    $str_start = '<!-- wp:image ';
    $str_end   = '<!-- /wp:image -->';
    $int_start = strpos( $the_content, $str_start );
    $int_end   = strpos( $the_content, $str_end );

	// Did we find what we were looking for?
	if ( false !== $int_start && false !== $int_end ) {
        
        $str_first_image = substr( $the_content, $int_start + strlen( $str_start ), $int_end - ( $int_start + strlen( $str_start ) ) );

		// now get the json encoded string
		$int_end_2 = strpos( $str_first_image, ' -->' );
		if ( false !== $int_end_2 ) {

            // get the json encoded string from the img block. 
            $str_first_image_json = substr( $str_first_image, 0, $int_end_2 );
            
            // decode the json string.
            $arr_first_image = json_decode( $str_first_image_json, true );
					
            if ( isset( $arr_first_image['id'] ) ) {
				$int_thumb_id = (int) $arr_first_image['id'];
			}
		}
	}
    // Did we find an image in the content?
    if ( false !== int_thumb_id ) {
        set_post_thumbnail( $post, $int_thumb_id );
    }
	
}

Setting first image in post as featured and define categories to use specific images as featured.

I did a lot of searching online and came across an article from
https://wpsites.net/web-design/add-default-featured-image-for-each-post-in-a-category/

The below code that will do the following:
1. Sets the featured image.
2. If no featured image then look for category image.
3. If no category image set the first post image.
3. If no post image it will set a fallback image.

The attachment id
Since the code uses post-id/attachment id one needs to find the image data id. Go to the media library and right click the image you want to find the data id to. Select Inspect Element then look into the html code and you should notice the data-id number of the image. This is the number you need to use.

NB! The code related to getting the first image in a post and set it as featured is not working.

NB! This seems to be working for general post but not custom post types.

// Inside your functions file add the following code
// 
function wpforce_featured() {
          global $post;
          $already_has_thumb = has_post_thumbnail($post->ID); 

          // If post have a featured image use that.
          if (!$already_has_thumb)  {
              // If post does not have a featured image then get the first post image and set as featured image.
              $attached_image = get_children( "post_parent=$post->ID&post_type=attachment&post_mime_type=image&numberposts=1" ); 
// Number 1 relates to taking post image number 1 and adding it as a featured image.
                     if ($attached_image) {
                                foreach ($attached_image as $attachment_id => $attachment) {
                                set_post_thumbnail($post->ID, $attachment_id);
                                //$attachment_id = attachment_url_to_postid( $image_url );
                                //   echo $attachment_id;
                               
                                }
                           } else if ( in_category('WordPress') ){ 
                             // Add your own categories.
                             set_post_thumbnail($post->ID, '21'); 
                                
// Find attachment media id by right clicking the image in the Media library and selecting inspect element. Look for the data-id number. This number is then added to the post id. Or go into list view in the Media Library and hover the image. Notice the status area bottom left that mentions the image ID.
                           }
                           
                           else if ( in_category('test') ) {
                           set_post_thumbnail($post->ID, '30');
                           }
                           else if ( in_category('images') ) {
                           set_post_thumbnail($post->ID, '111');
                           }
                           else if ( in_category('Uncategorized') ) {
                           set_post_thumbnail($post->ID, '111');
                           }
                        }
      }  //end function
add_action('the_post', 'wpforce_featured');
add_action('save_post', 'wpforce_featured');
add_action('draft_to_publish', 'wpforce_featured');
add_action('new_to_publish', 'wpforce_featured');
add_action('pending_to_publish', 'wpforce_featured');
add_action('future_to_publish', 'wpforce_featured');

If you do not want to add the else if categories then adjust the first else if to:

} else {
 set_post_thumbnail($post->ID, '21'); // Find attachment media id by right clicking the image in the Media library and selecting inspect element. Look for the data-id number. This number is then added to the post id.
 }

Then remove each else if that follows.

From Marks plugin

Takes image IDs added to taxonomies and adds these as featured images.

// Did we find a thumbnail? If not, look by tax > term.
		if ( 0 === $int_thumb_id && true === apply_filters( __NAMESPACE__ . '\use_post_type_tax_flag', false, $int_thumb_id, $post ) ) {

			// return a associative array of pairs: cat_id => img_id.
			// TODO - build an admin UI to enter these?
			$arr_post_type_tax_term_img_ids = apply_filters( __NAMESPACE__ . '\post_type_tax_term_img_ids', array(), $post );

			if ( is_array( $arr_post_type_tax_term_img_ids ) && ! empty( $arr_post_type_tax_term_img_ids )
			&& isset( $arr_post_type_tax_term_img_ids[ $post->post_type ] ) && is_array( $arr_post_type_tax_term_img_ids[ $post->post_type] ) ) {

				$str_tax = key( $arr_post_type_tax_term_img_ids[ $post->post_type ] );

				// Get all the cats assigned to the post.
				$arr_terms = get_the_terms( $post, $str_tax );

				if ( is_array( $arr_terms ) ) {
					foreach ( $arr_terms as $wp_term ) {
						if ( isset( $arr_post_type_tax_term_img_ids[ $post->post_type ][ $str_tax ][ $wp_term->term_id ] ) ) {
							$int_thumb_id = (int) $arr_post_type_tax_term_img_ids[ $post->post_type ][ $str_tax ][ $wp_term->term_id ];
			// We found a thumbnail, so we're done.
							break;
						}
					}
				}
			}
		}

Set Youtube thumbnail as featured image when video is the first media in a post.

I have tried but these are not working:
https://wordpress.stackexchange.com/questions/25808/setting-a-posts-featured-image-from-an-embedded-youtube-video

A variation of the above.
https://wordpress.stackexchange.com/questions/73996/how-to-replace-youtube-videos-with-a-click-to-play-thumbnail
Scale up thumbnail: https://wordpress.stackexchange.com/questions/50649/how-to-scale-up-featured-post-thumbnail

Remove featured images.

To test out various code I also had to add a snippet to remove all featured images in between each test.
(I am not fully sure that I needed to do this, but it seemed to help.)

add_action ('init', 'remove_featured_images' );
function remove_featured_images () {
global $wpdb;
// The following query will only unset the featured image, it will not delete it. 
$wpdb->query( "
 DELETE FROM $wpdb->postmeta 
 WHERE meta_key = '_thumbnail_id'
" );
}

The above code came from a site that does not exist any longer.
https://spicemailer.com/wordpress/how-to-remove-featured-image-from-all-posts-wordpress/ 

The plugin approach

Coming up…

(Older) I also have a code for Genesis themes.  

(It seems to work better then the general featured image code above. I am looking into taking the Genesis featured images code and making it work for most themes in addition to Genesis themes.) This code looks for images through the url.

// GENESIS get featured image. 
// 1. Sets the featured image. 
// 2. If no featured image then get image from category. 
// 3. If no category image then get the first post image. 
// 4. If no post image or category image then set a fallback image.
// Add to your functions file.

// Resources
// https://wordpress.org/support/topic/make-first-image-in-post-featured-if-no-featured-is-set?replies=9
// http://wpsites.net/web-design/add-default-featured-image-for-each-post-in-a-category/
// https://codex.wordpress.org/Conditional_Tags


function get_src() {
  if ( has_post_thumbnail() ) {
	$src = wp_get_attachment_image_src( get_post_thumbnail_id(), 'thumb' );
	$fbimage = $src[0];
  } else {
	global $post, $posts;
	$fbimage = '';
	$output = preg_match_all('/<img.+src=[\'"]([^\'"]+)[\'"].*>/i',
	$post->post_content, $matches);
	$fbimage = $matches [1] [0];
  }
 
 if(empty($fbimage) && in_category('WordPress') ) {
    $fbimage = get_stylesheet_directory_uri().'/images/Leaves-white.jpg';
 }
 if(empty($fbimage) && in_category('images') ) {
    $fbimage = get_stylesheet_directory_uri().'/images/Tree-road-sun.jpg'; 	
 }
 if(empty($fbimage) && in_category('Uncategorized') ) {
    $fbimage = get_stylesheet_directory_uri().'/images/front-page-1.jpg'; 	
 }
 
 if(empty($fbimage)) {
 $fbimage = get_stylesheet_directory_uri().'/images/Red-back.jpg';
 /*$fbimage = site_url().'/wp-content/uploads/Red-back.jpg'; Works.
  $fbimage = site_url().'/images/Red-back.jpg'; Works
   $fbimage = CHILD_URL.'/images/Red-back.jpg'; Works - Genesis. But do not use CHILD_URL.*/
 }
 return $fbimage;
}
add_filter('genesis_get_image', 'default_image_fallback', 10, 2);
function default_image_fallback($output, $args) {
    return get_image();
}

function get_image($class="") {
    $src = get_src();
    ob_start()?>
    <a href="<?php echo get_permalink() ?>">
        <img class="featured-image <?php echo $class ?>" src="<?php echo $src ?>" alt="<?php echo get_the_title() ?>" />
    </a>
    <?php return ob_get_clean();
}

Removing the featured images

If you need to remove your featured images (I had to when I was testing the above featured images code to clear the cache in WordPress.)

add_action ('init', 'remove_featured_images' );
function remove_featured_images () {
global $wpdb;
// The following query will only unset the featured image, it will not delete it. 
$wpdb->query( "
 DELETE FROM $wpdb->postmeta 
 WHERE meta_key = '_thumbnail_id'
" );
}

Plugins

Default featured image plugin
Categories images plugin
Easy featured images plugin
wpmudev tutorial for easy featured images plugin

Additional resources to learn from:

https://www.sitepoint.com/how-to-add-featured-image-thumbnails-to-your-wordpress-theme/

wordpress.stackexchange
https://pastebin.com/34WFEMXd
https://github.com/devinsays/auto-set-featured-image/blob/master/auto-set-featured-image.php
https://paulund.co.uk/get-wordpress-image-id-by-url

I am working on figuring out how to set the URL/folder location of a fallback/default image instead of having to find the attachment image id. I will post the code for that when I have it.

The original tutorial was published 12 July 2016.

Share the article:

Leave a Reply

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