Get Images Attached to a Post

When you upload an image (or other media file) through the Write Post or Write Page panel, WordPress remembers which post that file is attached to. This is a great feature if you want to pull some of the attached images for use as thumbnails on your blog’s homepage for instance – similar to the way the Tutorials and Blog indexes are set up on this site.

Inside and Outside The Loop

For my project, I needed to get the attached images for a page outside of The Loop, so in this tutorial I’ll show you both ways. First inside the loop, then I’ll show you the changes to make to get this done outside the loop.

Also, I’m trying a new strategy this time around… Instead of giving you the complete code and then going through each section step by step, I’m shortening this post a bit by only showing the complete code…but well-commented so you can see what’s going on. Let me know what you think about this strategy and if you’d prefer to see the step by step break down like I’ve done in previous tutorials.

First, Inside The Loop

One thing to keep in mind is that inside the loop, the $post object is set, and so we can access its various properties using the $post->;PROPERTY syntax. So we first need to create a new function in our functions.php file.

function bdw_get_images() {

    // Get the post ID
    $iPostID = $post->ID;

    // Get images for this post
    $arrImages =& get_children('post_type=attachment&post_mime_type=image&post_parent=' . $iPostID );

    // If images exist for this page
    if($arrImages) {

        // Get array keys representing attached image numbers
        $arrKeys = array_keys($arrImages);

		/******BEGIN BUBBLE SORT BY MENU ORDER************
		// Put all image objects into new array with standard numeric keys (new array only needed while we sort the keys)
		foreach($arrImages as $oImage) {
			$arrNewImages[] = $oImage;
		}

		// Bubble sort image object array by menu_order TODO: Turn this into std "sort-by" function in functions.php
		for($i = 0; $i < sizeof($arrNewImages) - 1; $i++) {
			for($j = 0; $j < sizeof($arrNewImages) - 1; $j++) {
				if((int)$arrNewImages[$j]->menu_order > (int)$arrNewImages[$j + 1]->menu_order) {
					$oTemp = $arrNewImages[$j];
					$arrNewImages[$j] = $arrNewImages[$j + 1];
					$arrNewImages[$j + 1] = $oTemp;
				}
			}
		}

		// Reset arrKeys array
		$arrKeys = array();

		// Replace arrKeys with newly sorted object ids
		foreach($arrNewImages as $oNewImage) {
			$arrKeys[] = $oNewImage->ID;
		}
		******END BUBBLE SORT BY MENU ORDER**************/

        // Get the first image attachment
        $iNum = $arrKeys[0];

        // Get the thumbnail url for the attachment
        $sThumbUrl = wp_get_attachment_thumb_url($iNum);

        // UNCOMMENT THIS IF YOU WANT THE FULL SIZE IMAGE INSTEAD OF THE THUMBNAIL
        //$sImageUrl = wp_get_attachment_url($iNum);

        // Build the <img> string
        $sImgString = '<a href="' . get_permalink() . '">' .
                            '<img src="' . $sThumbUrl . '" width="150" height="150" alt="Thumbnail Image" title="Thumbnail Image" />' .
                        '</a>';

        // Print the image
        echo $sImgString;
	}
}

Next you just need to call the function from wherever you want the image to show up at.

bdw_get_images();

A couple things to note about the above code:

  1. We’re only getting the first attached image’s thumbnail. If we wanted to display all the attached images, we’d have to use a for-loop to loop through each of the values in $arrKeys.
  2. The first attached image is the first image uploaded, and not the first image according to the order you’ve sorted them in the WordPress gallery admin. If you want to get the first image according to the gallery menu order, I’ve added the simple bubble sort above (commented out).
  3. If you want the full-size image instead of the thumbnail, use wp_get_attachment_url() instead of wp_get_attachment_thumb_url().
  4. I’ve hard coded the width and height of the thumbnail to be 150px by 150px. You could add a width and height parameter to the function declaration and pass those parameters when calling the function if you need those numbers to be flexible.

How to Do It Outside the Loop

The main difference to get this done outside the loop is that the $post object won’t be set (or rather it will be set, but can’t be used reliably), so we need to either know the post ID we want the images for, or we need to be on the post/page that we want the images for, but just outside of the loop for that post/page.

If we’re on the post/page but outside the loop (i.e. in the sidebar), we can use the get_the_ID() function to get the ID of the current post/page. So instead of $iPostID = $post->;ID, we could use $iPostID = get_the_ID().

If we want to pull the images from a post/page other than the one we’re currently viewing, we’d have to pass the post ID of the post/page we want to the bdw_get_images() function as a parameter when calling the function.

