Easier And Better Solutions To Get Pictures On Your Posts

WordPress makes it pretty easy to upload picture on posts and pages. Thereby are various data stored, which can be used.
Again and again, you can read tutorials on how to bring photos to posts, normally this is a solution via the custom fields. But there is a different and simpler solution, I think. The maintenance of custom fields is not always necessary.
Therefore, I would like to show some solutions that are, in my opinion, much better and can be expanded in many ways.

With custom fields

In the first case, the solution using a custom field to be displayed, while the data must be maintained in this field to a key.

In version 1 you store the value of the authors to the key author link, so it's easy to understand the use of the fields. More information about this can be found in the Codex.

Version 1

wp-cf
The output of the key is handed over by using the template tag get_post_meta(). The function expects the Id of the post and the key value as a mandatory, or alternatively you can set if a value or arrays are allowed. Put on true and it returns only a string

/**
 * @param int $post_id Post ID.
 * @param string $key The meta key to retrieve.
 * @param bool $single Whether to return a single value.
 * @return mixed Will be an array if $single is false. Will be value of meta data field if $single
 *  is true.
 */
function get_post_meta($post_id, $key, $single = false)
<?php $key = 'authorlink'; ?>
<p>Photo of <a href="<?php echo get_post_meta($post->ID, $key, true);?>"></a>.</p>

The next step is basically no different, except that we now put the address in a value to another key, where the picture is. This requires the author to know address and save the URL.
wp-cf2

In version 2, however, we go one step further and put a function into the functions.php, which takes care of it and then we can feed it with data. Again, this is just an example and needs in this version the key of the custom fields, the width and height of the images. These three sample values, we then write in the tag to output the image.

Version 2

/*Custom Field Images*/
function image_attachment($key, $width, $height) {
	global $post;

	$custom_field = get_post_meta($post->ID, $key, true);
	if ($custom_field) {
		echo '<img src="' . $custom_field . '" alt="Post Image" width="' . $width . '" height="' . $height . '" />';
	} else {
		return;
	}
}

The output of the template is determined by the above function as follows.

<?php
$image_key = 'image';
$myimage = get_post_meta($post->ID, $image_key, true);
if ($myimage) { ?>
	<div class="post-image">
		<?php image_attachment($image_key, 512, 200); ?>
	</div>
<?php } ?>

This really can make some beautiful things. Many theme authors would like to just have a picture to a post, which is directly taken at various points. Often this is achieved through the above solution. However, this requires that the authors need to know the custom fields and maintain them, so the key of the custom field and URL to the image.

Not very comfortable, so I want to show a solution, how you can get the image that was uploaded to the post, which can be found in the Gallery of the post.

wp-images

WordPress own functions for images

One of the many options is wp_get_attachment_image(), which represents in my view, the simplest solution. Here is an example of what explains it in more detail.

At first we just get all pictures, not all the attachments of the posts that has been uploaded directly to the post. These images, we can directly display. The syntax must always be in the loop.

<?php
$attachments = get_children( array('post_parent' => get_the_ID(), 'post_type' => 'attachment', 'post_mime_type' => 'image') );
foreach ( $attachments as $attachment_id => $attachment ) {
	echo wp_get_attachment_image($attachment_id);
} ?>

The above example loads via the loop all images and display them. We don't take care about the actual size of the image, in default it will display the thumbnail. By setting post_mime_type = image, it only fetches images and not other attachments of the post.
The function of WordPress, which outputs the image with HTML, requieres the ID of the attachment, so you have to retrieve the ID to the post beforehand, we'll do with get_children().

A few words now to function wp_get_attachment_image() of WP to display the images. As already mentioned, there are several functions that all have a similar structure, and either give back other markup or allow other parameters. For a simple output, this function is best. It is also described in the Codex.

The function allows for 3 parameters:

/**
 * Get an HTML img element representing an image attachment
 *
 * @param int $attachment_id Image attachment ID.
 * @param string $size Optional, default is 'thumbnail'.
 * @param bool $icon Optional, default is false. Whether it is an icon.
 * @return string HTML img element or empty string on failure.
 */
