One of the many great features built in to Umbraco that I use on a daily basis, is it’s ability to cache the output of your Macros. This is great if you have a processor intensive Macro that doesn’t change too often, or if you have a high traffic site, and want to maximise on response times. The best thing about this, is just how easy it is to do.
Within the macro properties tab, simply set the cache duration and optionaly check one or more options on how you want to cache the Macro.

If no options are checked, the Macro will be cached for the cache period regardless. Checking the Cache by Page option, caches the Macros output on a page per page basis, and checking Cache Personlized caches the Macros output per Member. You can also combine the two options to cache on a per page and per Member basis.
For me though, there is one option missing, which is the ability to cache a Macro based upon a QueryString value. This is needed for things like paged lists, or where you have one page, that does multiple tasks based upon a QueryString parameter (You could get around this by using URL rewriting, but that’s not always an option). Recently, a few of us stumbled across a solution.
When you set a Macro to cache, Umbraco generates a key to cache that Macro by.
<umbraco:Macro Alias="TestMacro" runat="server"></umbraco:Macro>

In the example above, because we have the Cache by Page option set, the key is made up of the page id, and the Macro alias. One usefull thing to know about how this key is generated (and what will ultimatley make caching by QueryString possible) is that if we have any parameters defined on the Macro, the value of these will also be included.
<umbraco:Macro Alias="TestMacro" runat="server" TestParam="testparam"></umbraco:Macro>

In the example above, our Macro now has a parameter defined with its value set to “testparam“, which has also been included in the cache key. I know what you are thinking, “but this is a hardcoded value”, and you are right, but there is a way to set a Macro parameter to a QueryString value. This is done using the [@...] Macro parameter syntax.
<umbraco:Macro Alias="TestMacro" runat="server" TestParam="[@MyQueryStringKey]"></umbraco:Macro>
Now when we request our page, the TestParam property is set to the value of the MyQueryStringKey parameter, which in turn is then used as the cache key for the Macro.
Any change to the MyQueryStringKey will result in a new cache key, and will create a new cached instance of the Macro.

One final little tip. The cache key is actually generated based upon the attributes defined on the Macro server contol tag itself, regardless of whether these map to properties defined on the Macro in the Umbraco UI, so if you don’t actually need to know the value of the QueryString parameter, you can just define the attribute on the Macro server control tag, and not define it as an actual parameter for the Macro, and it will still work.
So there we have it, how to cache a Macro by QueryString parameter.
Good write up Matt. One of the nice gems from the Level 2 course!
Yea, thought it was about time I wrote it up =)
Hi Matt,
Nice work. One question.. how do you get it to work? On all the websites where we tried to use this feature the cached macro’s disapere from the site at random.. This happens for all versions of Umbraco.
Thanks, Ron
Hey Ron,
Hmmm, that doesn’t sound too good. I’d probably suggest starting a forum topic on our.umbraco.org as you’ll get more people offering suggestions then.
Matt
This is awesome! Thanks Matt.. off to add it to a few sites right now!
Awesome tip, Matt. This solved a problem on a site I’ve built that depends on subdomains for language versioning.
Per default, the output of any macros were cached independently of the subdomain, so cached results were returned in the wrong language. However, creating a “domain” parameter and calling the macros like this solved the problem:
And what I meant to say there, before the HTML was stripped, was:
<umbraco:Macro Alias=”Sitemap” runat=”server” domain=”[@HTTP_HOST]“/>