World is now on Opti ID! Learn more

Linus Ekström
Oct 15, 2009
  2100
(0 votes)

Settings for properties

Background

One of the top developer feature request I have heard during my years at EPiServer has been to be able to store settings for a property. In EPiServer CMS 5 an administrator has had the possibility to select which plugins should be available for the built in editor. This feature has been only been available for longstring/xhtmlstring properties and it has not been able for developers to add their own settings for their custom properties.

Note: This feature should not be mistaken with “Properties for Properties”, ie to be able to save down additional properties on your custom property class for each page instance.

Whats new in EPiServer CMS 6

In EPiServer CMS 6 we are working on implementing support for the TinyMCE editor. This editor will replace the current editor as the default editor though you still have the option to use the old editor. You can even use the different editors for different properties in you like that. This is described more in my previous blog post Setting up multiple property controls for a property. As TinyMCE needs to be able to store different settings for plugins etc and we still need the support for settings for the old editor we decided to implement settings for properties for all kind of properties.

How do I add my own property settings?

Property settings are added to a property by adding attributes to either your property class or your property control class:

[PropertySettings(typeof(Settings), true)]
public class PropertyXhtmlStringControl :

PropertyLongStringControlBase

The settings class must implement IPropertySettings and might look something like this:

[PropertySettingsUI(AdminControl = typeof(SettingsUISample))]
public class SamplePropertySettings : IPropertySettings
{
public int Width { get; set; }

public IPropertySettings GetDefaultValues()
{
return new SamplePropertySettings() {Width = 200};
}
}

You might have noticed that this class also specifies a similar attribute. The PropertySettingsUI defines the class that is used to edit the settings. This class must inherit  The System.Web.UI.WebControls.Control class as well as implementing the IPropertySettingsUI interface. Or you can just inherit from the PropertySettingsUIBase and implement the abstract methods. It’s also possible to specify the url to a user control through either the Url, UrlFromUi or UrlFromUtil property. This user control needs to either implement IPropertySettingsUI or inherrit PropertySettingsUserControlBase.

How do I access the settings object?

PropertyData has got a new Property:

public PropertySettingsContainer SettingsContainer

It will also have a new method:

public IPropertySettings GetSetting(Type settingsType)

The PropertySettingsContainer might hold settings for both the PropertyData-derived object as well as settings for all configured property controls for the property. With the GetSetting-method you are able to fetch the settings object that you are interested in. For a property control for instance, you are able to fetch both your own settings as well as the settings for the PropertyData-object. It’s even possible to get the settings for another Property Control that is registered for the property as long as you know the type name for the controls settings object.  Here is an example that shows how to load a settings object of the type “Settings” when loading the TinyMCE editor:

