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.