Display all images attached to a post/page

You’ve probably struggled with the default output of the WordPress gallery shortcode. It’s OK. We all have. By default, WordPress wraps the entire gallery in a div, and then further wraps the images in dl & dt tags.

There are a few, excellent WordPress image gallery plugins that address gallery shortcode styling (File Gallery Plugin), as well as the invalid XHTML code (Cleaner Gallery Plugin). These plugins work great for many things, but they also add a lot more functionality.

If all you want to display is a simple list of all the image attachments that are attached to a particular page/post, and you just want the img tags, there’s a much easier way to do it.

Display WordPress attachments (images) with img tags only

Place the following code inside the loop on a single page or post template.

<?php
	$images =& get_children( array (
		'post_parent' => $post->ID,
		'post_type' => 'attachment',
		'post_mime_type' => 'image'
	));

	if ( empty($images) ) {
		// no attachments here
	} else {
		foreach ( $images as $attachment_id => $attachment ) {
			echo wp_get_attachment_image( $attachment_id, 'thumbnail' );
		}
	}
?>

get_children explained

You can adjust the variables in the get_children array.

If you want to get images from a specific page/post, you’d set post_parent to the ID of that page/post. Using $post->ID returns the images from whatever page/post you are on.

If you just used 'post_type' => 'attachment', then PDFs, audio files, and any other type of attachment would also be listed. Using 'post_mime_type' => 'image' will only return image attachments. You could similarly get video attachments by using 'post_mime_type' => 'video'.

There are a few other parameters you could pass to the get_children array, to further customize the display of attachments. View all the get_children options in the WordPress codex »

Image Size

The size of the image is easily controlled in the last line of code:

echo wp_get_attachment_image( $attachment_id, 'thumbnail' );

Just change thumbnail to medium, large, or any custom image size you have created in your functions.php file. (how to create custom image sizes)

Display Images As Links to Fullsize Image

As mentioned by Jason in the comments, you might want to display all images attached to your WordPress page/post as a list of links, with the link opening up the fullsize image. In the echo statement above, just replace wp_get_attachment_image with wp_get_attachment_link. (WordPress codex for wp_get_attachment_link)

Exclude Featured Image

You might want to include all images attached to the post, but exclude the featured image. To do this, just add the exclude parameter to your get_children array.

Using the above example, your code would look like this:

$images =& get_children( array (
	'post_parent' => $post->ID,
	'post_type' => 'attachment',
	'post_mime_type' => 'image',
	'exclude' => get_post_thumbnail_id()
));

Exclude Specific Image(s)

If you want to exclude a particular image, you can do so using the “post__not_in” parameter. Find the ID of the image you want to exclude, and then modify the get_children array to look something like this (assuming the ID of the image you want to exclude is 27):

$images =& get_children( array (
	'post_parent' => $post->ID,
	'post_type' => 'attachment',
	'post_mime_type' => 'image',
	'post__not_in' => 27
));

Or to exclude multiple images, that last line would look like this:

'post__not_in' => array( 27, 28, 29, 30 )

Limit The Number of Images Displayed

Let’s say you have 15 images attached to your post/page, but you only want to display 10. Modify your call to get_children using the posts_per_page parameter:

$images =& get_children( array (
	'post_parent' => $post->ID,
	'post_type' => 'attachment',
	'post_mime_type' => 'image',
	'posts_per_page' => 25
));

Add Class to Images (ex: class=”lightbox”)

Do you need to add a class to all the images that you’re displaying? Maybe you have a lightbox script that fires for all images with a class="lightbox". You can automatically add a class to every image using the following code. Place this code in a custom functionality plugin or your themes functions.php file.

NOTE: This will add a class of “lightbox” to ALL images that are rendered using the wp_get_attachment_link function. Be careful if you, or your theme, is using this function in various places.

function add_class_attachment_link($html){
    $postid = get_the_ID();
    $html = str_replace('<a ','<a class="lightbox" ',$html);
    return $html;
}
add_filter('wp_get_attachment_link','add_class_attachment_link',10,1);

Or Add a rel attribute

You can easily swap out class="lightbox" above, and replace with rel="lightbox" (or give any value to the rel attribute).

Set a Default Image, If No Attachments Are Found

If no images are attached to your page, and you’d like to use a default image… In the original example above, try replacing this line:

