Cache-bust local css/js so a deploy is picked up immediately
Apache serves this site's static files with only Last-Modified/ETag and no Cache-Control or Expires, so browsers apply heuristic freshness and can hold a stale stylesheet for hours. Deploys here are a file copy, so nothing else signals a change. During development this masked CSS edits three separate times; on the live site a returning customer would keep the old stylesheet after a deploy with no way to know. Adds asset_ver() (autoloaded), which returns the asset URL with the file's mtime appended, so the URL itself changes whenever the file does. Falls back to the plain URL when the file is missing, so a bad path degrades to the previous behaviour rather than warning. All 54 local css/js links now route through it, across the four *-head.php and four *-skeleton-bottom.php includes. Notes - Remote assets are deliberately untouched: Google Fonts, momentjs, cookieyes and the googleapis jQuery keep their own URLs. Only files inside the webroot are versioned. - vertical-head.php has one dynamic path (assets/css/<?= $vertical['css'] ?>) which is special-cased; a generic rewrite would swallow the nested <?php. - Images are NOT versioned. Replacing an image under the same filename can still serve stale. - head.php is shared by the public home page and the whole admin portal; /login verified to still render with versioned CSS. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
defined('BASEPATH') OR exit('No direct script access allowed');
|
||||
|
||||
/**
|
||||
* Cache-busting asset URLs.
|
||||
*
|
||||
* Apache serves this site's static files with only Last-Modified/ETag and no
|
||||
* Cache-Control or Expires header, so browsers fall back to heuristic freshness
|
||||
* and can hold a stale stylesheet for hours after a deploy. Because deploys here
|
||||
* are a file copy, there is no other signal that anything changed - during
|
||||
* development this repeatedly masked CSS edits, and on the live site a returning
|
||||
* customer would keep the old stylesheet with no way to know.
|
||||
*
|
||||
* Appending the file's mtime makes the URL itself change whenever the file does,
|
||||
* so the browser is forced to refetch. It costs one stat() per asset, which PHP
|
||||
* caches per request.
|
||||
*/
|
||||
|
||||
if ( ! function_exists('asset_ver'))
|
||||
{
|
||||
/**
|
||||
* Absolute URL for a local asset, with ?v=<mtime> appended.
|
||||
*
|
||||
* Only for files inside the webroot. Remote assets (Google Fonts, the
|
||||
* cookieyes script, momentjs) must keep their own URLs untouched.
|
||||
*
|
||||
* Falls back to the plain URL when the file is missing, so a bad path
|
||||
* degrades to the previous behaviour rather than emitting a warning.
|
||||
*
|
||||
* @param string $path webroot-relative, e.g. 'assets/css/main.css'
|
||||
* @return string
|
||||
*/
|
||||
function asset_ver($path)
|
||||
{
|
||||
$path = ltrim((string) $path, '/');
|
||||
$url = rtrim(SITEURL, '/').'/'.$path;
|
||||
|
||||
$file = FCPATH.$path;
|
||||
|
||||
if ($path !== '' && is_file($file))
|
||||
{
|
||||
$url .= (strpos($url, '?') === FALSE ? '?' : '&').'v='.filemtime($file);
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user