Navigation and service panel


Content

Enable Multi-level Site Property Inheritance

By Pascal Mathys on 8. August 2014, 2 Comments

Sitecore supports site property inheritance since ever. We work with so-called "base sites" which define most of the site configuration but don't serve as an actual site. Those sites inherit from the default "website" site provided by Sitecore.

With this configuration approach, we can simplify the configuration of actual sites because we can leave them as light-weight as possible and make setting changes easy as a breeze.

The problem with this inheritance feature is, that it only works if every site which depends on another, is patched after it's inherited site.

Because of more specialized sites (e.g. virtualFolder), this is not a good idea as the "website" site would be resolved for every request first.

The Problem

When you patch the sites like this:

<sites>
  <site name="super-special-site" inherits="less-special-site" />
  <site name="less-special-site" inherits="website" />
  <site name="website" />
</sites>

the inheritance feature does only support one single level of inheritance. The reason for this is the way the ConfigSiteProvider class of Sitecore reads the xml nodes of the configuration. On empty properties of the current processed site, it tries to get the value of the inherited site. But since the inheritance of the inherited site is not done yet (our super special site is processed first), it can only fallback field values which are actually filled on the inherited site.

Our Solution

The solution is basically a one-line fix. Sadly, Sitecore does not want to give us the possibility to reuse the code of their ConfigSiteProvider (protected for the win!).

You have to copy the whole content of the Sitecore.Sites.ConfigSiteProvider class and do the following fix inside the ResolveInheritance method:

Before

foreach (Site site in (Collection<Site>) sites)
{
  if (!string.IsNullOrEmpty(site.Properties["inherits"]))
    this.AddInheritedProperties(site, siteDictionary);
}

After

var reversedSiteCollection = sites.Reverse();
foreach (Site site in reversedSiteCollection)
{
  if (!string.IsNullOrEmpty(site.Properties["inherits"]))
    this.AddInheritedProperties(site, siteDictionary);
}

This small change inverts the order in which the provider resolves the sites. More general sites are processed first, so that on the more specialized sites, the value on the inherited site is already resolved.

Last but not least you have to replace the Sitecore provider with your own one in an include file:

<siteManager defaultProvider="config">
  <providers>
    <add name="config" set:type="Examples.ConfigSiteProvider, Examples" />
  </providers>
</siteManager>

Now you can have as much inheritance levels as you want.

2 Comments

  1. Jan Bühler
    10. June 2015 at 10:33

    Wouldn't changing the order in the config solve the issue?

  2. 15. June 2015 at 09:01

    Indeed it would fix the inheritance issue. But then the more generic site (virtualFolder = "/") would be evaluated first and every more specific site (virtualFolder = "/whatever") would not be accessible anymore.

    My fix keeps the site resolving order intact but changes the order while loading the sites for loading the inherited stuff.

Add your comment

Your email address will not be published. Required fields are marked *

*