Feb 04

New ExpressionEngine extension: Cachebuster

Categories:
Tags:
, , , , ,
Published:
8:06am on Wednesday 4th February, 2009

Ever find yourself explaining to a client (for the umpteenth time) how to press F5 so they can see the changes you just made to their site? If you’re being responsible in terms of performance by setting far-future expiry dates on your site assets, clearing the cache is often necessary to pick up minor tweaks to CSS or JavaScript - but rather than deal with yet another email from a confused client, wondering why their site layout is broken, I thought I’d find a way to automate this step.

Who ya gonna call?

Cachebuster is a new ExpressionEngine extension that allows you to automatically append a variable to your external CSS or JavaScript files. Changing this variable when you update a file tells your visitor’s browser that it is a new file and should be re-downloaded, instead of using a cached version. For a full explanation, see Stefan Hayden’s post on CSS Caching from 2006.

Installation

As this extension relies on hacking the core EE files, it is NOT recommended for mission-critical sites or applications. However, if you are confident that you can maintain the necessary hack (including when upgrading) you shouldn’t have any problems. (If you forget to upgrade, the extension will fail silently.)

Hacking a new hook

Open the /system/core/core.output.php file and locate the following lines (around line 272 in EE1.6.5):

/**—————————————————-
/**  Fetch the buffered output
/**—————————————————-*/
		
echo $output;

We are going to add a new hook for our extension to allow us to manipulate the HTML output just prior to sending it to the browser. Add the new lines shown below:

/**—————————————————-
/**  Fetch the buffered output
/**—————————————————-*/
		
// MGP Cachebuster 030209: Added new hook to do stuff with 
// the final browser output
if (isset($EXT->extensions[‘before_display_final_output’]))
{
    $output = $EXT->call_extension('before_display_final_ »
output’, $output);
}
        
echo $output;

We also need to make sure we can refer to the $EXT object - scroll up to the start of the display_final_output() function (around line 94) and add $EXT to the declared globals on the first line of the function:

global $IN, $PREFS, $TMPL, $BM, $DB, $SESS, $FNS, $LOC, $EXT;

Installing the extension

Installing the Cachebuster extension is exactly the same as installing any other extension:

  1. Copy the ext.cachebuster.php file into /system/extensions
  2. Copy lang.cachebuster.php into /system/language/english
  3. Visit your Extensions Manager and enable the new extension

Using the Cachebuster

When you visit the Settings page for the Cachebuster extension, you will see five fields:

  • Current version – This is the version number that will be appended to CSS or JS files to force visitors to load the latest version instead of a cached version
  • Apply version numbers to CSS files – Choose whether you want to control CSS files
  • CSS filenames – A comma-separated list of stylesheets you want to affect (either with or without the ”.css” extension)
  • Apply version numbers to JavaScript files – Choose whether you want to control JavaScript files
  • JavaScript filenames – A comma-separated list of external scripts you want to affect (either with or without the ”.js” extension)

Every time you make a change to a CSS or JavaScript file and upload it to the live website, you can now login to the Cachebuster extension settings and increment the version counter. Any files flagged for inclusion will have that number appended to their filename:

<link rel=“stylesheet” type=“text/css” href=”/css/layout.css »
?v=42”>

Feedback and bug reports

There are a few obvious drawbacks to this version 1.0 of the extension. The most obvious one is the need for a hack to the core EE files - hopefully EE2.0 will introduce new hooks we can use without the need to hack.

The extension also appends the version number to every file (or at least those listed in the settings); this means that even if you have only edited one file, incrementing the version number will force visitors to download every file as if it were new. Of course, for true speed tweaks you should be concatenating your stylesheets and script files, so you should only have one or two external files at most.

If you have any suggestions for how to improve Cachebuster, please either comment below or on the GitHub Wiki for Cachebuster.

What is GitHub? GitHub is a web application that uses the version control software Git to allow its members to manage their code online. I am hosting the files for this article there so that any bugfixes or improvements I make can be found in one central location.

I'd love to hear what you think - please use the form below to leave your comments. Some HTML is permitted: b, i, em, del, ins, strong, pre, code, blockquote, abbr. URLs or email addresses will be automatically converted into links.

Comment Form

  1. Rommi's Gravatar

    Rommi at 4:48pm on 26th June, 2009 #

    Cachebuster will be excellent for Expression users, Thanks for this.

  2. Jim Bechdel's Gravatar

    Jim Bechdel at 8:41pm on 6th March, 2010 #

    I was sent to you because the last forum I was on said this what I may need to do to solve my problem. They said I need to do a cachebuster?
    When I make changes in my xml file on the server they won’t change on my site. The only changes that work is if I add new images and make those changes in the xml file it’s ok but if I try to change the order of the images or add new text that is at the bottom of each image it won’t change. I’m on a Mac with the latest Snow Leopard OS. I use Transmit for my ftp browser.

  3. Matthew Pennell's Gravatar

    Matthew Pennell at 7:46am on 7th March, 2010 #

    Hi Jim - what is your XML file used for, and how is it referenced by your HTML page?

    This extension currently only works for JS and CSS files, but it could be hacked to work with other filetypes.