Cache Busting for CSS stored in database (Kentico 8.2)

Peter Wooster asked on March 10, 2020 23:50

I want to use a fingerprinting or cache busting function on CSS that is stored in the database and referenced from Development/CSS Stylesheets App in Kentico 8.2. I've read dozens of posts online that recommend using a macro based on Mads Kristensen's post from 2014. They all work on the assumption I can pass the source url to the C# code or a macro.

Is there a way to do this with CSS from the database?

Correct Answer

Brenden Kehren answered on March 11, 2020 03:54

Do something like this then in a HTML webpart.

<link href="~/CMSPages/GetResource.ashx?stylesheetname=stylesheetcodename&vid={%GlobalObjects.CssStylesheets.StyleSheetCodeName.StylesheetVersionGUID%}" type="text/css" rel="stylesheet"/>

The URL parameter name can be whatever you want it will never be used for anything other than breaking the clients cache when the version history changes.

0 votesVote for this answer Unmark Correct answer

Recent Answers


Brenden Kehren answered on March 11, 2020 03:07

I'm not following your request fully. Can you provide some examples of what you want and what you've tried? I use a macro to append the CSS stylesheets version history guid to update a bogus URL parameter so it updates the clients browser cache. It works well but not sure it will work for what you're looking for.

0 votesVote for this answer Mark as a Correct answer

Peter Wooster answered on March 11, 2020 03:35

What I want is exactly what you described. Where do I find something unique such as that GUID and how do I specify the bogus URL in GetResource? I had intended to add a query string to the URL as I prefer a solution that doesn't require a rewrite in web.config.

The code in the master page is: href="/CMSPages/GetResource.ashx?stylesheetname=DYN-MainStyles"

I haven't tried anything yet because I got stopped at this point while researching the solution.

0 votesVote for this answer Mark as a Correct answer

Peter Wooster answered on March 11, 2020 13:22

I built a test stylesheet in the database with codename=DYN-PKWTest and added it to the Head on the root page with a vid parameter based on your example. The macro evaluates to 0. Here's the code:

href="/CMSPages/GetResource.ashx?stylesheetname=DYN-PKWTest&vid={%GlobalObjects.CssStylesheets.DYN-PKWTest.StylesheetVersionGUID%}"

In the Chrome developer tools I see:

href="/CMSPages/GetResource.ashx?stylesheetname=DYN-PKWTest&vid=0"

0 votesVote for this answer Mark as a Correct answer

Brenden Kehren answered on March 11, 2020 13:25

That macro works for version 11 and newer so maybe you'll have to try another property to find the version history value. I chose something which was different after the stylesheet was saved.

0 votesVote for this answer Mark as a Correct answer

Peter Wooster answered on March 11, 2020 14:02

Is there any documentation on these properties? How do I display the available properties?

0 votesVote for this answer Mark as a Correct answer

Brenden Kehren answered on March 11, 2020 14:30

No documentation that I'm aware of for all the macro properties. You may need to restart your application pool or clear the cache on your website to get the macro to work properly. And I just tested in 8.2 and it works as expected.

0 votesVote for this answer Mark as a Correct answer

Peter Wooster answered on March 11, 2020 15:17

I cleared the cache and restarted the application from the System tab. The value is still 0. I've put a request into operations to restart the application pool. That may take a while. I'll let you know if it works.

0 votesVote for this answer Mark as a Correct answer

Brenden Kehren answered on March 11, 2020 16:31

That could also be a valid value if you dont have versioning turned on. Check out the settings to see if it's turned on.

0 votesVote for this answer Mark as a Correct answer

Peter Wooster answered on March 11, 2020 16:52

Versioning is on, and that stylesheet has version numbers, Modified and StylesheetGUID and StylesheetVersionGUID properties in the CSS Stylesheets App.

I tried the macro in a Static HTML Webpart and it show 0 there as well as in the MasterPage.

0 votesVote for this answer Mark as a Correct answer

Brenden Kehren answered on March 11, 2020 16:58

Do some testing then with the macro console in System > Macros > Console and see what you come up with.

0 votesVote for this answer Mark as a Correct answer

Peter Wooster answered on March 11, 2020 17:01

Thanks, I'll give that a try.

0 votesVote for this answer Mark as a Correct answer

Peter Wooster answered on March 11, 2020 23:01

The macro console solved the problem. It chose the syntax which works:

{%GlobalObjects.CssStylesheets["DYN-PKWTest"].StylesheetLastModified%}

The one I was using was

{%GlobalObjects.CssStylesheets.DYN-PKWTest.StylesheetLastModified%}

which fails and always returns null because of the - in the stylesheet name. This code is using C# syntax and - is minus, not hyphen, unless quoted. I also switched to using StylesheetLastModified as it is more readable. Also the console provides that list of properties I was looking for.

Thanks, I learned a lot about macros today.

0 votesVote for this answer Mark as a Correct answer

Brenden Kehren answered on March 11, 2020 23:05

StylesheetLastModified is not a URL friendly string like the guid is, so be sure to urlencode it. Plus is there any reason to make it readable?

0 votesVote for this answer Mark as a Correct answer

Peter Wooster answered on March 12, 2020 01:04

The readability is mainly for testing, so I can tell which version I'm getting. I may switch back to the guid when this goes into production.

0 votesVote for this answer Mark as a Correct answer

Peter Wooster answered on March 12, 2020 16:53

I've got this to work everywhere except the main style sheet which is specified in the root page properties > General > Design > CSS stylesheet. This is chosen from a dropdown list of stylesheets in the Development > CSS Stylesheets App.

It also doesn't work for stylesheets loaded from the file system using a CSS Stylesheet Web Part. This is less serious as these change rarely.

Is it safe to load these from the Master Page Layout, or is there a better solution that allows the use of the macro?

0 votesVote for this answer Mark as a Correct answer

Brenden Kehren answered on March 12, 2020 17:07

You can reference other stylesheets in your main styleshet you call in your masterpage like so:

{%CSS["StylesheetCodeName1"]%}
{%CSS["StylesheetCodeName2"]%}

body { }
....

Then there is no need to call it multiple times. The CSS macro will simply inject the css from the other stylesheets into the one you're calling. You'll have a few extra SQL calls but you'll cut down your page load and HTTP requests on the front side.

0 votesVote for this answer Mark as a Correct answer

Peter Wooster answered on March 12, 2020 18:09

But without the HTTP requests how do I do the cache busting? The browser will always cache the outer CSS file and never see the source or guid of the inner ones so they also get cached.

I will be combining the CSS files where possible, but I need a way to add the cache busting code to the main stylesheet that is being chosen from a dropdown in the masterpage properties, or a better place to call it that allows the macro to be used,

0 votesVote for this answer Mark as a Correct answer

Brenden Kehren answered on March 12, 2020 19:08

The one you call from your master page will have the macro on it. The others are called when that page is requested and will be cached within Kentico until they need to be refreshed.

0 votesVote for this answer Mark as a Correct answer

Peter Wooster answered on March 12, 2020 19:14

Then the browser won't know they have changed.

0 votesVote for this answer Mark as a Correct answer

Brenden Kehren answered on March 12, 2020 19:16

The other style sheets that you would typically include would be ones that wouldn't change or would change very infrequently like bootstrap or some plug-in style sheet not your main style sheet.

0 votesVote for this answer Mark as a Correct answer

   Please, sign in to be able to submit a new answer.