WordPress Post Thumbnails with Caption

This is a tidying up of a WordPress support forum topic – nothing really that I came up with myself.

The question is how to post the caption with a post thumbnail, aka featured image, in an ordered way.

This code below is tested in wp3.3.

(code version for wp4.1 to remove warning messages related to undefined variables, etc – see pastebin http://pastebin.com/ciLUSeJ4 )

//POST THUMBNAIL AND CAPTION STYLED SIMILAR TO .wp-caption//
function the_post_thumbnail_and_caption($size = '', $attr = '') {
global $post;
$thumb_id = get_post_thumbnail_id($post->ID);
	$args = array(
		'post_type' => 'attachment',
		'post_status' => null,
		'parent' => $post->ID,
		'include'  => $thumb_id
	);

$thumbnail_image = get_posts($args);

if ($thumb_id && $thumbnail_image && isset($thumbnail_image[0])) {
	$image = wp_get_attachment_image_src( $thumb_id, $size );
	$image_width = $image[1];

	if($attr) $attr_class = $attr['class'];
	$attr['class'] = ''; //move any 'class' attributes to the outer div, and remove from the thumbnail

	$output = '<div class="thumbnail-caption attachment-'.$size.($attr?' '.$attr_class:'').'" style="width: ' . ($image_width) . 'px">';

	$output .= get_the_post_thumbnail($post->ID, $size, $attr);

	/* to show the thumbnail caption */
	$caption = $thumbnail_image[0]->post_excerpt;
	if($caption) {
		$output .= '<p class="thumbnail-caption-text">';
		$output .= $caption;
		$output .= '</p>';
	}

	/* //Uncomment to show thumbnail title
	$title = $thumbnail_image[0]->post_title;
	if($title) {
		$output .= '<p class="thumbnail-title-text">';
		$output .= $title;
		$output .= '</p>';
	} */

	/* //Uncomment to show the thumbnail description
	$descr = $thumbnail_image[0]->post_content;
	if($descr) {
		$output .= '<p class="thumbnail-description-text">';
		$output .= $descr;
		$output .= '</p>';
	} */

	/* //Uncomment to show the thumbnail alt field
	$alt = get_post_meta($thumb_id, '_wp_attachment_image_alt', true);
	if(count($alt)) {
		$output .= '<p class="thumbnail-alt-text">';
		$output .= $alt;
		$output .= '</p>';
	} */

	$output .= '</div>';
	}
echo $output;
}

(above code edited Oct 2012)

Possible styles for that to make it look like an ordinary wp caption:

.thumbnail-caption { padding: 5px; background: #f5f5f5; border: 1px solid #ddd; }
.thumbnail-caption-text { text-align: center; margin-bottom: 5px; font-size: 90%; }
/*
.thumbnail-title-text { text-align: center; margin-bottom: 5px; font-size: 90%; }
.thumbnail-description-text { text-align: center; margin-bottom: 5px; font-size: 90%; }
.thumbnail-alt-text { text-align: center; margin-bottom: 5px; font-size: 90%; }
*/

Use the code in the template, for instance in single.php, with one of the registered thumbnail sizes as parameter; example:

<?php the_post_thumbnail_and_caption('large',array('class' => 'alignleft')); ?>

A huge ‘thank you’ to all the contributers to this topic in the forum.

PS

my personal extension of the idea –
to add the functionality using a filter function:

// dec 17 2016 @alchymyth
// filter to show caption, if available, on thumbnail, wrapped with '.wp-caption thumb-caption' div;
// show just the thumbnail otherwise

add_filter( 'post_thumbnail_html', 'add_post_thumbnail_caption',10,5 );

function add_post_thumbnail_caption($html, $post_id, $post_thumbnail_id, $size, $attr) {

if( $html == '' ) { 
 
	return $html;
 
} else {
 
	$out = '';
 
	$thumbnail_image = get_posts(array('p' => $post_thumbnail_id, 'post_type' => 'attachment'));
 
	if ($thumbnail_image && isset($thumbnail_image[0])) {
 
		$image = wp_get_attachment_image_src($post_thumbnail_id, $size);

		if($thumbnail_image[0]->post_excerpt) 
			$out .= '<div class="wp-caption thumb-caption">';
 
		$out .= $html;
 
		if($thumbnail_image[0]->post_excerpt) 
			$out .= '<p class="wp-caption-text thumb-caption-text">'.$thumbnail_image[0]->post_excerpt.'</p></div>';
  
	}

	return $out;
  
}
}

Simply use

the_post_thumbnail()

as usual.
The minor ‘downside’ of this approach is that the post thumbnail will get the caption added in any location it is used, which might not always be desired.

Here, for instance, is some css that will whow the caption only on ‘hover’:

.wp-caption.thumb-caption {
  padding:0;border:none; position:relative;
  }
.wp-caption.thumb-caption img {
  margin: 0;
}
.wp-caption.thumb-caption .wp-caption-text {
  position:absolute; bottom:10px; left: 0;
  background: #111; color: #fff; font-weight: bold; text-align: left;
  display:block; padding:3px 3%; width:94%;
}
.wp-caption.thumb-caption:hover .wp-caption-text {
  visibility: hidden;
}