function wp_get_attachment_image($attachment_id, $size = 'thumbnail', $icon = false)

You get the markup back for the img-Tag, like the following example.

<mg width="150" height="150" src="http://example.com/wp-content/uploads/2009/08/DSC00261-150x150.jpg"; class="attachment-thumbnail2 alt="Image Example" title="Example Image" />

The last of the three parameters is not really interesting in association with pictures, since it displays an icon. But the second parameter is there even more exciting, because this allows to set the size of the image. Here you can give either one of the preconfigured sizes, the sizes which you can configure in the settings of WordPress and are created when you upload using the media library. The following options are available.

  • Default-Values: thumbnail, medium, large oder full
  • Custom sizes via Array: array( width, height ) Example: array(100, 100)

If you pass your own values, then WordPress fetches the appropriate image in dependence of these values. So if you set, for example, 100x100 and the thumbnails are 150px150px, then these images are drawn. If you have your own array of 200x200, it will output the medium image because the thumbnail is too small.

<?php
$attachments = get_children( array('post_parent' => get_the_ID(), 'post_type' => 'attachment', 'post_mime_type' =>'image') );
foreach ( $attachments as $attachment_id => $attachment ) {
	echo wp_get_attachment_image( $attachment_id, array(200, 250) );
} ?>

Images with links

Now I will not always just the pictures, but also have the image with a link to the image in original size. In that case there is the function wp_get_attachment_link(). Here an example:

<?php
$attachments = get_children( array('post_parent' => get_the_ID(), 'post_type' => 'attachment', 'post_mime_type' =>'image') );
foreach ( $attachments as $attachment_id => $attachment ) {
	echo wp_get_attachment_link( $attachment_id, 'medium' );
} ?>

The HTML looks like this.

<a href="http://example.com/wp-content/uploads/2009/08/DSC00261.JPG" title="Example Image"><img src="http://example.com/wp-content/uploads/2009/08/DSC00261-150x150.jpg" class="attachment-thumbnail" alt="Image Example" title="Example Image" height="150" width="150"/></a>

Thus the image in the requested size is generated, and the link was set to the image in original size.

Determine size of the images

Sometimes you want to know in advance how big is the image. There is a function that returns the values as an array. This is an example of the output:

<?php
$attachments = get_children( array('post_parent' => get_the_ID(), 'post_type' => 'attachment', 'post_mime_type' => 'image') );
foreach ( $attachments as $attachment_id => $attachment ) {
	$src = wp_get_attachment_image_src( $attachment_id, 'full' );
	var_dump($src);
} ?>

This simple loop to output the values returns an array.

array
  0 => string 'http://example.com/wp-content/uploads/2009/08/DSC00261.JPG' (length=63)
  1 => int 1632
  2 => int 1224
  3 => boolean false

The order of the array is allocated as follows.

  • $src[0] => url
  • $src[1] => width
  • $src[2] => height
  • $src[3] => icon

Thus, it can react to the size, depending on requirements. Alternatively, you can work with the function image_get_intermediate_size($post_id, $size='thumbnail'), which returns some more values. A sample of the output for 'medium':

array
  'file' => string 'DSC00261-300x225.jpg' (length=20)
  'width' => string '300' (length=3)
  'height' => string '225' (length=3)
  'path' => string '2009/08/example-300x225.jpg' (length=28)
  'url' => string 'http://example.com/wp-content/uploads/2009/08/DSC00261-300x225.jpg' (length=71)

Further functions and possibilities

In this context, there are a few other functions that enable the work with attachments or pictures. I do not want to explain each of them, therefore I constribute a small loop for testing purposes. This covers many possibilities and are self explanatory, I think.

