Thursday, September 15, 2011

Implement a SettingsPageType in EPiServer

There are loads of different opinions about this matter. Even here at Nansen we haven't reached consensus. This is strictly my personal opinion.

Here's why I think you should use a separate page type for global site settings.

  • Do not bloat the start page with non start page related properties.
  • DO NOT BLOAT THE START PAGE WITH NON START PAGE RELATED PROPERTIES.

The only downside is I have to contradict myself to implement this. You still need to add one property to your start page. A page reference property for pointing out the settings page, so you can easily reach it from code.

For easy code access to your settings I suggest that you add this code snippet in your page template base class, page type base class or your master page base class:

private SettingsPageType _settings;
public SettingsPageType Settings
{
    get
    {
        if (_settings == null)
        {
            var startPage = DataFactory.Instance.GetPage(PageReference.StartPage) as StartPageType;
            if (startPage == null || startPage.SettingsPage == null)
            {
                throw new ApplicationException(
                    "Settings page not configured. The website will not work until it has been configured.");
            }
            _settings = startPage.SettingsPage;
        }
        return _settings;
    }
}

A small downside is that there will be an extra request to the EPiServer page cache. But I'm convinced it will not affect the performance of your website.

A typical example of using site settings is that the editor wants the website logo to be replaceable. So in my SettingsPageType I add a property for this purpose:
[PageTypeProperty(Type = typeof(PropertyImageUrl),
    EditCaption = "Website logo",
    HelpText = "The website logo, visible on all pages on the website.",
    UniqueValuePerLanguage = false,
    SortOrder = 10)]
public virtual string SiteLogo { get; set; }

Then in your master page you set the image source to <%= Settings.SiteLogo %> or manage it in code behind.

From an editors point of view it's confusing to see global site settings mixed with the content of the start page. There's a risk that they'll be confused and that they might change something unintentionally.

The coolest and most convincing argument is that you can add this neat page type icon to your SettingsPageType:


4 comments :

  1. Nice post! Maybe you could syndicate this blog on EPiServer World. You will probably need to create a Nansen account (one world account = one blog syndication) and then you can syndicate the Nansen blog with all posts tagged with EPiServer.

    Paul Smith
    EPiServer

    ReplyDelete
  2. Thanks Paul!

    A good idea about the syndication to EPiServer World. Filtering on the EPiServer tag. I'll see what we can do.

    ReplyDelete
  3. Good article!

    I also find this a good idea. Usually I add a property of type SettingsPageType to my base PageType so that i have easy access to it from CurrentPage. That way you can go CurrentPage.SettingsPage.SiteLogo.

    Sometimes I have found myself needing semi-global settings, say for example for one section of the site. To not end up sprinkling the site with dynamic properties I use one dynamic proprerty referencing an instance of the SettingsPageType for that region. So, when I need to have different global settings per region I simply reference the settingspage from a dyn prop instead of from the start page.

    Need to add that icon though :p

    ReplyDelete
  4. Yeah in my latest project I did the same thing. CurrentPage.Settings.SiteLogo :)

    Thanks for the input regarding section-styled settings. Using a dynamic property to point out the settings page for current section is a nice way of doing it.

    The icon is the main reason for implementing the whole thing. I loooove adding icons to each page type :)

    ReplyDelete