In my opinion, WordPress isn’t great at handling media. Well, it’s better than some other CMS’ I’ve used, but it’s still not amazing. This post describes a little WordPress functions.php tweak that makes takes a bit of hassle out of using WordPress galleries with a lightbox plugin.

Background

The background to this is that I have a client who has lots of photos on his website, displayed in WordPress galleries, using a simple jQuery lightbox plugin to show the photos in a nice way.

To make the Lightbox work, the gallery needs to use links to the image files rather than to the attachment pages.  It’s simplest form looks something like:

[gallery link="file"]

However, linking directly to the file is a problem if you’re uploading large image files, as the lightbox displays the full-size image. This is annoying because, if you upload a large image, the lightbox takes ages to download the picture. It’s also unnecessary, as WordPress cleverly creates thumbnail, medium and large versions of your images when you add them to the media library.

What would be really handy would be if the gallery could link to one of the resized versions of the image, thus keeping the load times down for the lightbox images without the end-user having to worry about resizing images.

UPDATE: lyndonr has commented that the original code here deleted title attributes from the links. He’s right and I’ve updated the code as a result. Apologies to anyone that this affected.

This little code snippet does exactly that. Add it to your functions.php and it will use the ‘large’ version of the image wherever WordPress is displaying a link to an attached image.

function oikos_get_attachment_link_filter( $content, $post_id, $size, $permalink ) {

	// Only do this if we're getting the file URL
	if (! $permalink) {
		// This returns an array of (url, width, height)
		$image = wp_get_attachment_image_src( $post_id, 'large' );
		$new_content = preg_replace('/href=\'(.*?)\'/', 'href=\'' . $image[0] . '\'', $content );
		return $new_content;
	} else {
		return $content;
	}
}

add_filter('wp_get_attachment_link', 'oikos_get_attachment_link_filter', 10, 4);

Technical Details

The walk through the code that I used to get to this was:

gallery_shortcode() (in media.php) does:

$link = isset($attr['link']) && 'file' == $attr['link'] ? wp_get_attachment_link($id, $size, false, false) : wp_get_attachment_link($id, $size, true, false);

to get the link-wrapped img (e.g. <a href="...."><img ... /></a>)

wp_get_attachment_link() is in post-template.php and, for link=file does

$url = wp_get_attachment_url($_post->ID)

wp_get_attachment_url() is in post.php

When we’re linking to file we want wp_get_attachment_url() to return the ‘large’ image, rather than the full-size image.

I initially set a filter on the wp_get_attachment_url hook, and the filter used wp_get_attachment_image_src( post_id, 'large' ) to get the URL of the large image size. HOWEVER, this resulted in a loop because wp_get_attachment_image_src() (which is in media.php) calls image_downsize() (also in media.php), which then uses wp_get_attachment_url() to get the URL. Which calls our filter…and so on.

So I had to look back up the chain of calls a bit and do something higher up. I settled on filtering on wp_get_attachment_link and using the regular-expression to replace the href attribute. The regular expression is probably not bomb proof, but it gets the job done.

Hope that’s helpful to someone!