Let’s say you wanted to use the post thumbnail feature of WordPress, but had a whole archive of posts that would take too much time to go through. For new posts, you can be specific and use the feature as intended. For old posts, you just want to use the first image it finds in the content for the thumbnail, or a default if none present.
Add this to functions.php or make a functionality plugin:
function catch_that_image() {
global $post, $posts;
$first_img = '';
ob_start();
ob_end_clean();
$output = preg_match_all('/<img.+?src=[\'"]([^\'"]+)[\'"].*?>/i', $post->post_content, $matches);
$first_img = $matches[1][0];
if(empty($first_img)) {
$first_img = "/path/to/default.png";
}
return $first_img;
}
To use it, use this code in the loop:
if ( get_the_post_thumbnail($post_id) != '' ) {
echo '<a href="'; the_permalink(); echo '" class="thumbnail-wrapper">';
the_post_thumbnail();
echo '</a>';
} else {
echo '<a href="'; the_permalink(); echo '" class="thumbnail-wrapper">';
echo '<img src="';
echo catch_that_image();
echo '" alt="" />';
echo '</a>';
}
I found that has_post_thumbnail wasn’t as reliable as the logic above.
Thanks for this. Always on the lookout to add functionality to WP.
Best,
Reece
Great function, I am trying to add youtube functionality to this but am a bit stuck.
I wanted it to grab the youtube thumbnail if it sees a youtube embed before it sees an image. Any ideas?
I’m not familiar with how to make things work in WordPress – – – but I included similar functionality in my Journal which I recently rewrote (hand coded – not WordPress). It is based on my use of the iFrame Video Embed for HTML5 compatability in my Journal – so won’t work with object and embed code. Hopefully you can use it and adapt it to your WordPress application in a similar way as above with the first image.
This video check code, comes after I have checked to see if there is an image in the content from a post (as I loop through). If it finds an iframe, it uses preg_match to extract the “src” of the iframe – and if there is a match to ‘www.youtube.com’ – I can create a url based on the video id that is extracted from the src url.
This is one of the pages that contains a couple of posts with Youtube video – where I got the Youtube images and display them – http://robertwatcher.com/journal/index.php?crnt=9
I have left out the extra if statements that check next for a Vimeo video url (which requries more complex code to extract) , as well as a default image if there is not a src url.
I have this in a page kind of like a small gallery but its limited due to:
Settings >> Reading >> Blog pages show at most
Is there a way around this to grab all images no matter what the limit is from settings?
I’ve been using the functions.php version of the code for a while now, but only recently discovered that this doesn’t seem to work for pages. Any chances there’s a way to make it apply to them as well?
Hi, i would like to ask what if i want to get the second image instead of the first one? Helps are much appreciated thanks
just change this
$matches[1][0];
to
$matches[1][1];
That’s a great piece of code, thanks for sharing.
I have a question though – if you were doing this from an attachment page (attachment.php) what would you change in the function to make it output correctly?
Thanks.
Paul.
How Can I change the image size?
You should use some css:
.thumbnail-wrapper img {width:300px;}
If you want it to resize with the page use something like:
.thumbnail-wrapper img {width:60%;}
Does anybody know how to get the first occurance of firstbigimage_big.jpg from:
Imgur
thanks
Thanks. Help my day.
Great tutorial. I would also like to know how to leverage this code to offer a dynamically sized image. It seems folks are using timthumb for this, I’m curious if there is a way to do it with core WP functions.
It’s mentioned above that CSS can be used, but that’s not a great approach if you need to resize an image more than a few pixels. The goal is to deliver the image in a new size similar to how get_the_post_thumbnail($post->ID, array(80,80)); works. Thanks!
I’d also love to know how to incorporate the built-in WP thumbnail sizes. Right now the code above pulls the image in it’s original dimensions, but I’d like it to crop a thumbnail using the dimensions I have specified in my functions.php.
Any ideas?
Dave,
You’d need to lookup the attachment ID using the URL then use that to get the image size you want:
http://frankiejarrett.com/get-an-attachment-id-by-url-in-wordpress/
Did you ever find out how to do this? Its something I am struggling with .
Here is the code I use to resize the first images:
GitHubGist — get-first-image.php
Thank you so much! I don’t know why after all this time, I just don’t check your page first when it comes to WordPress.
I’d love to know how to use this logic in a child theme. I’ve hacked my child theme’s content.php so far to enable excerpts in the loop, but I’d really like the excerpt to show the first image in the post as well. Not got into making plugins yet, so I was hoping there might be a way, either by modifying my child theme’s content.php and/or its functions.php (crosses fingers) ;)
OMG I did it! Thanks TONS for this code!!!
This code is gold! It picks up the image if it’s a featured image or not. Brilliant! Thank you!!!
This is a great snippet, thanks for posting it.
Just curious if anyone has successfully altered the function to return no IMG tag if no image is found instead of a placeholder? I’ve been tinkering with it but no joy, my PHP is rusty sadly.
Remove these two lines from the function:
if(empty($first_img)) {
$first_img = “/path/to/default.png”;
}
and then…
<?php
if ( $image = catch_that_image() )
echo '’;
?>
great! what would be the code in order to show the LATEST image attached to a post. best, flo
For some reason this always gets the last image in a post and not the first. Used as is with a few posts with about 2 images in each.
To get the first image instead of the last, replace /i with /U in the regular expression
@Barry – That’s strange – it’s taking the first image for me (i.e., the first image that appears in the post – the one nearest the top).
I’m inserting the code inside a duplicated content.php in a child theme, directly after:
… in its own div.
Seems to work for me.
Just one problem – it returns the first image for listings in the loop, but not for category listings
sorry – I meant, not for category listings where the first image is a featured image (I know I could get the first non-featured image, but I wondered if it could be tweaked to get the first featured image for category listings?
Ah – I worked it out – just to add:
|| is_category()
… to the conditional.
Duh!
Is there anyway we can display an image for Only First Post?
There’s a problem with the default image path when viewing category listings with pretty permalinks turned on – you get a broken image link because something like “images/default.jpg” is appended to the end of the permalink (e.g., “example.com/category/images/default.jpg”).]
Trying to think of a path to use that would cover all bases for that situation.
add a / before images. This way you’re doing a direct path from the root.
I tried the code; it did return the image …
p.s. I wrote my posts using windows live writer 2012 and embed Facebook photo link in live writer)
But I couldn’t get the returned image in thumbnail size… Also, the image appears on top of the posts on both the index and individual post.
That makes two images (one thumbnail and a duplicate one inside the post)..
. I’d like to get rid of the thumbnail when it’s in single post while only showing the thumbnail with float left on index page.
What can I do?
I am using my own child theme from twenty twelve …
Many thanks in advance…
Thanks! Works like a charm :)
This is how I handled it without regular expressions. I just put it in the template (in the loop of an archive page), but it wouldn’t be too hard to pull it into a function that could then be called in the template.
I actually got to this page because I was doing something similar to what you have.
I really liked that way, however get_children will only work if said image is only used in the current post. Or at least that’s where it was used first.
That’s because in the current WP version, post_parent has to be unique (an attachment can’t have multiple parents).
Solutions to this can however be obtained by hacking around with plugins that duplicate attachment entries in the database for each new post (see here).
Are you using any of those solutions?
Hi guys,
I am using a foundations theme and have followed the exact steps above. It works on the localhost (links to images in the right localhost path). The problem comes in on the live, the images path is that from the localhost:
http://localhost/MySite/wp-content/uploads/2013/06/corrupt.jpg
So basically it breaks. How to I turn the localhost url into a more dynamic one?
Perfectly Working! :) Many ThanX
I’m currently give up with the_post_thumbnail(); function at all and moving to use first_img instead from duplicate my work making thumbnail and inside post image ..
I’ve been using this function for a while, now noticing that I’m getting a php notice in my error log, PHP Notice: Undefined offset: 0. for this line:
$first_img = $matches [1] [0];
This post here: http://stackoverflow.com/questions/9399509/getting-rid-of-php-notice-undefined-offset tells me I need to use isset() to check if something is in there first. Has anyone else experienced this? I’m only noticing this notice now, wondering what may have changed.i have a problem the default img not show & it show me the error:
Notice: Undefined offset: 0 in /vagrant/wp-content/themes/advocacy/functions.php on line 51 http://127.0.0.1:8080/wp-content/themes/advocacy/assert/img/ipa.no.list.img.jpg”
line 51: $first_img = $matches[1][0];
can someone help me?
I found a solution that works for me:
REPLACE:
$output = preg_match_all(‘/<img.+src=\'”[\'”].*>/i’, $post->post_content, $matches);
$first_img = $matches[1][0];
with:
if( $output = preg_match_all(‘/<img.+src=\'”[\'”].*>/i’, $post->post_content, $matches) )
{
$first_img = $matches[1][0];
}
i am trying this.. but instead of getting image. i am getting only the link… can any one help me on this
This code looks very similar to an answer provided on StackOverflow.
Hello,
I’m not a programmer, but think I have stumbled upon your post looking for the right thing and was hoping you could help me integrate your code into the following code in my theme?
Thanks in advance :)
Is there a way to bypass the featured image and take the image that is listed first in the content? I’m using a child theme of twentythirteen and for some reason it will not crop my images when reducing it to thumbnail size. It just squeezes it into 100×100. So I’m forced to use a 100×100 image for my featured image (because I need a thumbnail displayed on my home page. I want to display the full size image on my page that displays my posts.
thanks a lot. It works. great helpful.
Hello sir please tell me how to use the second part of your code i mean how to add that code in a loop,sir i am a newbie so please help me thanks
This is great! Great fallback when no thumbnail is set. Thanks!
Hi there.
Thank you for your code. I’ve used it to display 4-5 random posts along with their first image.
The code works fine but I would like to get the images dynamically resized. Using CSS is not an option since the images on my website are quite big and therefore loading 4-5 full size images below each post would make the site slow.
So, is there a dynamic way to resize the image?
Thank you in advance for your help :)
Not working in custom post types .any one please provide a solution to this
hey guys,
I was wondering , what would it be needed to make it retrieve more than just the first one. maybe the first 4 images…. ?
I think the array must be modified but i don’t understand it much…
thanksss
First, thanks for this code! Second, I had the same undefined offset problem as some others had. So, what I did was leave the output line alone but change what came after that to :
in the function and then in my template i put this:
I need to add some styling, but I’m still learning so I was more concerned with function for now than the style part. It also fixes the issue of having a default image show when there’s nothing to show, which was bugging me.
Well, crud, this just isn’t my day apparently. I thought I had pasted my own code but apparenty I pasted the original .
THIS is actually what I did in the function:
if (!empty($matches[1][0]) ) {
$first_img = $matches[1][0];
} else {
$first_img = “”;
}
return $first_img;
Sorry for any confusion.
What’s the purpose of the $posts variable and output buffering? I tried it without either one and it worked fine. Here it is bundled up with an img tag and an alt attr:
* Return an HTML img tag for the first image in a post content. Used to draw
* the content for posts of the “image” format.
*
* @return string An HTML img tag for the first image in a post content.
*/
function icicle_get_first_image() {
}
Hello, the code worked perfectly, however, I wonder how do I automatically generate a smaller image size, because it is loading the original image.
I tried to do something like:
add_image_size (‘thumb-medium’, 160, 140, true, array (‘center’, ‘top’));
More unsuccessfully!
Hello, I want to show excerpt with first 300 characters of the post, how can I do it?
By using the Excerpt function
https://codex.wordpress.org/Function_Reference/the_excerpt
Thanks for this. work for me.
I tried this and it worked, but I have a problem with the fact that sometimes the first image turned out to be a smiley because it is also started with tag. Is there any way to exclude smilies from being selected as the first image?
Tried to read about preg_match and regex but it’s way beyond my comprehension since I’m not a programmer myself.
Very helpful and works like a charm
Thanks so much for this tutorial and the one on Functionality plugin! I made my first plugin with the help of your tutorial and am so happy :)
You and your site are the best!
That is an awesome hack. One quick question, how to get the thumbnail of the non-featured image displayed using catch_that_image()?
Hi,
How do I make all thumbnails are aligned to the left?
Thank you
First, thanks for the tip on the function! But, like someone above, I got “Undefined offset”. After many hours of trial and error I stumbled on this code:
This worked perfectly! Code from: http://www.devnetwork.net/viewtopic.php?f=1&t=136123 Now, onto the next mission. Get this to only show the thumbnail of the caught image. God, I really need to learn php! ;)
Almost a day later, after muuuch trial and errors and help from a lot of forum posts, I have come up with this:
It will find the first image, then find the corresponding thumbnail and add width, height, alt and title to the output. You can also add the caption. Uncomment the row “//$caption_text” and add the caption in in the image string.
To use it:
Hopefully this will save some time for someone else!
Thanks for this.
Thanks a lot, very usefull when working with content already in place that does not have featured images!
Thank you so much. Great post. Helped me a lot.
I was having problems with this code outputting the last image in the post, instead of the first. Not exactly sure why. But replacing the “preg_match_all” line with this, cured it.
if(preg_match_all('/< *img[^>]*src *= *["\']?([^"\']*)/', $post->post_content, $matches)){
Nice Code! Thanks.
And thanks Richard for the version that delivers a sized thumbnail.
Does not work
Thanks for the function.
How can this be used to render custom image size?
Great functionality plugin :D
I would strongly suggest wrapping
$post->post_content
indo_shortcode()
so that you also grab images from galleries or other shortcodes that put images in content.Doing that, the output line looks like this:
Awesome! Thanks
Exactly what I was looking for and it works great! Thank you!
Worked great!!!!
What if I want to use the post thumbnail, because my articles always have post thumbnails. So what if I want to use the post thumbnail instead of the first image.
The has_post_thumbnail function isn’t giving me what I want.
Hey!
has_post_thumbnail()
checks for the post thumbnail and is great for writing conditions that require it.the_post_thumbnail()
should return the image for you: https://developer.wordpress.org/reference/functions/the_post_thumbnail/Hey Graham, thanks for the response. The has_post_thumbnail() works, but doesn’t force the images to have thesame height and width since the images are not the same, so I used the catch_that_image function, and added this code to my exerpt
<img src='’width=’50’height=’50’ alt=”/>
<a href="”>
and it worked fine but uses the first image instead of post thumbnail. So is there a way I can use this code and add the has_post_thumbnail function to it?
I tried it this way
<img src='’width=’50’height=’50’ alt=”/>
<a href="”>
but it didn’t work. Please advice.
Without knowing all the context,
has_post_thumbnail
is great for checking, but you may need to usethe_post_thumbnail()
with a parameter that calls the exact thumbnail size you are looking for — and you may need to create that custom thumbnail size in a function. For exampleecho the_post_thumbnail( 'my-custom-size' )
Thanks a lot. Fixed it at last
Please I really need help on this.
Here is my function code
function catch_that_image() {
global $post, $posts;
$first_img = ”;
ob_start();
ob_end_clean();
$output = preg_match_all(‘/<img.+src=\'”[\'”].*>/i’, $post->post_content, $matches);
$first_img = $matches [1] [0];
if(empty($first_img)){
$first_img = “../img/bg.png”;
}
return $first_img;
}
And here is my loop
if (FILE == $_SERVER[‘SCRIPT_FILENAME’]) { die(); }
if (CFCT_DEBUG) { cfct_banner(FILE); }
if (have_posts()) {
echo ‘
<
ul class=”disclosure table group”>’;
while (have_posts()) {
the_post();
?>
What I was trying to do is to get the post thumbnail as featured image that displays on the homepage.
The has_post_thumbnail only picks the first image from a post, and some post only contains featured images
Please I need help on this
I know this is ancient but it still comes up in Google.
Can we fix the RegEx so it’s less hungry, otherwise it gets a lot more than it should and potentially grabs the wrong image.
Just needs a couple of question marks added:
Thanks
I thought that
{Pattern}+?
or{Pattern}*?
will match the same thing as{Pattern}
, so.+?
or.*?
is equivalent to.
. This won’t match<img>
elements like:–
<img <!-- Note that there are 4 spaces before this comment -->src="/image.png">
–
<img
<!-- Note that there are a line break (in this case <cr><lf>) and 7 spaces before this comment -->src="/image2.png">
Also, without the
g
flag the regex will only match the first token (or the first image in this case).The correct regex (in PHP) should be
/<img[\s\S]+src=[\'"]([^\'"]+)[\'"][\s\S]*/i
gOops! It should be
'/<img[\s\S]+src=[\'"]([^\'"]+)[\'"][\s\S]*\/?>/i'
(missing quotes and\/?>
at the end of the element)Would this snippets work on HTML5 websites? Example: blogspot sites.
Thanks for this snippet – I did have an issue where the fallback default image got an error, “undefined offset”. The change I made in functions.php:
Instead of:
$first_img = $matches[1][0];
I used:
$first_img = isset( $matches[1][0] ) ? $matches[1][0] : null;
That did the trick (although I am very newbie and this may be incorrect). Hope this saves someone hours on Stack Overflow!