This is working well when writing ââ directly in my twig templates, but it is not working when I write â{% do assets.addCss(âtheme://css/styles.123.cssâ, 100) %}â because the asset manager needs to confirm that the file exists (and the physical file doesnât the version number).
I donât understand the problem. When you update the file, Grav should automatically invalidate the cache for that file. You shouldnât have to do anything weird. I certainly never have problems when Iâm developing a theme, for example. I update the CSS file, refresh, and the changes are there.
The nuclear option is to bin/grav clearcache after you update the CSS file, but that shouldnât be necessary.
I may have missed some Grav options but how does Grav (server side) force refresh the CSS on the client browsers cache? I do have the problem that when I update a CSS file I have to force refreshing the page (CTRL+F5) to see the modifications.
In my present configuration (which is the default), I donât see any query strings appended to the css file names in the HTML produced by Grav. In system.yaml, there is an option âenable_asset_timestampâ which allows to bust the cache by adding a timestamp to the asset names, but this is too aggressive and I would rather control this on a version basis.
You only have to Ctrl+F5 because youâre developing in real time. Assuming someone doesnât visit your site multiple times a day, this just shouldnât be a problem. A well behaving client will check the freshness of its cache periodically. A simple HEAD request will show that it has changed, and it will refresh it.
These sorts of cache busting techniques are (in my opinion) rude, for lack of a better word. They subvert the whole purpose of the standard and of caching in general. CSS files are hardly critical. The client should have the right to choose how frequently to refresh their cache. And if they see the site isnât looking right, they can Ctrl+F5 themselves and refresh it directly.
Whether it is âethicalâ or not to do cache busting is another discussion.
In my opinion, the html tag lacks of some kind of timestamp attribute that would indicate to the browser if itâs necessary to request the CSS via HTTP.
I think this would be smoother for both the client and the developer.
Now I am a bit confused about what you are saying because that is a bit different to what I observed.
Are you talking about the browser here? I often see cases where the cache is not refreshed for several days.
You also used âclientâ in this sentence, but I guess you refer to the user here. Well, I think that many users donât even know about âCtrl+F5â. And even if they know it, is it their role to investigate whether the styles look right or not? This is assuming they know how the styles should look⌠(Btw, I know users who would clear the whole cache of the browser, which in this case would certainly subvert the purpose of caching). I think itâs fairly reasonable to assume that the developer, who edit the files, is the best placed to indicate when a new version is published. Of course this requires some self-discipline to do a proper versioning. On the other hand, the grav option âenable_asset_timestampâ is (in my opinion) not the good policy as it doesnât reflect the changes made on the files.
To go back to the original question: How can I solve the issue of the first post if the file âstyles.123.cssâ doesnât exist physically?
I apologize for sidetracking the conversation. I do not know of a native way to make Grav recognize these âvirtualâ files. If your method is deterministic, then you could maybe create a plugin that does some mapping on the back end. Or if you just create the version numbers manually, then maybe the plugin could consult a map file or something. Having never done this myself, I donât know off the top of my head. Iâd start with the Grav Lifecycle (in particular the onAssetsInitialized event) and then look at other plugins to see what sorts of things others have done with that event. And maybe someone else will reply to this post.
Ignore this paragraph if you wish. Just responding to your questions: âClientâ refers to the softwareâthe browser. It comes with certain defaults and can be configured by a user to refresh the cache after different periods of time. My only point is that itâs not the serverâs role to force things on the client. The HTTP standard makes mechanisms available to signal to the client that resources have changed. A âwell-behavedâ server leverages the standard and lets the client do its job. Thereâs no need for a âtimestampâ attribute, for example. The standard has ways of managing this very thing. You can set the cache-control header, for example, to suggest to the client to check more often than it normally would. I was just suggesting that maybe there are simpler solutions to your problem.
Thank you for your reply. Itâs not a problem at all to drift a bit from the original question. I think the cache discussion is actually very interesting.
I get your standpoint that the server should not force the client to update stuffs. I agree that always forcing to load CSSs or arbitrarily force at regular interval would be bad⌠I was more thinking about a way to indicate to the client when a new version of the asset is published (it is always more efficient to inform than having to check multiple times at regular interval). If there was a timestamp (or a version) attribute in the link tag, the browser would not need such thing like regularly send a HEAD request to the server to check the fileâs status. It would simply compare the timestamp (date of the new version) to the last loaded time and update it if necessary. This would btw be a better technique than what I want to do because then the file could be replaced in the cache instead of cluttering it⌠but anyway it was just a thought and it doesnât exist.
Of course the client (the browser) can surely be configured, but most users wonât do it and might not get updated for several days when a new script or CSS is published. Updating the cache-control header to check more often would make the problem âless worseâ⌠but would also increase unnecessary requests in normal time (when nothing is updated).
I will look at the onAssetsInitialized event. Developing a plugin might be interesting. I heard that WordPress natively has a way to control cache and assets versioning via query strings, and I think that could be a good thing to have a similar mechanism in Grav.
@mathmax I may be mistaken, but it seems that server side caching by Grav and client side caching by the browser are a bit mixed-up in the discussion.
TL;DR: Enabling Gravâs Assets pipelines leads to cache busting.
I guess the OP is talking about busting the browser cache by renaming the resource (js, css), or by adding a querystring when a resource has changed. When the page is refreshed, the document contains references to the new resources. The browser can no longer use the css/js from cache and has to request the new css/js file from the server.
When enabling Gravâs Assets pipelines, cache busting will happen automatically. When the css/js pipelines are enabled, Grav will process the resources and if any file has changed, a new filename will be created. This will force the browser to fetch the new css/js file when the browser has refreshed the page from the server.
Renaming files are just one part of the whole. Cache expiration, caching directives and cache validators/validation are another part.