Hello there,
I have been coding WordPress themes for the last years and now I am building my first website with Kirby CMS. Looks very promising and I am looking forward to doing a lot more Kirby projects in the future. I have added the yarn/webpack pipeline from the Sage WP theme (GitHub - roots/sage: WordPress starter theme with Laravel Blade components and templates, Tailwind CSS, and block editor support), which has integrated cachebusting. Now I am facing the question how I can get the generated hashed versions of JS or CSS files to the website code.
In Kirby we tend to do the cache busting for CSS/JS in a tooling agnostic manner via plugins who automate this for your via PHP. Then you can safely remove the cache busting part from your development pipeline.
A more lightweight method would be to add a css and js component in a plugin.
You can do something like this and use the default css() and js() helper functions.
This solution will “only” add a query string with the current timestamp of the file. But in most cases this is sufficient. And if you do not user the @auto feature you can ditch the complete if statement.
Query strings for cache busting is an anti-pattern as it confuses proxies etc. Adding it to the file name should do the trick.
Imho this should be in core, as it works this way for the assets from the plugins. I’ve added this as enhancement request in github: https://github.com/getkirby/kirby/issues/1474
<?php
/**
* Get cache-busting hashed filename from assets.json.
*
* @param string $filename Original name of the file.
* @return string Current cache-busting hashed name of the file.
*/
function get_hashed_asset( $filename ) {
// Cache the decoded manifest so that we only read it in once.
static $manifest = null;
if ( null === $manifest ) {
$manifest_path = kirby::instance()->roots()->assets() . '/assets.json';
$manifest = file_exists( $manifest_path )
? json_decode( file_get_contents( $manifest_path ), true )
: [];
}
// Get rid of asset folder in path to match filename in manifest
$filename = str_replace('assets/', '', $filename);
// If the manifest contains the requested file, return the hashed name.
if ( array_key_exists( $filename, $manifest ) ) {
$hashed_filename = $manifest[ $filename ];
// Add asset folder path to hashed file again
return 'assets/' . $hashed_filename;
}
// Assume the file has not been hashed, when it was not found within the manifest and add asset folder path
return 'assets/' . $filename;
}
Kirby::plugin('test/cachebusting', [
'components' => [
'css' => function ($kirby, $url, $options) {
return get_hashed_asset($url);
},
'js' => function ($kirby, $url, $options) {
return get_hashed_asset($url);
}
],
]);
It works, but for sure it can be improved. It checks, if an json-manifest file exists + simply compares the filenames. If there is a hashed version the filename is adjusted. I appreciate your suggestions or feedback. Thanks!