Best way to cache Domain class in multi language site
Following an unfinished conversation on twitter (https://twitter.com/ProNotion/status/295852202919096320) regarding the best way to cache the content of the Umbraco Domain class. I've created this post:
Summary so far: Accessing the information contained in the umbraco Domain class involves a SQL query, so it is not ideal to use this class directly to generate a list of languages and domain names for a language selector that will appear on every page of a multi-languge website. A cached copy is therefore more suitable.
Thanks to @ProNotion, @Kipusoep, @Richie_Green, @netaddicts
The question then is what is the best way of going about this?
Domain.GetDomains() returns the list of all domains and it uses the cache, ie no DB access, but the method is internal.
You can use Domain.GetDomain(string domainName), Domain.GetDomainsById(int nodeId)... though, they are public and rely on GetDomains() internally, so they would use the cache, ie no DB access.
What I may not have been clear about on Twitter is that I caching my macro content rather than the explicit result of the API calls. See below for my Razor script which I hope is of some help.
var globalHomePage = Model.NodeById(-1).Descendants("HomePageGlobal").First();
var globalHomePageDomain = umbraco.library.GetCurrentDomains(globalHomePage.Id)[0];
var homepages = Model.NodeById(-1).Descendants("HomePageNational");
var currentHomepage = Helpers.GetCurrentHomepage(Model);
var currentDomain = umbraco.library.GetCurrentDomains(currentHomepage.Id)[0];
var currentCulture = currentDomain.Language.CultureAlias;
var currentCountryCode = currentCulture.Substring(currentCulture.IndexOf("-") + 1);
<form action="@Model.Url" class="align-left country-select" method="POST">
<div class="flag [email protected]()">
</div>
<select id="location-switcher" name="country">
<option data-flag="gb" value="@string.Concat("http://", globalHomePageDomain.Name, "/")" @(globalHomePage.Id == currentHomepage.Id ? "selected=\"selected\"" : string.Empty)>@globalHomePage.Name</option>
@foreach (var home in homepages)
{
var domain = umbraco.library.GetCurrentDomains(home.Id)[0];
var culture = domain.Language.CultureAlias;
var countryCode = @culture.Substring(culture.IndexOf("-") + 1);
<option data-flag="@countryCode.ToLower()" name="@countryCode" value="@string.Concat("http://", domain.Name, "/")" @Html.Raw(countryCode == currentCountryCode ? "selected=\"selected\"" : string.Empty)>@Library.Coalesce(home.MenuText, home.Name)</option>
}
</select>
</form>
Admittedly this is not ready for production yet as there are a few more checks I need to add since there are some instances where this may fall over at the momen e.g. no hostname on a home node.
I had misunderstood the caching issue partly because of Dirk's comment on twitter suggests the opposite to Stephen's comment above - ie that the domain api involves SQL calls.
I'm not sure about latest versions of umbraco (and not sure what version you're on), but thought that those api calls were not cached. I may be wrong (and can't for the live of remember why I was thinking that those calls aren't cached), so in case you're on a version that supports caching of those api calls, go for this method. Otherwise, follow either Simon's suggesting of using aggresive caching on your macro that fetches and displays results from the api call. Alternatively, use my approach of setting some extra props on your top level nodes and fetch those props using standard node api. (And of course, this can also be used in combo with caching the results)
Soooo many options to choose from, just pick one that suits your needs!
Inclined to agree with Dirk. To the best of my knowledge it's not cached but in reality how often is that information likely to change in production so macro caching with a long expiry should prevent the need to hit the database on each page request in order to populate your list.
Best way to cache Domain class in multi language site
Following an unfinished conversation on twitter (https://twitter.com/ProNotion/status/295852202919096320) regarding the best way to cache the content of the Umbraco Domain class. I've created this post:
Summary so far: Accessing the information contained in the umbraco Domain class involves a SQL query, so it is not ideal to use this class directly to generate a list of languages and domain names for a language selector that will appear on every page of a multi-languge website. A cached copy is therefore more suitable.
Thanks to @ProNotion, @Kipusoep, @Richie_Green, @netaddicts
The question then is what is the best way of going about this?
Domain.GetDomains() returns the list of all domains and it uses the cache, ie no DB access, but the method is internal.
You can use Domain.GetDomain(string domainName), Domain.GetDomainsById(int nodeId)... though, they are public and rely on GetDomains() internally, so they would use the cache, ie no DB access.
Unless I miss something?
Stephan
Hi Matthew,
What I may not have been clear about on Twitter is that I caching my macro content rather than the explicit result of the API calls. See below for my Razor script which I hope is of some help.
Admittedly this is not ready for production yet as there are a few more checks I need to add since there are some instances where this may fall over at the momen e.g. no hostname on a home node.
Cheers, Simon
Thanks Simon & Stephen,
I had misunderstood the caching issue partly because of Dirk's comment on twitter suggests the opposite to Stephen's comment above - ie that the domain api involves SQL calls.
Would be good to clarify this!
Thanks again
Matt
Matthew,
I'm not sure about latest versions of umbraco (and not sure what version you're on), but thought that those api calls were not cached. I may be wrong (and can't for the live of remember why I was thinking that those calls aren't cached), so in case you're on a version that supports caching of those api calls, go for this method. Otherwise, follow either Simon's suggesting of using aggresive caching on your macro that fetches and displays results from the api call. Alternatively, use my approach of setting some extra props on your top level nodes and fetch those props using standard node api. (And of course, this can also be used in combo with caching the results)
Soooo many options to choose from, just pick one that suits your needs!
Cheers,
/Dirk
Thanks Dirk,
Version 4.9 for this project. The codebase is changing quickly at the moment so it is very difficult to keep up. Really appreciate your help!
Matt
Inclined to agree with Dirk. To the best of my knowledge it's not cached but in reality how often is that information likely to change in production so macro caching with a long expiry should prevent the need to hit the database on each page request in order to populate your list.
Simon
It seems the Domain API has caching built-in (at least in v4.8.1): http://pastebin.com/BhFidJax
Thanks Stefan,
That's good to know, make sense that it should be cached too.
Matt
is working on a reply...