image_pdfimage_print
52 Comments
  1. Thanks for the heads up on that Keith. I try to catch those, but WordPress changes it every time I edit a post, so I miss those sometimes.

  2. Your code snippet is turning ampersands into html entities which breaks the php

  3. I'm using v 2.6. The postId is not getting passed to the function. I modified the function to take in the postId

    function bdw_get_images($postId) {
    $iPostID = $postId;
    ...

    and in my loop

    < ? bdw_get_images($post->ID); ?>

    • Hi Keith
      nice solution you have, I also find other solution
      just adding
      global $post, $posts;
      under the function name
      example
      function bdw_get_images() {
      global $post, $posts;

      should be works

  4. This is great, but is there a way to do it with images that were embedded from flickr?

  5. Thanks man! Saved me some precious time! Cheers from Brazil.

  6. Thanks a lot, this hack works like a charm…

  7. This is a great plugin, but what about images that you add to your post that are already in your media library? I found that it will not make the thumbnail.

    • gp, I believe the thumbnail is created either when a post is saved or when the image itself is uploaded, so the thumb should exist, and if you add that image to a post, WordPress should return that thumb url with the wp_get_attachment_thumb_url() function. Are you saying the thumbnail’s not being returned with that function?

      • it could be me, but I foudn that if I “link” an image from the media library it will not find the linked image. Only if I upload an image with that post. It works very well for that. But what if my post wants to use an image that was uploaded and attached to another post… I might not be making sense, or it could be a lack of testing on my part.

        • This is a problem I’m having with my themes too! Right now I’ve been using Justin Tadlock’s Get-The-Image Plugin, but every onece in awhile my image isn’t getting recognized as attached.
          His plugin can scan the post for images, but can’t resize them from there.
          I sure hope wordpress fixes their media options for 2.8

          • Scott, I have the same problem as GP – want to make a thumbnail from the original version of an image inserted in to a post from the media library (but not attached directly using upload in to that post) – do you know if WP2.8 will address this or not?
            - for example the image may be inserted in to the post as a thumbnail size, and I don’t want to make a “thumbnail of a thumbnail” but rather to get to the original full size image and make the new thumbnail from that one…
            Does that make sense?
            Steve

  8. Nice! Thank you a lot for open my eyes to the very useful get_children function and by the way updating my knowledge about get_posts in 2.6+! Looking at the docs you could shorten your function a lot using the ‘orderby’ parameter.

  9. really nice code! :)
    thanks

  10. Thanks for putting the effort in and then sharing this code – works great with Keith’s little addition to make the image unique to the post. I’m a happy man.

  11. when i run this script on my WP v.2.7, why i couldn’t get thumbs on my post…

    i’ve used

    function bdw_get_images($postId){
    $iPostID = $postId
    …….

    and bdw_get_images($post->ID)
    in my post where i wants to put my thumbs up…

    and this code, work just in loop #1, why this script do that???
    would you help me up from this problem….

  12. Hi,

    Got it working – good write up!

    Could you elaborate on point 1 in your notes:

    1. We’re only getting the first attached image’s thumbnail. If we wanted to display all the attached images, we’d have to use a for-loop to loop through each of the values in $arrKeys.

    How would I go about creating the loop. I’ve googled ‘for-loop’ but haven’t found anything useful.

    Could you give an example?

    Thank you!

      • Thanks for the reply.

        I’m pretty new to wp and I’m still not sure how to implement this. Is there any chance of an example of how to integrate this with your code? I’m a bit lost at the moment.

        It also seems to be picking up the last image uploaded instead of the last image uploaded for that page.

        Thanks again for the help.

        • I’d recommend the WordPress.org forums for more on the loop.

          As for the last image issue, I think that was solved above, so read those comments.

  13. Fantastic! but almost works… why am i getting the last image uploaded and not the one of the post?

  14. Thank you for your code!!

    I would like to know what should we write to get ALL the first images thumbnails from ALL the posts (to show them in the categories page)?

    Thank you!!
    Sabella

  15. I’m having the same problem as many others — pulling up the last uploaded image and not the one that’s attached to the post in question. Any solutions?

  16. My solution to posting all images instead of just the one

    comment out where it selects the first image:
    //$iNum = $arrKeys[0];

    and instead write in the foreach:

    foreach ($arrKeys as $iNum) {

    (remember to end it all with an extra ‘}’ )

    • It works all images displayed. Can you help me how can i display them in a list? i want to combine them in jquery slider unfortunate cant get around that.

      thx

      • Sorted i just put : $sImgString = ‘ ‘;

  17. Why would you ever manually bubblesort anything when you can have a custom compare function and use PHP’s substantially faster quicksort?

    • Hi Aaron, there are definitely better ways to do this. This post is about a year and a half old so I may come back and rewrite it.

      I don’t believe php has a built-in quicksort function, so I assume you mean writing a quicksort function of your own. I believe quicksort is a recursive function and I tend to avoid those on this blog b/c they can be tough to understand.

      Maybe you could provide a better implementation for us?

  18. thank you for this great tip, but I am having a bit of a problem customizing it in WP3. I have different posts with different tags (ie, local news, interviews, etc). These posts are assigned to a category called “photos”, and have image attachments in them (1 image per post)…

    I want to be able to show the latest post image from that category using any given tag, for example “interviews”… only the image attachment

    How do I go about doing this? Thanks in advance.

  19. I found the solution, I used Keith’s alteration of the script (posted above in the comments), and did a query_post, identifying the tag I wanted in that query… Thank you to both of you :)

  20. Great piece of code that succeeded for me where many otheres failed. Have to say it is annoying that the line numbers copy to the clipboard along with the code.

  21. It’s great saved my day but I have a problem. I’m using it for a portfolio page and for me it takes the attached image only from one post and now I have the same thumbnail for all portfolio items. Is there a solution?

    • Did you try some of the suggestions in the comments above? I believe someone else had a similar issue.

  22. ‘attachment’,
    ‘numberposts’ => 40,
    ‘post_status’ => null,
    ‘post_parent’ => 19
    );
    ?>

    ID, $size=’thumbnail’, $icon = false);
    ?>

    this is what worked for me, ‘numberposts’ sets the maximum number of images You want to display and post_parent You can replace with post->$ID to display the images related to current post. I wanted to have a static list of images which were attached to a page.

    Hope You find this useful
    Cheers

  23. i am not able to get all the images related to that post only getting one image.can anyone please tell.
    Thank you

  24. hey, thanks! really helpful!

    just one thing: i was looking for a better way to do the sorting by menu_order and came up with this:

    foreach( $images as $image )
    $imglist[$image->menu_order] = $image->ID;

    ksort( $imglist );

    works well for me and is easier

  25. excuse the double post, but i just wanted to suggest another sorting method – even easier:
    get_post() supports an ‘order_by’ argument; so using the query with ‘order_by=menu_order&order=DESC’ should give you the same result as your code

    • Yeah, I’ve been meaning to update this post with that info. Not sure what I was thinking with that sorting method, but you beat me to it…thanks for the tip!

  26. Actually, I’m getting all the images in library and not just for the actual post. Any Idea?

    Code:

    function bdw_get_images() {

    // Get the post ID
    $iPostID = get_the_ID();

    // Get images for this post
    $arrImages =& get_children(‘post_type=attachment&post_mime_type=image&post_parent=’ . $iPostID );

    // If images exist for this page
    if($arrImages) {

    // Get array keys representing attached image numbers
    $arrKeys = array_keys($arrImages);

    /******BEGIN BUBBLE SORT BY MENU ORDER************
    // Put all image objects into new array with standard numeric keys (new array only needed while we sort the keys)
    foreach($arrImages as $oImage) {
    $arrNewImages[] = $oImage;
    }

    // Bubble sort image object array by menu_order TODO: Turn this into std “sort-by” function in functions.php
    for($i = 0; $i < sizeof($arrNewImages) – 1; $i++) {
    for($j = 0; $j menu_order > (int)$arrNewImages[$j + 1]->menu_order) {
    $oTemp = $arrNewImages[$j];
    $arrNewImages[$j] = $arrNewImages[$j + 1];
    $arrNewImages[$j + 1] = $oTemp;
    }
    }
    }

    // Reset arrKeys array
    $arrKeys = array();

    // Replace arrKeys with newly sorted object ids
    foreach($arrNewImages as $oNewImage) {
    $arrKeys[] = $oNewImage->ID;
    }
    ******END BUBBLE SORT BY MENU ORDER**************/

    // Get the first image attachment
    //$iNum = $arrKeys[0];

    foreach ($arrKeys as $iNum) {

    // Get the thumbnail url for the attachment
    $sThumbUrl = wp_get_attachment_url($iNum);

    // UNCOMMENT THIS IF YOU WANT THE FULL SIZE IMAGE INSTEAD OF THE THUMBNAIL
    //$sImageUrl = wp_get_attachment_url($iNum);

    // Build the string
    $sImgString = ‘

    ‘;

    // Print the image
    echo $sImgString;
    }
    }
    }

  27. Wonderful – many thanks! I have been looking for a way to get all of my images uploaded and assigned to posts to show on a single page – as a pictorial “archive”, listed by month.

    Using this, and another code snippet I found elsewhere, I’ve got the result I wanted: http://www.my105e.com/pictures

    —————————————————————

    post_date);
    $month = mysql2date(‘n’, $post->post_date);
    $day = mysql2date(‘j’, $post->post_date);
    $postid = $post->ID;

    ?>

    <a href="/date/”>

    ID;

    // Get images for this post
    $arrImages =& get_children(‘post_type=attachment&post_mime_type=image&post_parent=’ . $iPostID );

    // If images exist for this page
    if($arrImages) {

    // Get array keys representing attached image numbers
    $arrKeys = array_keys($arrImages);

    //******BEGIN BUBBLE SORT BY MENU ORDER************
    // Put all image objects into new array with standard numeric keys (new array only needed while we sort the keys)
    foreach($arrImages as $oImage) {
    $arrNewImages[] = $oImage;
    }

    // Bubble sort image object array by menu_order TODO: Turn this into std “sort-by” function in functions.php
    for($i = 0; $i < sizeof($arrNewImages) – 1; $i++) {
    for($j = 0; $j menu_order > (int)$arrNewImages[$j + 1]->menu_order) {
    $oTemp = $arrNewImages[$j];
    $arrNewImages[$j] = $arrNewImages[$j + 1];
    $arrNewImages[$j + 1] = $oTemp;
    }
    }
    }

    // Reset arrKeys array
    $arrKeys = array();

    // Replace arrKeys with newly sorted object ids
    foreach($arrNewImages as $oNewImage) {
    $arrKeys[] = $oNewImage->ID;
    }
    //******END BUBBLE SORT BY MENU ORDER**************/

    foreach ($arrKeys as $iNum) {
    // Get the first image attachment
    //$iNum = $arrKeys[0];

    // Get the thumbnail url for the attachment
    $sThumbUrl = wp_get_attachment_thumb_url($iNum);

    // UNCOMMENT THIS IF YOU WANT THE FULL SIZE IMAGE INSTEAD OF THE THUMBNAIL
    //$sImageUrl = wp_get_attachment_url($iNum);

    // Build the string
    $sImgString = ‘‘ .
    ” .
    ‘;

    // Print the image
    echo $sImgString;
    }
    }
    }
    ?>
    —————————————————————

    • I appear to copy/pasted over the first part of the code!!

      ————————————————————-

      post_date);
      $month = mysql2date(‘n’, $post->post_date);

      ——————————————————

  28. What if we wanted to randomly display an image from the group of images attached to the post?

    • Here’s what I did, I wanted to have random images display on subpages below the header, sort of like a featured image, so I setup a post for it and uploaded all the photos I wanted to rotate and I modified the above function to show random images each time the page is loaded or refreshed instead of just showing the latest uploaded image. In this particular case I knew exactly what post I wanted to pull from so it worked well.

      Let me know if anyone sees any reason why this may not be a good way to do it.

      //Get Post Images
      function bdw_get_images() {

      // Get the post ID
      $iPostID = 133;

      // Get images for this post
      $arrImages =& get_children(‘post_type=attachment&post_mime_type=image&post_parent=’ . $iPostID );

      // If images exist for this page
      if($arrImages) {

      // Get the first image attachment
      $iNum = array_rand($arrImages,1);

      // Get the full size url for the attachment
      $sImageUrl = wp_get_attachment_url($iNum);

      // Build the string
      $sImgString = ”;

      // Print the image
      echo $sImgString;
      }
      }

  29. HI there. I just noticed that when I used the function inside a loop that the post ID was not getting set, so I used the ‘out of loop’ method of setting it. It could be because I was calling it inside of a custom post type post? NOt sure if that ID would need to be called differently. Anyways everything works, and it was an easy fix. :) Thanks loads for a nice little snippet!

  30. Hey, this code works great although displays low image size for my thumbnails. I’ve increased the size to 210×170 and the images are very low quality.
    Plz help!

Address

Razorlight Media
Phone: 513-549-7355
Fax: 866-377-4331
Url:
cash, check, credit card, invoice, paypal
2207 Kemper Lane
Cincinnati, OH 45206
700 West Pete Rose Way, #68
Cincinnati, OH 45203