<?php
$attachments = get_children( array('post_parent' => get_the_ID(), 'post_type' => 'attachment', 'post_mime_type' => 'image') );
foreach ( $attachments as $attachment_id => $attachment ) {
	echo '<p>';
	echo 'wp_get_attachment_image: ' . wp_get_attachment_image( $attachment_id, array(200,250) ) . '<br />';
	echo 'wp_get_attachment_link: ' . wp_get_attachment_link( $attachment_id ) . '<br />';
	echo 'wp_get_attachment_url: ' . wp_get_attachment_url( $attachment_id ) . '<br />';
	echo 'wp_get_attachment_thumb_url: ' . wp_get_attachment_thumb_url( $attachment_id ) . '<br />';
	echo 'get_attachment_link: ' . get_attachment_link( $attachment_id ) . '<br />';
	$src = image_get_intermediate_size( $attachment_id, 'medium'	 );
	echo 'image_get_intermediate_size. '; var_dump($src); echo '<br />';
	$src = wp_get_attachment_image_src( $attachment_id, 'full', true );
	echo 'wp_get_attachment_image_src. '; var_dump($src); echo '<br />';
	echo 'Title of attachment: ' . apply_filters( 'the_title', $attachment->post_title ) . '<br />';
	echo 'Link to post: ' . get_permalink($image->post_parent) . '<br />';
	echo '<hr style="clear:both;" /></p>';
} ?>

Remember, the syntax must be in the loop of WordPress.

Only one picture to post

Now I have explained how to get the pictures but in general you will probably not need to post all the pictures, but you want just one picture. This occurs, for example, in magazine themes, where a small picture is displayed to make the post more interesting. Through these functions I can give the author of the respective post the control of that picture. Normally I do this in such a way that it explicitly output the first picture from the gallery to the post. Thus, the author can move the image in the gallery by dragging and dropping to the right place.

wp-gallery-reihenfolge

This is not an own function, you just have to feed get_children() accordingly. The output of the image, and other values to the image is again as described above.

In our first example we pick only the first image from the gallery.

<?php
$attachments = get_children( array(
				'post_parent'    => get_the_ID(),
				'post_type'      => 'attachment',
				'numberposts'    => 1, // show all -1
				'post_status'    => 'inherit',
				'post_mime_type' => 'image',
				'order'          => 'ASC',
				'orderby'        => 'menu_order ASC'
				) );
foreach ( $attachments as $attachment_id => $attachment ) {
	echo wp_get_attachment_image( $attachment_id );
} ?&>

Now the author of the contribution can always choose the first image of what he wants to use.

Alternatively we can turn the tables and get the last image from the Gallery .

<?php
$attachments = get_children( array(
				'post_parent'    => get_the_ID(),
				'post_type'      => 'attachment',
				'numberposts'    => 1, // show all -1
				'post_status'    => 'inherit',
				'post_mime_type' => 'image',
				'order'          => 'DESC',
				'orderby'        =>'menu_order ASC'
				) );
foreach ( $attachments as $attachment_id => $attachment ) {
	echo wp_get_attachment_image( $attachment_id );
} ?>

With the help of numberposts, we specify how many images are to be fetched. So we fetch in the following example the first 2 pics and after the last 2 pictures.

<?php
$attachments = get_children( array(
				'post_parent'    => get_the_ID(),
				'post_type'      => 'attachment',
				'numberposts'    => 1, // show all -1
				'post_status'    => 'inherit',
				'post_mime_type' => 'image',
				'order'          => 'ASC',
				'orderby'        => 'menu_order ASC'
				) );
foreach ( $attachments as $attachment_id => $attachment ) {
	echo wp_get_attachment_image( $attachment_id );
} ?>

Well, the last two pictures, starting with the last picture.

<?php
$attachments = get_children( array(
				'post_parent'    => get_the_ID(),
				'post_type'      => 'attachment',
				'numberposts'    => 2, // show all -1
				'post_status'    => 'inherit',
				'post_mime_type' => 'image',
				'order'          => 'DESC',
				'orderby'        => 'menu_order ASC'
				) );
foreach ( $attachments as $attachment_id => $attachment ) {
	echo wp_get_attachment_image( $attachment_id );
} ?>

Meta-Data of images

WordPress saves various meta data to the images. Now and then these are very useful, and why not simply use them.

