In this tutorial, you will learn about the different ways of dealing with global settings within Umbraco V8. Out-of-the-box Umbraco does not provide any mechanisms for developers to deal with global settings. Global settings are a staple of pretty much every single CM project I have ever worked on. Feature flags, header and footer settings, sitewide meta-data, all these settings need to be stored somewhere in the CMS. This draws the question where? It will be up to you to answer this question. Within this tutorial, I will propose three solutions that you can use:

  • The Homepage Settings Pattern
  • The Settings Page Pattern
  • The Settings Block Pattern

The Homepage Settings Pattern

The homepage settings pattern is by far the most common pattern used in almost every CMS. In this pattern all global settings are stored on the homepage document-type. Normally a tab, or, a section is created on the homepage document-type called 'Settings', or, something equality imaginative is defined. Its primary usage is a general placeholder area for all site settings. You can see this pattern applied in the majority of the starter-kits. For example, if you checkout the Fanoe starter kit you will see this pattern in action.

There are both advantages and disadvantages of the homepage settings pattern.

Advantages:

  • You do not need to create any additional document-types
  • The homepage is easy to access anywhere in code

Disadvantages:

  • Homepage bloat
  • Hard for content editors to understand the homepage
  • Performance

The main disadvantage of this pattern may not be too noticeable when the website is first launched. When a website launches you may only need a handful of properties. Imagine fast-forwarding 5 years into the future. it is impossible to predict how the site will change over time. Re-designs occur. New components will be required.
Keep track of what settings what to what features becomes a burden and a chore.

To make things worse, there is also a risk associated with removing these properties from the homepage. Imagine removing a setting that you think is obsolete. Unbeknown to you, this particular setting is used on the menu. Removing the setting in production breaks the menu. This it turns breaks the whole site. This type of refactoring is a big risk of using the homepage settings pattern. I have seen several live production websites being taken down due to it over the years. So be warned. As refactoring properties from the homepage adds risk even developers with the best of intentions can be hesitant to maintain settings on the homepage.

The code to access settings on the homepage can be done using the IUmbracoContextFactory. In this approach my recommendation is to create a service that you inject into your route-hijacked controllers, like this:

The code above uses the Umbraco ModelsBuilder. The Home type was generated based on a document-type within the CMS.

Settings Page Pattern

An alternative approach to storing settings on the homepage is to create a document-type specifically used for storing global settings. The settings page is usually located outside of the website hierarchy as a child of the root node. Which could also be referred to as a sibling of the homepage. The Umbraco content-tree in this pattern would look like this:

  • Root
    • Home
    • Page 1
    • Page 2
    • Settings

This pattern definitely has more advantages than disadvantages. The advantages include:

  • Settings can be more easily refactored
  • No page-load impact on the homepage
  • Decoupled architecture

While the main disadvantages being:

  • An additional document-type needs to be created

To access a settings-page within code can be done using DescendantsOrSelf():

Note The code above assumes site settings document-type is called 'settings page'.

It would also possible to put the settings as a child of the homepage. I would advise against this though. In this pattern the CMS content-tree would look like this:

  • Root
    • Home
    • Page 1
    • Page 2
    • Settings

The first issue with this approach is that the page could be indexed and returned within the search results, the menu, or the site-map. This approach is also a lot less secure. Global settings should never be publicly accessible and ensuring the setting-page sits outside the main content tree will present this.

Settings-Block Pattern

The settings-block pattern is a variation of the settings page pattern. As of Umbraco V8.9, Umbraconow ships with a new property called the block-list editor. For this discussion, the important concept to grasp is the usefulness of a block. Blocks are also made from a document-types meaning there are no be concepts to really grasp to start using them. A block can contain all the same properties as any other document-type. This means that you can build one or more settings blocks to store global settings. These blocks can then be added to a settings page as long as it has a lock-list editor defined within it.

The benefit of this thrid pattern is the layer of abstraction it provides. Closely related global-settings can be added into different blocks. These blocks can then be added to the setting page. Blocks provide more robust process for maintaining global settings. Batching related settings into specific blocks will give more flexibility. If a batch of settings become obsolete. Within the CMS the block simply is removed from the block-list property on the settings page. When new settings are required, a new block can be created and associated with the settings page.

Being able to add and remove blocks like this follows the open/close principle in SOLID. Settings can be added without modifying the behavior of the existing system. This will make maintaining global settings in the future easier. Another added side-effect of having global settings split across multiple blocks will prevent a monolith from occurring. To get started with the settings-block approach you would use this code:

Within a controller a setting can be accessed like this:

Where FeatureFlags is a block added into a block-list-editor. YOu can see this working, in my V8 sample site here. Happy Coding!