// no attachments here

with this:

<img src="/path/to/your-custom-image.jpg" alt="" />

And you would replace the image src with the URL to your custom image.

10 Commentson "Display all images attached to a post/page"

  1. /

    thanks a lot for great tutorial but i do all the code and replace $post->ID with my page ID and get images not relate to that page i can’t understand why ?!

    → Reply
    1. (Author) /

      Husien, if you post your entire code, I’ll see if I can help.

  2. /

    Thank you for your tutorial!

    When i have debug WP:
    define(‘WP_DEBUG’, false);
    Wordpress show this:
    Strict Standards: Only variables should be assigned by reference in

    → Reply
  3. /

    Many thanks for your clear explanation. It fixes my problem. I just need to add code here and there to match what I need. Thank you.

    → Reply
  4. /

    Hi Dave,
    For the papst five days or so I’ve been struggling to get the attached video url from get_attached_media('video', $post->ID); and all sorts of other bits and pieces in the codex and came up blank.

    I did these simple edits to your code anf I was bang on:
    function ht_function($type='ht_function') {
    $thistype = get_post_type();
    $args = array( 'post_type' => $thistype, 'posts_per_page' => 12 );
    $loop = new WP_Query( $args );
    while ( $loop->have_posts() ) : $loop->the_post();
    $the_url = wp_get_attachment_image_src(get_post_thumbnail_id($post->ID), $type);
    $videos =& get_children( array (
    'post_parent' => $post->ID,
    'post_type' => 'attachment',
    'post_mime_type' => 'video'
    ));

    if ( empty($videos) ) {
    // no attachments here
    } else {
    foreach ( $videos as $attachment_id => $attachment ) {
    $video = wp_get_attachment_url($attachment_id);
    }
    }
    echo $video;

    Now just one big question what conditional do I need to add to exclude posts with no attachments? Would that be somehing like:

    if ( empty($videos) ) {
    exclude $post->ID;
    }

    Thanks in anticipation of your pointing me in the right direction.

    → Reply
    1. /

      I spoke too soon, all the posts return the same video and when I activate the plugin I’m working on with the code added for the video, it get a message, “The plugin generated 6 characters of unexpected output during activation. If you notice “headers already sent” messages, problems with syndication feeds or other issues, try deactivating or removing this plugin.”

      Anyway I’m still ahead of where I was, because before this all I was getting was “Array” or null returned with the code I was using.

  5. /

    Since it took me so long to get this working, I’m sure it may help someone trying to get the featured image and video associated with the post in a post type (standard or custom). This is useful in creating a gallery plugin.

    //function to get images and videos
    function ht_function($type='ht_function') {
    echo '';
    $thistype = get_post_type();
    $args = array( 'post_type' => $thistype, 'post_parent' => $post->ID, 'posts_per_page' => 12 );
    $loop = new WP_Query( $args );
        while ($loop->have_posts()) {
            $loop->the_post();
            $the_url = wp_get_attachment_image_src(get_post_thumbnail_id($post->ID), $type);
    	$videos = get_attached_media('video');
    foreach($videos as $video) {
     $video = wp_get_attachment_url($video->ID);
        }
    if ($the_url && $videos);
    echo '<a href="'.$video.'" rel="nofollow">';
    echo '';
    echo '</a>';
    }
    echo '<!--End wrapper div-->';
    	}

    Not perfect and can be improved by a real coder.

    → Reply
  6. /

    Great piece of code.
    I have a little problem. I need to retrieve not only images attached to the post, but also images that were attached to another post but place in the content of this current post.
    Do you think is possible?
    Thanks in advance

    → Reply
    1. (Author) /

      Daniel — I haven’t tested this, but here are my initial ideas:

      I’m not sure if the post_parent parameter accepts arrays, but if it does, try something like this. In replace of the 'post_parent' => $post->ID, line above, try:

      'post_parent' => array( $post->ID, XX ),

      …where “XX” is the ID of the additional post you’re trying to pull images from.

      If that doesn’t work, maybe try using get_posts instead of get_children. This article might help. You’ll want to probably add an additional parameter for 'post_mime_type' => 'image' in your code, though.

      Let me know if either of those work out for ya.

What Are Your Thoughts?

All fields are required. Your email will not be published.

You can use standard <code> and <pre> tags to post code examples, or a service like codepen.io.