Sharing variables between Razor macros on a single Umbraco page

A typical template on our multi-site Umbraco installation is laden with dozens of Razor macros.

There's one for the search box, one to construct the canonical tag, another for the top navigation bar, one to output the correct logo... and so on.

It was a bit of a concern to me that many of these scripts were performing the same node tree queries.

Eg. because we are running a multisite system, the first thing most scripts have to do is to find the root node of the current site, so we are using in a dozen or more scripts:

 int rootId = Model.AncestorOrSelf(1).Id;  

It occurred to me that this, and other node traversal queries that are duplicated during a page load, must be having some kind of performance impact, and wouldn't it be better if you could make the query once, and store the result somewhere in the page context for later retrieval by other scripts.

A lot of pondering, and I found that you can do this:

In the first macroscript on the page:

 @{  
 int rootId = Model.AncestorOrSelf(1).Id;  
 HttpContext.Current.Items.Add("rootId", rootId);  
 }  

This retrieves the node Id of the root page and stores it in the page context "Items" collection.

Further down the page, to prove the concept, another macroscript contains this code:

 @{  
 @Html.Raw("<!-- from context " + HttpContext.Current.Items["rootId"].ToString() + " -->")  
 }  

This causes:

 <!-- from context 1071 -->  

To be output in the HTML (1071 being the value stored in the first macroscript).

So there you have it, a way of sharing data/variables between multiple macroscripts on a single Umbraco page.

There may be other ways of doing this, and perhaps newer versions of Umbraco (we're still on 4.x) make it easier.  But this does seem to work at least.

Only caveat, or point worthy of note is that the script that does the "setting" should not be cached.

Comments