Using the first image in a WordPress post as featured image

Advertisement:

I am a hobby photographer and I like to show and share my “work”. WordPress introduced the “featured image”-feature in version 2.9 (as “post thumbnail“) which is fine for displaying an image that is somehow hooked to an article or blog post, or even a page.

Post Thumbnail, now Featured Image, is an image that is chosen as the representative image for Posts, Pages or Custom Post Types. The display of this image is up to the theme. This is especially useful for “magazine-style” themes where each post has an image.

So the featured image does a pretty fine job in showing pictures instead of or in addition to a blog post – but the way it is been displayed depends on your chosen theme. Many WordPress themes that are made for hobby or professional photographers like me, have a so-called “portfolio category”. A category that only shows the featured image of blog posts and maybe their (post-) title. Usually, these portfolio categories also work with a custom post type, the image-post. So all posts that are of the “image post”-type and that are in the specified portfolio-category will be shown on this specially designed portfolio page (see my portfolio page).

The rather uncomfortable situation is that you would have to upload a picture to your WordPress media library and relate it to a post. For me, this is pretty unconvenient, since I usually upload my pictures to Flickr and want to use them from there or I post my images from Instagram automatically to my WordPress blog (there’s anĀ app plugin for that). But you can’t set a featured image for a blog post, which is not in the media library. And this is, where default portfolio pages and my habit to use Flickr or Instagram as image repository have a little conflict. So I use a function (actually, it’s two of them) as a workaround. These functions have a pretty simple job:

  1. get the first image of a post
  2. if there is no featured image connected, use the first image of the post instead

The get the first image function

This function was a little bit tricky to declare, since it checks the DOM of the corresponding post. When posting an image from Flickr, I usually hove at least two images in the blog post: one is the image itself, the other is the Creative-Commons-Logo that I attribute my images with. Also when using an Instagram picture, I’ll have a little link at the bottom that directs to my Instagram profile which is also an image.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
if ( ! function_exists( 'get_first_image' ) ) :
function get_first_image() {
     $document = new DOMDocument();
     $content = apply_filters( 'the_content', get_the_content( '', true ) );
     if( '' != $content ) {
          libxml_use_internal_errors( true );
          $document->loadHTML( $content );
          libxml_clear_errors();
          $images = $document->getElementsByTagName( 'img' );
          $document = new DOMDocument();
          $images_amount = ($images->length);
          if( $images->length ) {
               $image= $images->item( $images->length - $images_amount );
               $src = $image->getAttribute( 'src' );
               $width = ( $image->hasAttribute( 'width' ) ? $image->getAttribute( 'width' ) : false );
               $height = ( $image->hasAttribute( 'height' ) ? $image->getAttribute( 'height' ) : false );
               return array( $src, $width, $height );
          }
     }
     return false;
}
endif;

This function finds all images from the post, chooses the first image from that post and returns its source(-URI), its height and its width.

The set the featured-image function

Well, actually this function does not set the featured image, because that can only be done with editing the blog post or page or with manipulating the database – although I doubt that you could set a featured image with an alien domain, but I never tried! It rather checks the possibilities, if the blog post has a featurd image and if not, which one to use instead.

27
28
29
30
if ( ! function_exists( 'first_post_image' ) ) :
function first_post_image() {
     if( has_post_thumbnail() ) : ?>
          <?php the_post_thumbnail(); ?>

Pretty easy case: If the current post has a thumbnail (aka featured image), use it! You could wrap the <?php the_post_thumbnail(); ?>-line to fit it you needs. Maybe you would want to have the thumbnail in a div with a certain CSS-class, or wrap it in <figure></figure>-tags. The the_post_thumbnail(); returns only the <img>-HTML-tag with the featured image.

31
32
33
34
35
36
37
38
39
40
41
42
43
44
     <?php else :
          $args = array(
               'numberposts' => 1,
               'post_type' => 'attachment',
               'post_mime_type' => 'image',
               'post_parent' => get_the_ID()
          );
          $attachments = get_posts( $args );
          if( count( $attachments ) ) {
               $attachment = $attachments[0];
               if( isset( $attachment ) && ! post_password_required() ) :
                    $image = wp_get_attachment_image_src( $attachment->ID, 'full' ); ?>
                              <?php echo wp_get_attachment_image( $attachment->ID, 'image-thumb' ); ?>
               <?php endif;

This part of the function checks, if there is an image as attachment to the current post. You could attach multiple images to your blog post without setting any of them as you featured image. But you would need to attach an image first to set it as featured image. So maybe you just forgot – this part of the function will do that for you. Here you can modify the output of the image too, if you wrap some custom HTML around <?php echo wp_get_attachment_image( $attachment->ID, 'image-thumb' ); ?>.

46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
          } elseif( false !== get_first_image() ) {
               if( ! post_password_required() ) :
                    $image = get_first_image();
                    if( false === $image[1] )
                         $image[1] = 525;
                    if( false === $image[2] )
                         $image[2] = 394;
                    $attachment = get_post( get_the_ID() ); ?>
                              <img src="<?php echo $image[0]; ?>" alt="<?php the_title_attribute(); ?>" width="<?php echo $image[1]; ?>" height="<?php echo $image[2]; ?>" />
               <?php endif;
          } else {
               the_content();
          }
     endif;
}
endif;

