Versioning CSS and JavaScript files in MODx Evolution

In this article I'd like to show you a simple way how to force browser cache for static resources like CSS and JavaScript files simultaneously with cache clearing from the Manager area in MODx Evolution.

You probably know that if you add a some parameter to a query string inside of HTML code, then the browser will update this file and ignore its cached version. For example:

style.css?v=2013-07-27

Above we added an additional v parameter marked with the date when the file was last updated. This way we avoid the caching issue, when the new CSS version is placed on server, but the visitor's browser still uses outdated stylesheet version and the site look is messed up.

To render the value of v parameter in a query string, I use the CacheStamp snippet. It returns the timestamp of last cache update and allows me update the version of all required static resources by simple clearing of MODx cache.

Example:

<link rel="stylesheet" type="text/css" href="assets/css/style.css?v=[[CacheStamp]]">

Of course, the v parameter may be called by any name you like.

Snippet code:

<?php
$cachePath = MODX_BASE_PATH.'assets/cache/';
$cacheFile = $cachePath.'cacheStamp.pageCache.php';

if (!isset($GLOBALS['cacheStamp'])) {
    if (is_file($cacheFile))
        $GLOBALS['cacheStamp'] = (int) file_get_contents($cacheFile);
    else {
        $GLOBALS['cacheStamp'] = time();
        file_put_contents($cacheFile, $GLOBALS['cacheStamp']);
    }
}

return $GLOBALS['cacheStamp'];

The snippet uses a feature of MODx Evo caching system: on update, all files with .pageCache.php extension, which are located in assets/cache folder, are removed. Thus, the obvious solution is to store the timestamp inside of the specific file with the mentioned extension and read the value from the file when snippet is called. If the file does not exists, we should create it and write current timestamp given by time() function. Also, to avoid the redundant filesystem queries on multiple snippet call, the timestamp value, being received from file, is stored to global variable for reusing.

But wait. You may ask, why are we doing that manipulations with the file instead of simple returning the timestamp value from snippet which will be cached by MODx automatically?

Well, first, the MODx uses per-page caching. It means that the timestamp will be various for different pages. It will cause additional server requests, because browser will reload the same static resource for each page. Second, in some cases you may need to turn off the MODx cache for whole page, but the timestamp must remain unchanged. That was the main reasons.

Browse on GitHub

By on
If you want to repost this article, please keep the source hyperlink