My main site has a WordPress Multisite setup that is divided based on directories. For example,
- My dog articles are in http://shibashake.com/dog/ and
- My art galleries are in http://shibashake.com/blog-art.
In this setup, my image links look something like this –
http://shibashake.com/dog/files/2012/12/dog-image1.jpg
However, this is just a shorter more pretty url. The actual image file resides in –
http://shibashake.com/wp-content/blogs.dir/2/files/2012/12/dog-image1.jpg
In normal circumstances, the shorter image url will be automatically translated through our site .htaccess file. When we use a CDN, however, server side address changes may not be available. I recently switched to from Media Temple’s ProCDN to Amazon CloudFront. CloudFront (in pull mode) can actually grab files dynamically from the server, so it can handle this issue transparently. However, this will likely cause some delays when the images are first loaded or when they expire. ProCDN does not do dynamic pull, so we need to pre-translate the urls.
In Amazon CloudFront my image urls look something like this –
http://a2bcdef0ghij24.cloudfront.net/dog/files/2012/12/dog-image1.jpg
The actual image file, however, is in –
http://a2bcdef0ghij24.cloudfront.net/wp-content/blogs.dir/2/files/2012/12/dog-image1.jpg
We can just let CloudFront dynamically pull the images again when a page gets accessed, but if we want to avoid double pulling or simplify things for a push setup, we can do the link translation within the w3tc plugin. This will also be needed for systems like ProCDN which does not support dynamic pull.
Note – This is an advanced tutorial which involves editing core plugin files. Only do this if you are familiar with PHP, have ftp access, and know how to restore plugins back to their original state.
Here is what I do to translate my multisite CDN image links –
- I open the file w3-total-cache/lib/W3/Plugin/Cdn.php in the w3tc plugin.
- I look for the link_replace_callback function. This is the function which reformats relevant urls so that they point to our CDN.
- Within this function, I look for the line,
return $r;
then, I add in this line of code directly before it.
$r = apply_filters('shiba_cdn_remote_file_name', $r);
- Now, I can change my CDN urls by hooking into the shiba_cdn_remote_file_name filter.
For example, a general url replace function may look like this –
// Add to init action hook add_filter('shiba_cdn_remote_file_name', 'my_cdn_url'); function my_cdn_url($url) { global $blog_id, $current_blog, $current_site; $targetStr = $current_blog->path . 'files'; if (strpos($url, $targetStr) !== FALSE) { $url = str_replace($targetStr, "{$current_site->path}wp-content/blogs.dir/{$blog_id}/files", $url); } return $url; }
Here are the WPMU global variables. We can also use the get_blog_details function.
Since our blog path and blog_id stays constant, we can also just use those constant values.