I have seen many questions from people about how to create photo galleries in WordPress. But often I see these questions answered by somebody recommending a plugin or something like that. You don’t really need plugins to create photo galleries. WordPress has a huge amount of gallery functionality built right in. You just need to make your theme smarter in order to take advantage of it.

Note: Matt has one of the neatest photo gallery implementations around, and he often gets questions about it. So I’m going to refer to it from time to time in this post. Maybe you’ll want to head over there and familiarize yourself with some of the look and features of it.

Understanding the Gallery Concept

One of the first things you need to know is how WordPress organizes Galleries. A gallery is really just a post with a bunch of images attached to it.

While editing a post or creating a new one, you have the option to upload images or other files. When you upload a file through the file Uploader, WordPress creates a post just for that file. This post has a post_type of “attachment”. Images in particular get some extra processing, and they show up in multiple sizes, you can insert them into the posts, etc. You probably already knew that. You probably have seen the gallery inserter, which just inserts the “gallery” shortcode into your post.

What you might not have known is that it’s doing more than you think. It’s not just resizing those images you’re uploading, but it’s pulling out metadata and other information about the image too. It’s grabbing alot of the EXIF data from the image and storing it as postmeta items for that attachment post. The post itself, being a post, gets its own URL, which is the post that it is attached to’s URL followed by the attachment posts title. Basically, an attachment post is sorta like a child of the parent post, which contains the gallery. So all a gallery really is is the sum of the attachments posts that are children of the gallery post itself.

Graph of the Gallery concept

Is that clear as mud? Don’t worry, it’s simpler to work with than you think.

Create an Image Template

First thing you need to do is to edit your theme (or create a child theme, if you prefer). What you’re going to do is to make an “image.php” file.

(Side note: If you browse through the source of WordPress, you’ll never find where it loads the “image.php” file, because it isn’t there. What it is actually doing is looking for the mimetype of the attachment as a filename. So since you uploaded, say, a JPG file, then the mimetype is image/jpeg. It splits that and looks for image.php, followed by jpeg.php, followed by image_jpeg.php, and finally just attachment.php as the generic base. It does this for any and all attachments, and any and all mime types. So you can have a video.php for video attachments, audio.php for audio attachments, etc.)

The image.php file is the template that will load for “single images”. A gallery shows thumbnails, but when you click on them, you go to the attachment page for just that image. An easy way to start with your custom image page is to copy your existing single post page to it. Just copy single.php to image.php. If you don’t have a single.php, maybe you should try copying the index.php file instead.

Modify your Image Template

Since this is an image, it’s going to have things in it that normal posts don’t. It’s also going to need special navigational entries that other posts don’t have.

For starters, it has a parent, which is the post containing the gallery. So what if we want to display the gallery post’s name? Easy, we can reference the parent using $post->post_parent. So code like get_the_title($post->post_parent) will get us that title so we can echo it. Similarly, using something like get_permalink($post->post_parent) will get us the link back to the gallery. So this sort of code in our image template will display that link:

echo "<a href='" . get_permalink($post->post_parent). "'>Go back to ". get_the_title($post->post_parent) ."</a>";

For navigation, we have special functions. previous_image_link and next_image_link will let us display links to the previous or next images in the gallery order. Each of these takes two parameters. The first is the size of the previous or next image we want to display (or false to not show a thumbnail at all), the second optional parameter is some text to put in the link. So to show a couple of text navigational links, this code would work:

echo previous_image_link(false,'Previous Photo');
echo next_image_link(false,'Next Photo');

If I wanted to display image links instead, I could change that false to ‘thumbnail’ to display the thumbnail sized images. Or ‘medium’. Or whatever size I preferred.

Next we want to display the image. The wp_get_attachment_image function takes care of that easily:

echo wp_get_attachment_image( $post->ID, 'medium' );

The second parameter there is the size we want to display it at. You could also use ‘large’, ‘full’, ‘thumbnail’, etc. Any of the image sizes. If you want the image to be clickable, you might wrap it in an A tag and link it to the image itself.

But remember that attachment posts are still posts. All those fields you can enter on the image uploader are available to you to use. For example, the “Title” is stored in the normal Post Title field, so calling the_title() will display that. The Description is stored in the Content field and can be displayed with the_content(). The Caption is stored in the Excerpt field and can be displayed with the_excerpt(). You should use these as needed.

