I have a problem where when I publish an item in an SXA site, the cache does not get cleared for that site. I have a Sitecore 9.0.2 solution and the SXA site has a two "Site Grouping" items; one for master DB and one for web DB, named "Local Machine CM" and "Local Machine CD". What I find is that when viewing the Local Machine CD (which is using web) any published changes seem to cause a cache clear for the site "Local Machine CM" (which uses master). i.e. The HtmlCacheClearer class is only clearing the cache for CM. Is there some way to configure it to clear for both? I decompiled and recreated within my solution the class Sitecore.XA.Foundation.Multisite.EventHandlers.HtmlCacheClearer, Sitecore.XA.Foundation.Multisite
which confirms this behaviour. I can make a code change to this class to change the behaviour, but am wondering if there is a more official way to do this?
-
Raise a Sitecore Support bug? :)– Marek Musielak ♦Commented Jan 23, 2021 at 8:31
-
Are you using the environment name to differentiate between the two? By default it uses a wildcard but you can customize the name.– Michael WestCommented Jan 23, 2021 at 13:40
Add a comment
|
1 Answer
That's not the official way but still it may help if anyone is looking for a fix for that issue.
Create custom HtmlCacheClearer
class that inherits from Sitecore.XA.Foundation.Multisite.EventHandlers.HtmlCacheClearer
and override GetAllSitesForSharedSites
method:
public class HtmlCacheClearer : Sitecore.XA.Foundation.Multisite.EventHandlers.HtmlCacheClearer
{
protected override IEnumerable<SiteInfo> GetAllSitesForSharedSites(IEnumerable<SiteInfo> usages)
{
try
{
var list = usages.ToList();
var allowedDatabases = DatabaseRepository.GetDatabaseNames();
var siteInfo = list.FirstOrDefault(info => allowedDatabases.Contains(info.Database) && !info.Database.Equals("core"));
if (siteInfo == null)
return Array.Empty<SiteInfo>();
var database = DatabaseRepository.GetDatabase(siteInfo.Database);
var additionalSites = new List<SiteInfo>();
foreach (var site in list)
{
var rootItem = database.GetItem(SiteInfoResolver.GetRootPath(site));
if (rootItem != null)
{
if (IsSharedSite(rootItem))
{
Item tenantItem = MultisiteContext.GetTenantItem(rootItem);
if (tenantItem != null)
additionalSites.AddRange(GetSiteInfos(tenantItem.Paths.Path, list, additionalSites));
}
else
additionalSites.AddRange(GetSiteInfos(rootItem.Paths.Path, list, additionalSites));
}
}
return additionalSites;
}
catch (Exception exc)
{
Log.Error("Exception in HtmlCacheClearer", exc, this);
}
return base.GetAllSitesForSharedSites(usages);
}
protected virtual List<SiteInfo> GetSiteInfos(
string path,
IEnumerable<SiteInfo> usages,
List<SiteInfo> additionalSites)
{
return SiteInfoResolver.Sites
.Where(info => info.RootPath.Equals(path) || info.RootPath.StartsWith(path + "/"))
.Where(info => usages.All(x => !x.Name.Equals(info.Name, StringComparison.OrdinalIgnoreCase)))
.Where(info => additionalSites.All(x => !x.Name.Equals(info.Name, StringComparison.OrdinalIgnoreCase)))
.ToList();
}
}
Register your cache clearer instead of original one for both publish:end
and publish:end:remote
events:
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
<sitecore>
<events>
<event name="publish:end">
<handler type="Sitecore.XA.Foundation.Multisite.EventHandlers.HtmlCacheClearer, Sitecore.XA.Foundation.Multisite">
<patch:attribute name="type">MyAssembly.Caching.HtmlCacheClearer,MyAssembly.Caching</patch:attribute>
</handler>
</event>
<event name="publish:end:remote">
<handler type="Sitecore.XA.Foundation.Multisite.EventHandlers.HtmlCacheClearer, Sitecore.XA.Foundation.Multisite">
<patch:attribute name="type">MyAssembly.Caching.HtmlCacheClearer,MyAssembly.Caching</patch:attribute>
</handler>
</event>
</events>
</sitecore>
</configuration>