Relative Image Links in Wordpress Uploader

Wordpress has a very sophisticated image uploader that allows you to insert images directly into your post. It inserts images with an absolute path, including the full path to your image as an absolute link. My guess is this is for SEO and theming purposes, but if you're just building a one-off site using Wordpress as your platform, you might want to have a relative URL in there instead, i.e.:

/wp-content/uploads/2011/07/image.jpg

instead of:

http://yoursite.com/wp-content/uploads/2011/07/image.jpg

Relative attachment URLs would be useful if you were working locally at a dev domain or localhost or if you moved the website to a different server. Forcing Wordpress to insert a relative link into the database is pretty simple; you can do this by hooking a filter on the wp_handle_upload method:

function yoursite_get_relative_attachment_path($path)
{
    $paths = (object)parse_url($path);
    return $paths->path;
}

function yoursite_wp_handle_upload($info)
{
    $info['url'] = yoursite_get_relative_attachment_path($info['url']);
    return $info;
}
add_filter('wp_handle_upload', 'yoursite_wp_handle_upload');

This filter method receives the info about the upload which will be saved in the database after the upload completes. You parse the URL of the image and grab just the relative path and send it back. Your image's path in the database will now be relative to the root of your site.

That's great, but Wordpress still inserts the full site path on the front end and when you use the "Insert Image" button when writing your post. Easy fix:

function yoursite_wp_get_attachment_url($url)
{
    return yoursite_get_relative_attachment_path($url);
}
add_filter('wp_get_attachment_url', 'yoursite_wp_get_attachment_url');

By attaching another relative URL filter to the wp_get_attachment_url filter, anywhere where Wordpress requests an attachment URL will return the path relative to the root.

I haven't tested this too much with the rest of the platform, but it seems to work well so far for me. I typically create custom one-off sites with Wordpress, so I'm not super concerned with creating reusable themes.

Here's the final snippet that you'd add to functions.php. You'd just replace yoursite with your site's namespace.

function yoursite_get_relative_attachment_path($path)
{
    $paths = (object)parse_url($path);
    return $paths->path;
}

function yoursite_wp_handle_upload($info)
{
    $info['url'] = yoursite_get_relative_attachment_path($info['url']);
    return $info;
}
add_filter('wp_handle_upload', 'yoursite_wp_handle_upload');

function yoursite_wp_get_attachment_url($url)
{
    return yoursite_get_relative_attachment_path($url);
}
add_filter('wp_get_attachment_url', 'yoursite_wp_get_attachment_url');
July 6th, 2011 | Permalink