EXIF Information

Here’s an example of one of Matt’s single image pages, showing a balloon: http://ma.tt/2011/05/balloon-ride/mcm_9033/.

Nice shot. Scroll down a bit and look on the right hand side of that page, where it says INFO. Lots of nifty information there. But he didn’t put any of that in, WordPress did it all by itself.

To gain access to that information in your image.php file, you use this code:

$imagemeta = wp_get_attachment_metadata();

If you examine this array, you find that it contains widths, heights, filenames of the various sizes of thumbnails generated, etc. But it also contains an array called “image_meta”. This is an array of information that represents everything WordPress was able to glean from the image itself. After you know this, it’s just a matter of displaying it properly.

For example, to display the camera name, he has code similar to this:

if ($imagemeta['image_meta']['camera']) {
	echo "Camera: " . $imagemeta['image_meta']['camera'];

There’s other bits in there, like Aperture, Focal Length, ISO settings, and Shutter Speed. Most of these are straightforward, except for shutter speed which is often not in an easy format to display. Usually it’s a fractional value, represented as a decimal. Often we want to convert this to the fractional display. Here’s a bit of code I wrote to do that. It’s not perfect, but what is?

if ($imagemeta['image_meta']['shutter_speed']) {
	echo 'Shutter: ';

	// shutter speed handler
	if ((1 / $imagemeta['image_meta']['shutter_speed']) > 1) {
	echo "1/";
		if (number_format((1 / $imagemeta['image_meta']['shutter_speed']), 1) ==  number_format((1 / $imagemeta['image_meta']['shutter_speed']), 0)) {
			echo number_format((1 / $imagemeta['image_meta']['shutter_speed']), 0, '.', '') . ' sec';
		} else {
			echo number_format((1 / $imagemeta['image_meta']['shutter_speed']), 1, '.', '') . ' sec';
	} else {
		echo $imagemeta['image_meta']['shutter_speed'].' sec';

Ugly, I know, but it gets the job done, more or less. Works on most shutter speeds I’ve tested it with.

Gallery Formatting in the Stream

Now, obviously you want your posts to look good in the normal flow of the blog as well. Twenty-Ten and the upcoming Twenty-Eleven themes both show you how to do this rather easily. Twenty-Ten used the “gallery” category for this at one point, before Post Formats came along and made that method obsolete. Now it uses the gallery post format instead.

So first, obviously, your theme will need to support the gallery post format. This is easy, just add this to your theme’s functions.php if it doesn’t have gallery support already (or add “gallery” to it if it does have post format support).

add_theme_support( 'post-formats', array( 'gallery') );

Now that that’s done, you have the option of choosing gallery as a post format. So you need to edit your theme to use that flag as an indicator to display things differently.

There’s plenty of tutorials on post formats out there, so I’ll assume you’re more than capable of figuring out how to use has_post_format(‘gallery’) or the “.home .format-gallery” CSS indicators to style the posts as needed.

What you need to know for specific gallery formatting in the main stream of the blog is how to display a selected representative image from the gallery there instead of the whole thing. There’s two basic steps to this.

First, you have to write your post appropriately to begin with. Take one of Matt’s posts for example: http://ma.tt/2011/05/20/

Here’s how that post actually looks in the editor:

Description text at the top here... Went for balloon ride, etc.
< !--more-- >
[ gallery ]

In other words, he puts the description first, then the more tag, then the gallery after it. This has the effect of giving a natural separation of the description content and the gallery itself. The gallery is not displayed on the front page, because it’s after the more tag. So a call to the_content() on the stream pages will only show the description.

Secondly, you can easily adapt the Featured Image function to let you choose which image to display in the stream. All the user has to do is to upload their gallery then select one and set it to be the featured image. Voila, it’ll be the main representative one used.

if ( has_post_thumbnail() ) {
        // use the thumbnail ("featured image")
        $thumb_id = get_post_thumbnail_id();
	the_post_thumbnail( $size ); // whatever size you want

By tossing a div around that, you can then float it left, or right, or whatever you prefer to do. With some extra code and the use of the get_children function, you can make this default to the first image in the gallery if they don’t choose a featured image.

else {
	$attachments = get_children( array(
		'post_parent' => get_the_ID(),
		'post_status' => 'inherit',
		'post_type' => 'attachment',
		'post_mime_type' => 'image',
		'order' => 'ASC',
		'orderby' => 'menu_order ID',
		'numberposts' => 1)
	foreach ( $attachments as $thumb_id => $attachment )
		echo wp_get_attachment_image($thumb_id, $size); // whatever size you want

Using tricks like this, you can get the bits of the gallery yourself and display them in different ways.

Make a Gallery Specific Page Template

Matt’s Gallery Page is itself customized. It displays the galleries in an entirely different way. There’s a big copy of the featured image, along with a few thumbnails below the description, and it even has a count of the images in each “album”. This is all done with a pretty straightforward page template.

So to start, make a Page Template:

Template Name: Gallery

Right at the top of the template, we’re going to add a special taxonomy query, which will get all the gallery posts (as well those in the gallery category, since we’re being backward compatible and all). So here’s the code:

$args = wp_parse_args($query_string);

         'tax_query' => array(
                'relation' => 'OR',
                        'taxonomy' => 'post_format',
                        'terms' => array('post-format-gallery'),
                        'field' => 'slug',
                        'taxonomy' => 'category',
                        'terms' => array('gallery'),
                        'field' => 'slug',
        'paged' => $args['paged'],
) );

First we parse the normal arguments, then we override them with our own query. The only argument we really use from the normal set is the page number, for multiple paging.

Our overriden query uses an advanced taxonomy query. In this case, it selects any posts in the gallery post format, or any post with a category of gallery. By passing this to query_posts, we override our main page query, and thus our main Loop will now display the gallery posts only.

After this, it’s just a matter of displaying what we want to display.

The main Loop itself is pretty straightforward. To display that featured image, we use essentially the same code as we used before, only passing it a bigger size.

To display the description, we just use the_content() as per usual. One thing we have to do though is to set the global $more value to zero, so that it stops at the !–more– tag, preventing it from continuing to display the whole gallery.

Getting the count turns out to kinda suck. There’s no good function in WordPress to do this for you easily. So, reluctantly, I resorted to an SQL query.

echo $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->posts WHERE post_parent = '$post->ID' AND post_type = 'attachment'" ) .' PHOTOS IN THIS SET';

The four thumbnails you can do using the get_children trick. However, there’s a catch. We don’t want to display the featured image as one of those four thumbnails. So, since we’ve already displayed that image (see the code above), we have the $thumb_id variable still. So we’ll use that to not get that image. Like so:

$attachments = get_children( array(
	'post_parent' => get_the_ID(),
	'post_status' => 'inherit',
	'post_type' => 'attachment',
	'post_mime_type' => 'image',
	'order' => 'ASC',
	'orderby' => 'menu_order ID',
	'numberposts' => 4,
	'exclude' => $thumb_id )
foreach ( $attachments as $img => $attachment ) {
	echo '<a href="'.get_permalink($img).'">'.wp_get_attachment_image( $img, $size ).'</a>';

By using the exclude parameter, we can get the first four images in the gallery without getting that featured image again, if it’s in those first four images.


Andrew Nacin pointed out that I can combine the act of getting those four children and getting the attachment count into a single new WP_Query, like so:

$images = new WP_Query( array(
    'post_parent' => get_the_ID(),
    'post_status' => 'inherit',
    'post_type' => 'attachment',
    'post_mime_type' => 'image',
    'order' => 'ASC',
    'orderby' => 'menu_order ID',
    'posts_per_page' => 4,
    'post__not_in' => array($thumb_id),
    'update_post_term_cache' => false,
) );

This creates a new secondary query that I can loop through like so, to show the children:

foreach ($images->posts as $image) {
	echo '<a href="'.get_permalink($image->ID).'">'.wp_get_attachment_image( $image->ID, $size ).'</a>';

It also has the side benefit of doing the primary counting of the images for me, via the SQL_CALC_FOUND_ROWS that WordPress uses in full-blown queries. However, the count will be off by 1, since we’re excluding the featured thumbnail. Therefore, I just have to add one to it:

echo ($images->found_posts+1) . ' PHOTOS IN THIS SET';

That combines both of those elements into one query instead of two, and eliminates the need for the direct SQL query.

(Side note: I also set ‘update_post_term_cache’ to false to prevent it from doing an extra query to get the terms for these posts into the internal memory cache. This saves us a bunch of unnecessary queries, since I’m not using the terms here anyway. Using full WP_Query objects instead of the simpler ones like get_children can take a little bit more thought and effort, but can save you time in the long run, if used wisely.)


Throughout this post I’ve used $size as a generic indicator of where to put the size parameter. WordPress creates sized images by default, as we all know. These are thumbnail, medium, large, and full which is just the full sized uploaded image, unmodified.

But WordPress can create other sizes too, if you like. At different points throughout Matt’s gallery pages, you’ll see images displayed in all sizes. These sizes are custom, and they’re added in the functions.php file.

add_image_size( 'nav-thumbnail', 100, 100, true );
add_image_size( 'random-thumbnail', 200, 150, true );
add_image_size( 'gallery-thumbnail', 250, 200, false );
add_image_size( 'gallery-large', 660, 500, false );
add_image_size( 'gallery-pagethumb', 70, 70, true );

The add_image_size function takes a width, a height, and a flag to cause it to crop or not. So those tiny thumbnails on the gallery are “gallery-pagethumb” sized, and are 70×70, cropped. Anywhere I need one of those sizes, I can just pass that parameter instead of $size and voila.

Obviously though, adding too many sizes is undesirable, because it takes time to create those sizes (they’re created on upload of the images), and it takes storage space to store them. Hopefully a future version of WordPress can work around this issue.


These are the basics of making cool galleries, without plugins, without special uploaders, and while being able to style it to match your theme. Play with it. Experiment. There’s a ton of functions in WordPress specifically for dealing with these. Take a look through wp-includes/media.php and look at some of the function names. You might be surprised.



  1. Adding this to the learn-something-new files. Great post with lots of (at least to me) little known or implemented ideas.

  2. Nice post, really.
    It inspired me to stop using wp-gallery, as I often encounter issues I can’t solve, as it has its own way to handle images.

    I still see a bit cumbersome the way how media are managed by WordPress.

    I believe that the media must be improved with categories and other things.

    I’ve event tried that: I’ve created a custom hierarchical taxonomy and bound to the attachments type. It shows when adding or editing a media file, but only as a free text field: quite useless, isn’t it?

    Well, if WP could add something like that, or even more, I think would help a lot.
    In the last years I’ve read many rumors about that, but they were just that: rumors.

    However, back to your post, and since I can’t properly add custom taxonomies to attachments, I think I will add your guidelines.

  3. Thanks for the post! This is very good as I am trying my best to do all things possible with the core and not other gallery plugins.

    The downfall: no actual gallery management system. I can detach images from posts in the Media Library just fine, but why not have an atatch function as well? Is there something I am missing here?

    As an example, I upload my images via the post, and forget one or two. How can I “redo” the gallery without uploading all the images again.

    • I don’t fully understand the question. There is an Attach link for unattached images in the library. Just go to Media->Library, find an unattached image, then click the “Attach” link.

      If you forget to upload images, then just go back to the post and upload just those images. You can use the tabs at the top of the uploader popup to see what images are attached and modify them and such. Just click the “Media Library” link.

      • I see now. You did not misunderstand me. I got it backwards. There is no way to DETACH photos without deleting them. That is what I was thinking about. We came across the problem when trying to redistribute some images across a site. The Media Library could use just a little bit of attention to be extremely robust. Thanks for the reply, and especially this post.

        • Id i understand you problem realy; maybe the plugin Post2Media helps you. I build also all sites with the default WP Gallery features, especially the functions of wp for attachments. But on a gallery in WP on a post it is not possible to reduce images or de/activate pictures of the gallery. So i use a count for pictures, maybe the x pictures from the first one and the user must reorder via Drag and drop the images in the gallers. Also it is possible to de/activate the images in the gallery via the plugin post2media; also it with the plugin possibel use a picture also in other posts and galleries.

  4. It’s amazing how you always know what I’m working on. Am now trying to cobble something together using your info from above, but would like to know how to link to image, not to the attachment page.
    I’ve got:

    foreach($attachments as $img =&gt;$attachment)
    echo '<a href="'.get_permalink($img).'" rel="nofollow">'.wp_get_attachment_image( $img, 'thumbnail' ).'</a>';

    I guess I don’t want get_permalink($img) but not sure what I should have instead?
    (Goal: I’m putting the images in a sidebar gallery and want to open with a lightbox effect)

    • The wp_get_attachment_image_src($id, $size) function will return an array of the image src URL, its width, and its height. So you can use it like this:

      $image = wp_get_attachment_image_src($attachment_id, $size);
      list($src, $width, $height) = $image;
      // $src is now the direct image URL
      • Sorry Otto, couldn’t get that to work for me. It seemed to be linking to the original post, not the image nor the attachment.
        But this is working really closely to what I want:

        foreach($attachments as $img=>$attachment)
        echo wp_get_attachment_link($img, 'thumbnail',false);

        Now I’m just not sure how to get it to lightbox, but that’s not related to this post. I’ll find it eventually :)
        Thanks for the kick in the right direction :)

  5. [...] has created a very thorough primer to create a WordPress photo gallery without a plugin. He walks you through understanding pictures and galleries, creating and modifying an image [...]

  6. Post updated to include @nacin’s suggestion of using a single query to eliminate the direct SQL query for the count.

  7. primer: “an elementary textbook that serves as an introduction to a subject of study”

    Otto – really, help me, i’m ignorant and not a techie.

    • If you’re not a techie and not a coder, then I hate to tell you this, but you’re reading the wrong post. I write code. I write about code. I write about code for other coders to help them code.

      If you can’t code, then this post wasn’t meant for you.

  8. Looking at your hierarchy again, I was thinking, why not have a table for this? Not a custom postype or format, but on the same level as Post, and Page. Posts and pages easily communicate with each other via taxanomies/categories. Media (video/audio) could also have it’s place there?
    ~ A Laymen Playing Devil’s Advocate

    • Having a separate table sort of misses the whole point. By giving each attachment its own post, the attachment can be displayed in a unique way, alone. Thus the reason for the image.php file in the theme.

      For an example of this, click on the chart I made for this post. I don’t have an image.php file in this theme, so it ends up using the single.php file. It displays the image, the description of the image, it’s title, etc. Note the URL, how it is a child of this post. That’s the sort of thing you get by using the attachment post type and the parent/child relationship. Implementing that as a separate table would be strange and harder to do.

      • Ok, I see now. It is on the same level. There is the post_type column in the posts table. Sorry for blithering here last night. It was late, and I was not looking at the database.
        Looking at the database NOW, I see the post_parent column, where the parent ID is assigned to the attachment. Why don’t we have an detach link that zeros that value? It would be so very helpful in organizing galleries. As I said before, if you mistakenly attach a photo to the wrong post, you are SOL.

  9. [...] Photo Gallery Primer explique d’abord le concept d’une galerie : un article (« post ») [...]

  10. awesome :D this is really gonna help with my new theme :D

  11. Here I was railing against the “bargain basement” WP Gallery system, searching up and down for the perfect plugin, when it turns out there was all kinds of functionality cleverly hidden away in there that I can really use.

    Now I’m really looking forward to developing my own gallery system using the core tools. Great write-up, Otto.

  12. tried adding your exif code to a custom template and my error log says: ` Fatal error: Cannot use string offset as an array in..` and the line points to the exif code. I jusr called imagemeta, that worked, then tried outputting the camera, just testing, but get this error.

    can you advise or do you need more info?

    • ah, sorry, typo, didn’t mean imagemeta but this: `$imagemeta = wp_get_attachment_metadata();
      ` works fine, error pops up when trying to echo anything, i.e. `if ($imagemeta['image_meta']['camera']) {
      echo “Camera: ” . $imagemeta['image_meta']['camera'];

      • You may want to var_dump($imagemeta) in order to understand what’s in that array and how to use it. The camera may not be in the particular images that you’re uploading. Some images may not have image_meta in them. The code I posted is more of a guideline than actual code, though it mostly does all work.

  13. Thanks for this info.
    It will great if you can release this as a template page that can be added to themes.

  14. This is all very interesting, but have you not just created a “plug-in”? It uses code, it uses its own file(s), it has its own style, etc. I am not focusing on the semantics, but the notion that “WordPress has a lot of gallery functionality built in” is akin to saying “this bunch of grapes have a lot of wine in them”. I wish it really had gallery functionality built in so that we would not use plugins or develop our mini-plugins, albeit with limited functionality.

    • No, because I’m talking about editing your THEME, which is not a plugin.

      A plugin modifies how WordPress works. Your theme controls what WordPress displays. These are two very different things, even if they’re both made out of “code”.

      • That’s why I put the word plugin in quotation marks, it is not really a plugin but a set of files and modifications that change the way the system functions. I don’t mean to debate the semantics, or the importance of knowing how to bring the needed functionality in different ways, but what happens if I want to change the theme, or apply the same solution to multiple sites? A plugin will be a more transparent solution that can be ported to other sites or to other themes.

        But again, to each his own …

        • My goal is really more to get theme authors to add support for this in their own themes. Implementing this sort of thing as a plugin would defeat the purpose. A photo gallery isn’t an add-on, it’s built into WordPress. It’s an integral part of a site, for certain types of sites. It should look like the theme looks, not look like some bolt-on gallery.

  15. Simply amazing Otto! I used some of the stuff from Matala Theme in one of my Themes before and this now comes even more “supercharged”.


  16. Interesting. I’d been having similar thoughts, as I have a couple of needs for photos that go beyond a simple Gallery shortcode, but not for a full gallery-style plugin.

    The problem with the Gallery shortcode is that is will only (easily) let you see the images attached to a specific post. So if you want one picture to appear on two or more posts/pages you have to upload it more than once. My thought was to create a new custom post type, upload one image per post and then write a new gallery shortcode which takes a value, and then lists all the thumbnails of all the image-posts tagged with that value.

    But that does rather feel like I’m re-inventing the perfectly good attachment post type that exists and which you’ve used. So I’m a bit confused :->

    • Or, you know, you could just upload it twice. ;)

      Seems a long bit of effort to go for optimizing to use the same picture in multiple places. Also note that an attachment image is attached to its parent post and even has the parent post slug in its URL. This makes it tricky to really have the same attachment in more than one place.

      • I would, but if I need to use the same image several times, it seems silly to upload it over and over again.

        However, I might have found a plugin that does the job for me. Allied with your Primer above, I think I have the germination of an idea…

  17. [...] leads on to an article Samuel Wood (more known within the WordPress Community as Otto) wrote on how to create photo galleries, without the need of using a plugin.In a 45 minute video, Blog Design Guy shows us how to go about designing a minimalist blog using [...]

  18. I try to use the native gallery in preference to plugins, but it lacks in some respects. Compared to the rest of the admin UI, it’s terrible, and clients have difficulty using it effectively.

    As mentioned above, There’s no way to un-attach an image from a gallery in the UI ( http://core.trac.wordpress.org/ticket/6820 , http://core.trac.wordpress.org/ticket/8888 , http://core.trac.wordpress.org/ticket/14042 ) except to delete the post and try again ( http://wordpress.org/extend/ideas/topic/unattaching ). It’s also a pain that gallery, featured image, and single inserted images colide in unexpected ways (from a clients perspective, adding exclude by ids in the shortcode text sucks) that I’ve had to teach clients to create posts solely for the purpose of containing a gallery, and only a gallery, that is then inserted into the main post by id (which I guess works well enough). It’s just somewhat less of a satisfying experience for clients then what they’ve come to expect from WordPress (which they all love).

    Native galleries are great, but they could certainly be improved (The Media update version has been “Definitely the next version” since I’ve been following WP development ;-) ).

  19. Has something changed in wp 3.2rc1 where the query_posts example snippet you gave stops working? When I use the snippet provided the page ends up sending out the last 5 posts in all categories (5 is set as # in admin). I have even converted it over to a new wp_query, but still have the same problem.

    Posted on stack:

    Basically every other step in the tutorial above worked perfectly. I just can’t seem to get the query to work properly is all.

    thanks, and thanks for such a great tut. Learned a lot about attachments that I did not know before

  20. Thank you for this great post. I learned a lot. One question: Is there an easy way to state the number of comments below each photo on the gallery post (like on Matt’s website)? I guess you can’t use the gallery shortcode if you want to achieve this.

    • Sure. To do it, you just override the gallery shortcode.

      Step 1, copy the function gallery_shortcode from the wp-includes/media.php file into your theme’s functions.php file. Rename it to something else, like themename_gallery. Also change its parameters to look like this:

      function themename_gallery($filtered, $attr = null)

      Step 2, remove these bits at the top of the function:

      static $instance = 0;
      // Allow plugins/themes to override the default gallery template.
      $output = apply_filters('post_gallery', '', $attr);
      if ( $output != '' )
      	return $output;

      Step 3, go down into the function itself and find where it first starts to set the $output variable (in the foreach $attachments block). If you examine it, you see that it looks for the post_excerpt (which is the caption on the image) and it uses that to set the caption under the image. So what you want to do is to set the comments count into that excerpt so that that gets output. You do that just before the $output variable begins to get set. Here’s the code to do that:

      $cnum = get_comments_number($id);
      if ( $cnum && !empty( $attachment->post_excerpt ) ) {
      	$attachment->post_excerpt .= '<br />';
      if ( $cnum ) {
      	$attachment->post_excerpt .= get_comments_number($id) ;
      	if ( $cnum == 1 ) {
      		$attachment->post_excerpt .= ' Comment';
      	} else {
      		$attachment->post_excerpt .= ' Comments';

      All this does is to check the comments count, and if it’s non zero, then it adds the BR tag to the excerpt, followed by “Comment” or “Comments”, depending on the number.

      Step 4, you need to make your new function override the gallery output. This is a one-liner:

      add_filter ( 'post_gallery', 'themename_gallery' );

      Easy. The post_gallery filter lets you make your galleries look however you like, but by starting with a copy of the gallery_shortcode function, you have all the same normal functionality, and you can modify the output of it as needed.

  21. Does WordPress support specific image templates per post type? Similar to single-photo.php, for example.

    I am wondering because I’d like for my image.php that handles my portfolio post type to have comments disabled (taking out the comments template) while the image.php that handles my photo post type to have comments enabled.

    Granted, there may be another way to make this happen, but I haven’t found that yet…

    Fantastic post, by the way. Thanks!

    • No, there’s no post type specific code for images, but you can just detect the post-type in the comments.php file and show or not show comments as you please. Maybe something like this at the top of the file:

      if ($post->post_type == 'portfolio') return;
  22. [...] Mullenweg’s own photo gallery inspired me, and Otto’s post certainly helped with some of the functionality. I hope to add more photos and functionality [...]

  23. [...] As part of setting TEE up for this site I also decided to move away from using a plugin to manage the photos I have here on the site and instead moved to the default WordPress media management instead.  I made this decision after deciding to dramatically reduce the number of photos I had hosted here and because I thought it would be a good idea to support the default setup within TEE.  If the default setup doesnt appeal to you I would recommend the NextGEN gallery plugin which i previously used to manage my photos. To help support the default setup in TEE I added in a gallery page template and also tweaked the image attachment template for TEE a little.  You can see these in action by browsing the few Photos that survived the culling.  Note that the gallery and photo tweaks are heavily influenced by the photo gallery primer posted by Otto. [...]

  24. [...] don’t really need plugins to create photo galleries.” – Otto published another great post about making cool galleries without plugins. He refers Matt’s gallery as a neat example of WordPress gallery [...]

  25. Great post Otto!

    This is one of the most under-utilized features of WordPress. Looking forward to mucking around with this for an upcoming theme I’m building.


  26. [...] Photo Gallery Primer Great post by Otto on how to really use the WordPress built in gallery features. Share this:Like this:LikeBe the first to like this post. This entry was posted in Links and tagged WordPress by Nick Hamze. Bookmark the permalink. [...]

  27. This is a good post, creating a gallery without a plugin is good.

  28. Hi Otto,

    Interesting and informative post. I am fairly new to WordPress and PHP and currently building my first theme learning as I go, I have some experience with HTML and CSS though.

    I have the code you have created running on a WAMP server on my theme, I am using a medium image size and noticed the code gives the image a class=”attached-medium”. When I try to target this class via the CSS nothing appears to happen, any advice would be appreciated.



  29. I’d love to add a Photo Gallery, came across this but for a beginner it really sucks not to know where or how to add these codes. I absolutely love the way Matt’s gallery is set up too. Such a bummer -_- Off to look for new tutorials :(

  30. Good info .I have tried this plugin for embedding a photo stream on my website. Simple to use and works fast http://wordpress.org/extend/plugins/iframe-embed-for-momentme/. It automatically collects images from social events worldwide and its free…

Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Need to post PHP code? Wrap it in [php] and [/php] tags.