Kirby Assets Refresh - SHUT DOWN

I know there are already plugin for what they use to call cache busting. The difference with this one is that you don’t need to modify your htaccess file.

https://github.com/jenstornell/kirby-assets-refresh

To use it you simple add an r to the function, like this:

echo cssr('assets/css/site.css');

or

echo jsr('assets/css/site.css');

It supports the same arguments as the original functions does.

Be aware! Kirby has a bug in 2.3 beta which prevent the css and js to work with arrays. It will probably be fixed soon, but it can break this plugin in Kirby 2.3 beta.

I generally add a timestamp to the the css / js call, to prevent cache, like this:

<?php echo css('assets/css/site.css?v='.time().' ?>

Isn’t this the same as cache busting ? :slight_smile:

Yes, my plugin does the same thing.

The difference between your solution and the plugin would be that the plugin makes you write less code in the template/snippet and it support arrays.

Your code if you would use an array:

echo css(array(
  'assets/css/site.css?v='.time(),
  'assets/css/form.css?v='.time(),
  'assets/css/grid.css?v='.time()
))

You also would need some if statement to not refresh cache when not logged in.

With the plugin for the same thing:

echo cssr(array(
  'assets/css/site.css',
  'assets/css/form.css',
  'assets/css/grid.css'
))

A little shorter and don’t need to check if the user is logged in or not. It’s done automatically by the function.

As up today I’ve done it just like you. What does v stand for? I use `r´, which stands for refresh.

Why are you using time() and not filemtime()? Using filemtime the Browser will cache the File until it has actually changed.

3 Likes

That’s what I would recommend as well. The official cachebuster plugin does it like that as well and it even uses the native css and js functions so that there is no template change needed.
Apart from requiring rewrite rules, is there anything that you don’t like about the cachebuster plugin?

That’s the main reason. I don’t like to change the htaccess file If I don’t need to.

I don’t think any solution is better than the other. I prefer php, some prefer htaccess.

The rewriting solution does have advantages: Some environments don’t cache resources at all if they have a query string (i.e. if they contain a question mark). So including the file modification time in the filename is safer.

I have experienced this with a proxy server and also when using appcache manifests, so I always prefer the rewriting solution from now on.

Regarding the “which solution is better” part: That always depends on the use-case of course. But in my opinion it is essential to use the file modification time instead of the current time, otherwise you could just disable caching completely. Nothing will be cached if you use the current time. :wink:

3 Likes

There are other options as well. If you use gulp/gulp-rev, you get files with a hashed suffix and a rev-manifest file from which you can fetch the correct filename without changing the .htaccess. A bit more to write, but no changes to the .htaccess and no changes to the css/js helpers. And the suffix is part of the filename.

The thing I don’t understand about your plugin, @jenstornell, is the signed in users bit. I would want all my users to get the latest files?

1 Like

like @texnixe mentioned there is a gulp task for hashing your assets like js / css or even image files.

I think the real downside of your @jenstornell plugin is that by using the “time()” function you will disable any browser caching of your asset files? I’m not sure if that is the right thing to do because you want returning visitors to already have your assets in their cach.

For me I prefer to hash the assets via gulp, so when the content changes then my file changes and if the asset stays the same the hash will not change and so the user can get a cached version.

That’s exactly how it should work. In fact, you want to set the assets to never expire and then control cache busting via the hashed file. Using time() to bust the cache on every page load is really counterproductive.

Thanks for all the positive feedback I’ve got. :wink:

I’ve looked into all your suggestions and released a new version:

https://github.com/jenstornell/kirby-assets-refresh

In the html it looks like this:

<link rel="stylesheet" href="http://localhost/assets-refresh/assets/css/test-1461571548.css">
<script src="http://localhost/assets-refresh/assets/js/test-1461571763.js"></script>  

Some changes based on your suggestions:

  • It does no longer rely on a $_GET variable. Instead it rewrites the filename.
  • It does no longer rely on a timestamp. Instead it looks at when the file was updated.
  • It does no longer check if the user is logged in.

Thanks @Pascalmh @lukasbestle @texnixe

I’m considering to move to Gulp Rev as you suggested. It works well except for that it adds a new file on every save.

Do you know how only keep the latest prefixed file (and the original)?

Now it looks like this:

index-5b1bc87684.min.css
index-035387c2f5.min.css
index-e344af7a5a.min.css
index.min.css

What I want:

index-e344af7a5a.min.css
index.min.css

It’s possible with rename or delete tasks, but maybe there is a better way?

I think I got it working now:

This is my final css gulp task:

gulp.task('css', function() {
	gulp.src('site/patterns/site/site.scss')
		.pipe(sass().on('error', sass.logError))
		.pipe(autoprefixer())
		.pipe(rename('index.css'))
		.pipe(gulp.dest('assets/css'))
		.pipe(minifyCss())
		.pipe(rev())
		.pipe(gulp.dest('assets/css'))
		.pipe(rev.manifest())
		.pipe(revDel({ dest: 'assets/css' }))
		.pipe(gulp.dest('assets/css'))
		.pipe(notify("CSS generated!"))
	;
});

The magic is using:

Update

Most of the time it did not work. I ended up with this instead:

// CSS
gulp.task('css', function() {
	gulp.src('site/patterns/site/site.scss')
		.pipe(sass().on('error', sass.logError))
		.pipe(autoprefixer())
		.pipe(rename('index.css'))
		.pipe(minifyCss())
		.pipe(rev())
		.pipe(gulp.dest('assets/css'))
		.pipe(rev.manifest())
		.pipe(gulp.dest('assets'))
		.pipe(notify("CSS generated!"))
	;
});

gulp.task('clean-css', ['css'], function() {
	gulp.src( ['assets/css/index-*.css'], {read: false})
		.pipe( revOutdated(1) )
		.pipe( cleaner() );
	return;
});

Now the magic is done by https://github.com/shonny-ua/gulp-rev-outdated. It’s more stupid and more agressive, but it works.

I’ve worked with gulp-rev and gulp-rev-outdated on a big project, not really fond of it but it works (somewhat…) and if you have that kind of technical requirements I guess it helps.

One pitfall with gulp-rev (and any similar approach) is that you’ll probably forgot to use it for parts of your assets, e.g. you used it for CSS and JS but not for your SVG sprites or some of the layout images -> bam, disconnect between your styles or scripts and the files they reference.

For small projects I’m happy with adding a query string to asset URLs, even a manually managed, global one, or a per-file one based on filemtime (as in Get path to assets/images).

1 Like

This plugin was not good enough. I have now shut it down.