First an example to get to the data. This we do with the function wp_get_attachment_metadata(). This function returns quite a lot of data and we can access the size of images, their path and also access the meta data.

<?php
$attachments = get_children( array(
				'post_parent'    => get_the_ID(),
				'post_type'      => 'attachment',
				'numberposts'    => 1, // show all -1
				'post_status'    => 'inherit',
				'post_mime_type' => 'image',
				'order'          => 'ASC',
				'orderby'        => 'menu_order ASC'
				) );
foreach ( $attachments as $attachment_id =>; $attachment ) {
	echo wp_get_attachment_image( $attachment_id );
	$imagemeta = wp_get_attachment_metadata( $attachment_id );
	var_dump($imagemeta); // list values in array
	
	$aperture          = $imagemeta['image_meta']['aperture'];
	$credit            = $imagemeta['image_meta']['credit'];
	$camera            = $imagemeta['image_meta']['camera'];
	$caption           = $imagemeta['image_meta']['caption'];
	$created_timestamp = $imagemeta['image_meta']['created_timestamp'];
	$copyright         = $imagemeta['image_meta']['copyright'];
	$focal_length      = $imagemeta['image_meta']['focal_length'];
	$iso               = $imagemeta['image_meta']['iso'];
	$shutter_speed     = $imagemeta['image_meta']['shutter_speed'];
	$title             = $imagemeta['image_meta']['title'];
} ?>

In the above code is the output value of a var_dump() in it. Thus we see very quickly which content in the array exists and where they can be accessed.
All values of the meta data, I have written in each variable, so that even less experienced users should understand it.

For a simple picture, of what would be created via cell phone camera, for example, the array looks like this.

array
  'width' => string '1632' (length=4)
  'height' => string '1224' (length=4)
  'hwstring_small' => string 'height='96' width='128'' (length=23)
  'file' => string '2009/08/DSC00261.JPG' (length=20)
  'sizes' =>
    array
      'thumbnail' =>
        array
          'file' => string 'DSC00261-150x150.jpg' (length=20)
          'width' => string '150' (length=3)
          'height' => string '150' (length=3)
      'medium' =>
        array
          'file' => string 'DSC00261-300x225.jpg' (length=20)
          'width' => string '300' (length=3)
          'height' => string '225' (length=3)
      'large' => 
        array
          'file' => string 'DSC00261-1024x768.jpg' (length=21)
          'width' => string '1024' (length=4)
          'height' => string '768' (length=3)
  'image_meta' => 
    array
      'aperture' => string '2.8' (length=3)
      'credit' => string '' (length=0)
      'camera' => string 'W800i' (length=5)
      'caption' => string '' (length=0)
      'created_timestamp' => string '1184253323' (length=10)
      'copyright' => string '' (length=0)
      'focal_length' => string '0' (length=1)
      'iso' => string '100' (length=3)
      'shutter_speed' => string '0.0166666666667' (length=15)
      'title' => string '' (length=0)

Alternative in WordPress 2.9

Using WordPress version 2.9, there is a template tag just for this request, so it is easier and more understandable. You just use the the_post_image() and you can set the size. Default is thumbnail, it is possible thumbnail, medium, large or full.

the_post_image(); // without parameter -> Thumbnail
the_post_image('thumbnail'); // Thumbnail
the_post_image('medium'); // Medium resolution - use full, 

As a small alternative is still get_the_post_image() available, whereas the function doesn't have echo, and can optionally have the ID of the post.
get_the_post_image( $size = 'thumbnail', $post_id = NULL )

Conclusion

WordPress offers a lot of different functions to access attachments, whether pictures or other files. Also a part of meta-data is stored, which can be used. Many approaches can be found in the code, primarily in the wp-includes/media.php. Perhaps I could point out some solutions which in my view a better alternative than the use of custom fields, or even scanning the content.

Comments are closed.

