Speak the Web is a series of small, intimate, low cost web design & development events
It's the small things that make a big difference
![]()
Admittedly, this post is a little specialist. So if you don’t know what WordPress MU, TimThumb and/or the wonderful “catch_that_image” function (which automatically grabs the first image in a WordPress post without needing to use custom fields) are, then you should probably switch off right about….now.
Darren Hoyt‘s absolutely wonderful PHP image resizing script is utilised all over the place now-a-days, most notably in WordPress themes (including the very one we developed for this site). Alone, this script is excellent, but when used with the very user-friendly function ‘catch_that_image’ you have a very powerful combination on your hands. You’re now able to automatically grab the first image of a post (if there is one) and then resize it to your heart’s content in your theme. Usage for standard WordPress is relatively straight forward – download TimThumb.php and follow the instructions on Darren’s website. Then, place the catch_that_image function into your theme’s functions.php file. Then, in your theme, where you want to display the first image from a post (or a default image if there isn’t one in the post) you’d put something along these lines:
1 2 3 | <a href="<?php the_permalink(); ?>" title="Read <?php the_title(); ?>"> <img src="<?php bloginfo( 'template_directory' ); ?>/timthumb.php?src=<?php echo catch_that_image() ?>&w=100&h=50&zc=1" alt="<?php the_title(); ?>"/> </a> |
Fairly straight forward stuff. However, (there’s always a ‘however’ isn’t there?) on the multi-user version of WordPress, things fall apart a little. The main reason being that WordPress rewrites urls, specifically, it rewrites the paths to files you upload. This has the unfortunate repercussion of messing with TimThumb’s mojo. Up to the plate steps Ben, from Binary Moon with his excellent write-up of how to get TimThumb to work with WPMU. His clever little function checks to see if the theme being used is on WPMU, if it is, then it uses a bit of PHP to get the correct full path to the image and then hands that on a silver platter to TimThumb.
Sadly, things break down a little when we use the aforementioned catch_that_image function. So, here we present our little work around. It basically involves adding an extra check on the catch_that_image script which sees if it has found an image or not and if it hasn’t, it checks if WPMU is being used, if it is, then it goes looking for where your image really is.
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 | <?php // Automatically get the first image in a post, or display a default image function catch_that_image() { global $post, $posts, $blog_id; $first_img = ''; ob_start(); ob_end_clean(); $output = preg_match_all('/<img.+src=[\'"]([^\'"]+)[\'"].*>/i', $post->post_content, $matches); $first_img = $matches [1] [0]; // no image found in the post, display default image or one from a custom field (called 'thumbnail') instead if(empty($first_img)) { $is_thumbnail_set = get_post_meta($post->ID,'thumbnail',true); if(empty($is_thumbnail_set)) { //If there is no image in the post or there is no thumbnail set in the custom fields, display default $first_img = "/images/default.jpg"; } else { //There's a thumbnail image set, so check if we're on WPMU or WP if (isset($blog_id) && $blog_id > 0) { //We're on WPMU $theImageSrc = get_post_meta($post->ID,'thumbnail',true); $imageParts = explode('/files/', $theImageSrc); if (isset($imageParts[1])) { $first_img = '/blogs.dir/' . $blog_id . '/files/' . $imageParts[1]; } } else { //We're on WP $first_img = get_post_meta($post->ID,'thumbnail',true); } } } else { if (isset($blog_id) && $blog_id > 0) { $imageParts = explode('/files/', $first_img); if (isset($imageParts[1])) { $first_img = '/blogs.dir/' . $blog_id . '/files/' . $imageParts[1]; } } } return $first_img; } ?> |
There we have it. Not exactly complicated invasive surgery. Then you would go about using the TimThumb script as you would normally – something like:
1 | <img class="archive_image_thumbnail" src="<?php bloginfo('template_directory'); ?>/includes/timthumb.php?src=<?php echo catch_that_image(); ?>&w=150&h=70&zc=1" alt="Carry on Reading..." /> |
Job’s a good’un. Robert’s your father’s brother, and your mum has a sister with a strange and somewhat unfortunate name. If you can think of a more elegant way to go about this, then please do let us know in the comments. If you’re a plugin designer as well as a theme designer, you may be interested in our other recent post about adding an update bubble to your plugin.
Comments (11)
cokke' wrote:
thanks for the useful article… i try to do it and it solve my problem when i try to use ephoto from elegant theme on my WPMU….
regards…
- Cokke’ -
eDDi Hughes wrote:
Wait! I miss read it! So I tested it out by replacing the no thumbnail line:
$first_img = “/images/default.jpg”;
With the lines below. Now, if we add another if statement, if attachment > 0 then boom! What do you think of that?! :D
—————————
$attachments = get_children(array(‘post_parent’ => get_the_ID(), ‘post_type’ => ‘attachment’, ‘post_mime_type’ => ‘image’, ‘orderby’ => ‘menu_order’));
if ( ! is_array($attachments) ) continue;
$count = count($attachments);
$first_attachment = array_shift($attachments);
//We’re on WPMU
$theImageSrc = wp_get_attachment_url($first_attachment->ID);
$imageParts = explode(‘/files/’, $theImageSrc);
if (isset($imageParts[1]))
{
$first_img = ‘/blogs.dir/’ . $blog_id . ‘/files/’ . $imageParts[1];
}
—————————
FriendlyDesign wrote:
eDDi, that’s a neat little trick, good work! We’ll update our original post in due course.
eDDi Hughes wrote:
I had an idea to call out the first image, so I tested it replacing the default.gif part with:
———————————
$attachments = get_children(array(‘post_parent’ => get_the_ID(), ‘post_type’ => ‘attachment’, ‘post_mime_type’ => ‘image’, ‘orderby’ => ‘menu_order’));
if ( ! is_array($attachments) ) continue;
$count = count($attachments);
$first_attachment = array_shift($attachments);
echo wp_get_attachment_url($first_attachment->ID);
———————————
How would we write it so that wp_get_attachment_url($first_attachment->ID); returns the $first_img = ‘/blogs.dir/’ . $blog_id . ‘/files/’ . $imageParts[1]; properly???
eDDi Hughes wrote:
Sir,
I feel that I owe you a pint of the best beer in your region. This worked flawless with one draw back, the files timthumb.php was generating weren’t being written to the cache directory.
I chmod the directory to 777 and it worked. The downside: with WPMU this could be cumbersome if you have multiple themes / users…
Any suggestions?
FriendlyDesign wrote:
Hi Eddi, glad this worked for you. You’re right about this being potentially cumbersome if you start getting into scores or hundreds of blogs. However, TimThumb does actually cache the images (hence the folder) so this will save some server resources. We have it running on a setup which has about 120 blogs and generates about 10,000 unique visitors on a daily basis and (albeit with a fairly poky server) never had a hiccup. Let us know how you get on! Now, about that beer…. :)
Chad Hill wrote:
Thanks…you saved my life
James wrote:
Brilliant explanation. Thanks for taking the time to go step by step. I’m gonna take a crack at implementing this over the weekend.
Thanks again!
-james
FriendlyDesign wrote:
Our pleasure! Thanks for the comments and good luck over the weekend. Give us a shout if you need a helping hand.
James wrote:
So, if I wanted to implement this into a theme that I have (like from Woo for instance) on a wordpress mu install, I would add the code you have posted here to the top of the thumb.php or the functions.php?
Or am I so far off that your just rolling your eyes at the screen right now…
Sorry, I’m still a n00b on this, but I’d like to learn how to implement this feature correctly. Help a brother out? ;)
FriendlyDesign wrote:
Hi James, don’t worry about being new to this – this sort of stuff isn’t as trivial as it first seems. You need to add that larger chunk of code into your functions.php file. You need to make sure you _replace_ the existing catch_that_image function with that. Then, in your theme files – so on index.php, home.php, single.php or wherever you want to have control over the size of the image, then you put the first line of code that we posted. Hopefully that makes sense. If not, send us an e-mail and we’ll walk you through it.