This solution is written in PHP, but it should be easily adapted to other languages.
The original .htaccess
regex can cause problems with files like json-1.3.js
. The solution is to only rewrite if there are exactly 10 digits at the end. (Because 10 digits covers all timestamps from 9/9/2001 to 11/20/2286.)
First, we use the following rewrite rule in .htaccess:
RewriteEngine on
RewriteRule ^(.*)\.[\d]{10}\.(css|js)$ $1.$2 [L]
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 you include your CSS, change it from this:
<link rel="stylesheet" href="/css/base.css" type="text/css" />
To this:
<link rel="stylesheet" href="<?php echo auto_version('/css/base.css'); ?>" type="text/css" />
This way, you never have to modify the link tag again, and the user will always see the latest CSS. The browser will be able to cache the CSS file, but when you make any changes to your CSS the browser will see this as a new URL, so it won't use the cached copy.
This can also work with images, favicons, and JavaScript. Basically anything that is not dynamically generated.
since master page is like a control embedded in a page, you can add these scripts towards the end of the page cycle, the control would fire first and then page, so your page would be fine.
Best Answer
Use Page_Init in your MasterPage to make code run before child page and UserControl Page_Load events.
Don't forget to do the occasional "View Source" as a sanity check. You gotta make sure that stuff goes into the response in the order you expect.
The client script used in your UserControls will not execute until the response is sent to the user agent, so as long as the jQuery libraries are included earlier in the response, you should be ok. This is not actually a lifecycle issue unless you have server code mixed in with the client code that you are sending.
I have this in the head of my MasterPage
and this in the codebehind:
This allows me to have it minified or hosted by google in production, but use the full version in dev, with intellisense.
Don't forget this in your Page_Load to get ResolveUrl to work:
Hope this helps. :)