4

Is there any way of achieving a similar versioning solution on a CDN (not Cloudfront, Edgecast in this case) for js and css files as the rather neat one, combining a Rewrite rule and PHP, described in this thread? I don't know of a way of making that PHP/mod-rewrite combination work on a CDN, change my versions often, and don't want to do the versioning manually. I use a cookieless, entirely separate domain to serve static content, so I have to specify the full url in the function.

For convenience I'll set out the code from the other thread here.

First, we use the following rewrite rule in .htaccess:

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-s # Make the file doesn't actually exist
RewriteRule ^(.*)\.[\d]+\.(css|js)$ $1.$2 [L] # Strip out the version number

Now, we write the following PHP function:

/**
 *  Given a file, i.e. /css/base.css, replaces it with a string containing the
 *  file's mtime, i.e. /css/base.1221534296.css.
 *  
 *  @param $file  The file to be loaded.  Must be an absolute path (i.e.
 *                starting with slash).
 */
function auto_version($file)
{
  if(strpos($file, '/') !== 0 || !file_exists($_SERVER['DOCUMENT_ROOT'] . $file))
    return $file;

  $mtime = filemtime($_SERVER['DOCUMENT_ROOT'] . $file);
  return preg_replace('{\\.([^./]+)$}', ".$mtime.\$1", $file);
}

Now, wherever we include our CSS, we change it from this:

<link rel="stylesheet" href="/css/base.css" type="text/css" />

to this:

<link rel="stylesheet" href="<?=auto_version('/css/base.css')?>" type="text/css" />

This will render as something of this kind, ensuring the latest version is always served, without having to update versions manually:

<link rel="stylesheet" href="/css/base.1251992914.css" type="text/css" />

In order to get this working in an external CDN (on a totally different domain), I've tried to replace

<link rel="stylesheet" href="<?=auto_version('/css/base.css')?>" type="text/css" />

by something like this...

<link rel="stylesheet" href="<?='http://cdn.externaldomain.com' . auto_version('/css/base.css')?>" type="text/css" />

But wrapping the function around the internal URL and adding the CDN domain doesn't seem to work...

Community
  • 1
  • 1
Donald Jenkins
  • 3,485
  • 8
  • 33
  • 35

2 Answers2

3

It turns out my solution:

<link rel="stylesheet" href="<?= 'http://cdn.externaldomain.com' . auto_version('/css/base.css') ?>" type="text/css" />

works. I'd just missed out a space in the code.

Donald Jenkins
  • 3,485
  • 8
  • 33
  • 35
1

Just a suggestion: Have a look at Aptimize

Versioning issues solved. Many CDNs perform only periodic version checking – meaning pages can be served with out-of-date resources. Aptimize actively detects version changes and ensures pages stay up-to-date, with a unique auto-URL versioning mechanism and aggressive caching of resources on the browser.

ThinkingMonkey
  • 12,539
  • 13
  • 57
  • 81
  • Thanks for the suggestion: I'd vaguely heard of it a while ago, it looks like a good product, I may want to try it out. In the mean time, though, my own suggested solution (placing the URL outside the function) ended up working after all: there was just a typo in the code… :) – Donald Jenkins Mar 01 '12 at 03:20
  • Yeah, I was pleased, must admit. But Aptimize looks totally cool: thanks again for suggesting it, I'll be asking for a trial, it may be useful anyway. – Donald Jenkins Mar 01 '12 at 03:27