public override void CreateEditControls()
{
Settings settings =
(Settings)PropertyData.GetSetting(typeof(Settings));

EditControl = new Editor.TinyMCE.Editor(settings);

An entire code sample

Below is a code sample that describes how to implement the different parts needed to get use of setting for properties. This includes the property control that uses the settings, a sample settings class and a class that creates the admin user interface for the settings.

using System.Web.UI;
using EPiServer.Web.PropertyControls;
using System.Web.UI.WebControls;
using EPiServer.Core.PropertySettings;
namespace CodeSamples
{
    [PropertySettings(typeof(SamplePropertySettings), true)]
    public class SamplePropertyControlWithSettings : PropertyTextBoxControlBase
    {
        protected override void SetupEditControls()
        {
            EditControl.Text = ToString();
            SamplePropertySettings settings = (SamplePropertySettings)PropertyData.GetSetting(typeof(SamplePropertySettings));
            EditControl.Width = settings.Width;
        }
    }
    /// <summary>
    /// Example of a settings class. Needs to inherit from <see cref="IPropertySettings"/>.
    /// The easiest way is to inherit from PropertySettingsBase.
    /// </summary>
    [PropertySettingsUI(AdminControl = typeof(SettingsUISample))]
    public class SamplePropertySettings : PropertySettingsBase
    {
        public int Width { get; set; }
        /// <summary>
        /// Gets the default values. for the setting this is used when nothing 
        /// is specified in the settings store either locally or globally.
        /// </summary>
        public override IPropertySettings GetDefaultValues()
        {
            return new SamplePropertySettings() { Width = 200 };
        }
    }
    /// <summary>
    /// Used to render a UI for editing the settings in the admin UI.
    /// Needs to be in the inherit from <see cref="Control"/> and implement <see cref="IPropertySettingsUI"/>.
    /// Most easily accomplished using <see cref="PropertySettingsControlBase"/>
    /// </summary>
    public class SettingsUISample : PropertySettingsControlBase
    {
        private TextBox _widthInput;
        #region IPropertySettingsUI Members
        protected override void CreateChildControls()
        {
            base.CreateChildControls();
            _widthInput = new TextBox { ID = "WidthValue" };
            Label label = new Label { Text = "Width", AssociatedControlID = "WidthValue" };
            Controls.Add(label);
            Controls.Add(_widthInput);
        }
        public override void LoadSettingsUI(IPropertySettings propertySettings)
        {
            EnsureChildControls();
            _widthInput.Text = ((SamplePropertySettings)propertySettings).Width.ToString();
        }
        public override void UpdateSettings(IPropertySettings propertySettings)
        {
            EnsureChildControls();
            ((SamplePropertySettings)propertySettings).Width = int.Parse(_widthInput.Text);
        }
        #endregion
    }
}

To test this sample property control I have added a configuration setting to use my property control as the ui control for the built in property PropertyString.

<add type="EPiServer.Core.PropertyControlClassFactory, 
EPiServer" id="PropertyControlFactory">
<register type="EPiServer.Core.PropertyString, EPiServer"
mappedType="CodeSamples.SamplePropertyControlWithSettings,
EPiServer.Templates.Public" />
</add>

PropertySettingsAdminUI

Figure 1: A screenshot of how the admin ui looks like when editing a page type property of type PropertyString. Note the tabbed ui where the custom settings tab is where your property settings ui will be displayed.

CustomPropertyEditModeExample

Figure 2: A screenshot of the actual property in edit mode(with the width set to 400):

Validation of input values

If you need to validate any input values you should add validation controls to your settings ui control. When the save button is pressed the page will call Page.Validate() and any validation messages will show up at the top of the dialog.

ValidationExample

Figure 3: An example of using validation controls in the property settings ui.

Using global settings

As you might have noticed in the settings admin UI there is a option to “Use global settings”. This can either be the default setting which results in a call to the method “GetDefaultSettings” for the settings class or a global settings object. These are defined per property type (PropertyString, PropertyNumber, MyCustomProperty etc). It’s also possible to assign the “default settings” to use one of the created global settings objects instead of the code default settings.

When defining settings for a page type property you can either use the default settings, a global setting object or define custom settings that will only affect the current property. Often it might be enough to define your default settings and add a couple of global settings which you point to for the properties that you want to differ from the standard settings.

An example might be the editor settings for a PropertyXhtmlString. Default settings might be to have an editor with all the default plug-ins enabled. To be able to have some properties that use a more basic editor you create a global settings object with a few plug-ins that you want to use. Then you set your properties that want to have the locked down editor to use this global settings object.

GlobalSettingsUI

Figure 4: A screenshot showing the global settings UI including a popup window to add a new global setting.

Oct 15, 2009

Comments

Please login to comment.
Latest blogs
Make Global Assets Site- and Language-Aware at Indexing Time

I had a support case the other day with a question around search on global assets on a multisite. This is the result of that investigation. This co...

dada | Jun 26, 2025

The remote server returned an error: (400) Bad Request – when configuring Azure Storage for an older Optimizely CMS site

How to fix a strange issue that occurred when I moved editor-uploaded files for some old Optimizely CMS 11 solutions to Azure Storage.

Tomas Hensrud Gulla | Jun 26, 2025 |

Enable Opal AI for your Optimizely products

Learn how to enable Opal AI, and meet your infinite workforce.

Tomas Hensrud Gulla | Jun 25, 2025 |

Deploying to Optimizely Frontend Hosting: A Practical Guide

Optimizely Frontend Hosting is a cloud-based solution for deploying headless frontend applications - currently supporting only Next.js projects. It...

Szymon Uryga | Jun 25, 2025

World on Opti ID

We're excited to announce that world.optimizely.com is now integrated with Opti ID! What does this mean for you? New Users:  You can now log in wit...

Patrick Lam | Jun 22, 2025

Avoid Scandinavian Letters in File Names in Optimizely CMS

Discover how Scandinavian letters in file names can break media in Optimizely CMS—and learn a simple code fix to automatically sanitize uploads for...

Henning Sjørbotten | Jun 19, 2025 |