How to Store Settings in Order to Configure Sitecore Easily

Today I want to share some ideas about how to build and use settings for your Sitecore site.

Why do we need settings?

I’ve met many projects that were configured via constants in code - sometimes messy, sometimes perfectly structured lists of IDs and paths. Such ‘configuration’ might even contain ‘#if DEBUG’ sections to add flexibility for testing purposes. There’s a better way to store settings, for example configuration files with Sitecore settings (<sitecore>/<settings>/<setting...>), custom configuration sections, completely ‘invented’ xml format with parser. Config files provide more flexibility for developers but just a bit more than nothing for a client. And this approach works for stable environments (finished for developers and for a client) or for solutions which are continuously under development, where developers can easily perform and deploy update if requirements were changed or added.

But I believe that this is not a best ‘Sitecore way’ to implement setting and with Sitecore backend we can provide better flexibility for content editors and site administrators. Second thing you should keep in mind - Sitecore tends to be multisite and multilingual . Therefore the settings should be site and language specific. And even if you were told that ‘it will be just one site in one language’ - be ready to be asked to add one more site in a few months, ‘just like existing but for another country’ or a new product.

Often customers require configurable options, but they do not know what exactly they would like to adjust on their site. We prefer to equip our implementations with at least a few basic settings. By default adjustable site parameters include strings used on all pages of our solutions(e.g. fixed part of the page title), links (e.g. search results page if search can be triggered from multiple places, error pages), images (e.g. site logo), numbers (e.g. some limit of text items can be different for languages with long words or hieroglyphs). –These settings supposed to be different for different sites with the same codebase.

Let’s take a look onto approach which works good for most small and medium implementations. That stand for a solution that hosts 1-10 sites for different regions/languages/brands with solid codebase.

Sitecore

It is essential to have clear and duplicable structure of the site tree, and usually we keep it as simple as possible:

Sitecore settings sample

Make sure you’ve created a template for a ‘Site root’ - it can be empty, just assign your favourite ‘Site’ icon :).

Site contains three items under site root:

  • home page item (root of all web pages)
  • data folder (root of all datasource items reusable within website, Template=’/sitecore/templates/Common/Folder,’ protected to avoid occasions)
  • settings folder (Template=’/sitecore/templates/<PROJECT_NAME>/Settings/Settings Folder’, protected as well)

We set up fixed settings structure for any site within solution and can leverage it to retrieve site-specific settings. Now it is time to add some settings. There are two main ways of structuring settings - 1) simple models and branchy structure; 2) simple structure with rich models. Both have pros and cons, but for small amount of options I prefer to have a few rich models.

Sitecore settings

Key points are:

  • each group of settings has its own template
  • settings subtree structure is very simple
  • location of the settings folder is fixed under site root

That allows us to easily retrieve a setting item for a context site by settings folder path and template of the item You might use template or name, or relative path, but I prefer to use template because it is more stable.

Code

It’s time to use the settings in our code. We use Glass.Mapper (http://www.glass.lu/Mapper) in most of our projects and for these settings we will create a model like this:

...
public class GeneralSiteSettings : SitecoreItem
    {
        [SitecoreField("Currency")]
        public virtual string Currency { get; set; }

        [SitecoreField("Show Footer Countries List")]
        public virtual bool FooterShowCountriesList { get; set; }

        [SitecoreField("Cookie Policy")]
        public virtual CookiePolicy CookiePolicy { get; set; }

        [SitecoreField("Error page link")]
        public virtual BasePage ErrorPage { get; set; }

        [SitecoreField("Logo White")]
        public virtual Image LogoWhite { get; set; }

        [SitecoreField("Logo Black")]
        public virtual Image LogoBlack { get; set; }
    }

Here SitecoreItem is our very base model.

Next step is to retrieve that model for a context site. Simplest way is to find settings item under ‘<site root>/Settings’ and map it to the model:

...
public static class SettingsProvider
    {
        private const string SettingsPath = "/Settings";

        public static TSetting GetSetting(string itemTemplateName) where TSetting : class
        {
            Item settingItem = Context.Database.SelectSingleItem(string.Format("{0}{1}//*[@@templatename='{2}']", Context.Site.RootPath, SettingsPath, itemTemplateName));

            if (settingItem != null)
            {
                return settingItem.GlassCast();
            }

            return null;
        }
    }

Please note that this is simplified code which requires template name as a parameter (can be retrieved from the settings model custom attribute) and uses “//*” Sitecore query which can be too slow. Any unique parameter can be used to select correct settings item - template name, template Id, item name or path. Choose the one that works best for you. Now we need an easy way to use these settings. You may have something like this:

...
public static class SiteSettings
    {
        public static GeneralSiteSettings GeneralSiteSettings
        {
            get { return SettingsProvider.GetSetting("General Site Settings"); }
        }
    }

But this code will load item from Sitecore and cast it to model on every call, could work for some environments but in most cases you will want to add cache:

...
public static class SiteSettings
    {
        public static GeneralSiteSettings GeneralSiteSettings
        {
            get { return CustomCache.GetOrExecute("generalSiteSettings", () => SettingsProvider.GetSetting("General Site Settings")); }
        }
    }

Remember to clear your cache if settings were changed and make sure that your cache takes into consideration context site and language.

Happy coding!


Do you need help with your Sitecore project?
VIEW SITECORE SERVICES