This is the “if all other things didn’t work”-section of the function. It gets the first image from the post and returns its <img>-HTML tag.

Both functions together need to be placed in your functions.php-file of your current WordPress theme.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
if ( ! function_exists( 'get_first_image' ) ) :
/**
* Show the first image inserted in the current postimage
**/
function get_first_image() {
     $document = new DOMDocument();
     $content = apply_filters( 'the_content', get_the_content( '', true ) );
     if( '' != $content ) {
          libxml_use_internal_errors( true );
          $document->loadHTML( $content );
          libxml_clear_errors();
          $images = $document->getElementsByTagName( 'img' );
          $document = new DOMDocument();
          $images_amount = ($images->length);
          if( $images->length ) {
               $image= $images->item( $images->length - $images_amount );
               $src = $image->getAttribute( 'src' );
               $width = ( $image->hasAttribute( 'width' ) ? $image->getAttribute( 'width' ) : false );
               $height = ( $image->hasAttribute( 'height' ) ? $image->getAttribute( 'height' ) : false );
               return array( $src, $width, $height );
          }
     }
     return false;
}
endif;
 
if ( ! function_exists( 'first_post_image' ) ) :
/**
* Show the last image attached to the current post
*
* Used in image post formats
* Images attached to image posts should not appear in the post's content
* to avoid duplicate display of the same content
*
* @uses get_posts() To retrieve attached image
*
*/
function first_post_image() {
     if( has_post_thumbnail() ) : ?>
          <?php the_post_thumbnail(); ?> // you would possibly need some attributes here for size
     <?php else :
          // Retrieve the last image attached to the post
          $args = array(
               'numberposts' => 1,
               'post_type' => 'attachment',
               'post_mime_type' => 'image',
               'post_parent' => get_the_ID()
          );
          $attachments = get_posts( $args );
          if( count( $attachments ) ) {
               $attachment = $attachments[0];
               if( isset( $attachment ) && ! post_password_required() ) :
                    $image = wp_get_attachment_image_src( $attachment->ID, 'full' ); ?>
                              <?php echo wp_get_attachment_image( $attachment->ID, 'image-thumb' ); ?> // you would possibly need some attribute other than 'image-thumb' here for size
               <?php endif;
          } elseif( false !== get_first_image() ) {
               if( ! post_password_required() ) :
                    $image = get_first_image();
                    if( false === $image[1] )
                         $image[1] = 525;
                    if( false === $image[2] )
                         $image[2] = 394;
                    $attachment = get_post( get_the_ID() ); ?>
                              <img src="<?php echo $image[0]; ?>" alt="<?php the_title_attribute(); ?>" width="<?php echo $image[1]; ?>" height="<?php echo $image[2]; ?>" />
               <?php endif;
          } else {
               the_content();
          }
     endif;
}
endif;

What you would have to do now is replace all corresponding functions in your template files with first_post_image();. So maybe in your content-image.php-template file, there is this place where the theme wants to retrieve the featured image of the current post (search for get_post_thumbnail, the_post_thumbnail or has_post_thumbnail). You would have to replace that function with first_post_image();. But you should check if there’s not already a function with the same name in your functions.php first. If that’s the case, rename first_post_image() to whatever you want and call the function with its new name from your template files.

What you need to be aware of

If you have a single post-view that shows the featured image, you will end up with two identical images. One is the “fake” featured image (that is used from within the content) and one image is the image in the content itself. I am still working on that, but haven’t found a proper solution yet. If so, I eventually would have found a way to use an image from outside the WordPress media libraby as a featured image.

Also you should really think about wanting to display a featured image for all posts when using the function in your template-file. I think there would need to be exceptions from the rule. So maybe you would want to use the first_post_image() in a kind of conditional if-then-clause, e.g. “If the post format is image, then use first_post_image(), else use the featured image (if there is any)“. That would display “standard”-format posts without a feature image (but with images inside the blog post) just as they are now. Then you would still have the decision to have a featured image or not.

If you have any suggestions on improving the functions or any questions, feel free to use the comments section.

Like this post? Share it!
Advertisement:

2 thoughts on “Using the first image in a WordPress post as featured image

Leave a Reply

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

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>