15 comments

  1. Keiy

    This post is surely needed to be read by me, I've bookmarked it. Thanks Frank for this comprehensive tutorial.

  2. Basti

    Yess. Great post, again.

    I wonder why there are not more comments - this has become an extreme important issue (i think not only for me.).

    Now I understand how to access a post image anywhere in any size. I was always searching for a way to insert some images in different sizes for the homepage, post page, etc. Until now, I've done this via custom fields and uploading the image into a FTP-Folder.

    Is there a way to "disconnect" the image from the text? I mean, it's really difficult to layout an image e.g. on the left side and the text on the right side with the tools given by wordpress.
    You could do this with the "more" - Tag, as seen in many templates.

    My "dream-workflow" would be uploading an image with the WP-uploader that is then linked to the post, but not forced to be displayed when I use "the_content();".
    This would give me simply more control about where the image is displayed.

    I could filter out the tags in the content, but this would cause some other problems, if I did want to display an image in some posts...

    Any idea is greatly appreciated, I think this is really close to that what I like to achieve.

  3. Frank

    @Basti: thanks, Feedburner has problems and the post was not in the feed :( Most people read aur blog on the feed and not on this site.

    the_content() listed all images in the post, you must added in the editor. You can upload over the backend of WordPress, include not in the post editor and include via template with the functions on this post. The second way ist, you exclude the images with regxp from the content. Please see this post for a solution.

  4. Basti

    Thanks again.

    The thing with stripping out the tags was something, I thought about.

    Now, after reading your comment twice, I finally got it. Upload must happen in the "Edit Post" panel in order to get the image attached to the post. - Not in the Media Library, because that won't link the attachment to the post.

    The editor could - as you told - change the order in the gallery to get control of what image is used for the post thumbnail in an archive etc. He also can decide himself, if the image should be presented in the content.

    That's a really interesting approach and makes the use of custom fields needless in many cases.

  5. Stephen

    A few months ago I released my Ordered Thumbnails plugin which does a lot of what is described here, in that it will automatically pull the thumbnail for the first image in a post (for when you don't want to have the full post displayed) and allow you to choose the image you want to appear by sorting the images in the gallery.

    I'm working on a new version of the plugin and incorporating the images' meta data seems to be a logical next step. Keep up the good work here!

  6. Octav

    But how about uploading an image and auto-assigning it to a key from custom fields? Wanted to code a plugin by myself, but had some problems with the wp-uploader...

  7. Alex

    This is not so easy to accomplish, you probably should try out the attachment plugin. Maybe this is the solution you are looking for:

    http://wordpress.org/extend/plugins/attachments/

  8. Octav

    @Alex: Thanks for the advice.

  9. Tom Steenhuysen

    This is the first explanation with code samples that has made the most sense to me, works and is complete!
    Thank you so much!
    Tom

  10. Jazz

    This is great post!

    Unfortunately, I can't really get this technique to work.

    I am using Wp2.8 and for some reason when examining the data in the wp_posts table...Post_type='post' and the post_mime_type is blank..even when I attach from the media gallery or upload.

    I gather this is the reason why get_children will sometimes not retrieve a image, even though there is one in the post.

    I also examined the wp_postmeta table as well and also the meta_key did not have a "_wp_attachment_" and there was not a reference to the image in the meta_value column either.

    Do you have any ideas as to why this is happening to me?

  11. IronMAN

    thank you,

    you are a life saver.

  12. Emil

    Let's ask stupid question. What about if the post already has the image attached. This will create i.e. thumb and still keep the attached image as well, making two images per post when the image is already inserted.

    Thanks,
    Emil

  13. Frank

    @Emil: you can read all pictures or you beach test the order of the picture. To add attachments from other posts you must use the plugin Post2Media, see on the plugin-directory for this.

  14. Chris

    Hi! first off, I'm sorry my bad English.
    When I press Edit Image to make thumbnail with size 214x214, I see a crop button disable.
    Somebody can tell me what can I do to use it? I just can rotate and less more.

    Thank you

  15. t.g

    How is it possible to use the width of an image to filter it?
    for example i only want to show images with a width of 400px fullsize!
    i'm referring to the 'determine size of image' part.

    helpful tutorial AND site