Linus Ekström
Oct 30, 2014
  9371
(17 votes)

Typed Property Settings

Today we released built in support to define Property Settings in code. The main use case for this is that you can now control what tools should be enabled in Tiny MCE in code. You can either create a global default setting or create a specific setting that you can assign to specific properties using an attribute. The GetPropertySettings method will be called for each content and user meaning that you can dynamically control the settings, for instance adding specific settings to certain roles like an administrator.

Creating a default setting

Creating a default setting is as simple as adding a class, marking it with the ServiceConfiguration attribute and setting the class as “Default”. Here is a simple example:

using System.Collections.Generic;
using EPiServer.Core.PropertySettings;
using EPiServer.Editor.TinyMCE;
using EPiServer.ServiceLocation;
 
namespace EPiServer.Templates.Alloy.Models.Pages
{
    [ServiceConfiguration(ServiceType = typeof(PropertySettings))]
    public class DefaultTinyMCESettings : PropertySettings<TinyMCESettings>
    {
        public DefaultTinyMCESettings()
        {
            IsDefault = true;
            DisplayName = "Default settings from code";
            Description = "This is the default settings as defined in code.";
        }
 
        public override TinyMCESettings GetPropertySettings()
        {
            var settings = new TinyMCESettings();
 
            var mainToolbar = new ToolbarRow(new List<string>() { TinyMCEButtons.Bold, TinyMCEButtons.Italic, TinyMCEButtons.Cut, TinyMCEButtons.Copy, TinyMCEButtons.Paste, TinyMCEButtons.EPiServerLink, TinyMCEButtons.Unlink });
 
            settings.ToolbarRows.Add(mainToolbar);
 
            settings.Height = 20;
            settings.Width = 200;
 
            return settings;
        }
 
        public override System.Guid ID
        {
            get { return new System.Guid("a6fe936f-190d-45e2-b83c-ccc0501a7312"); }
        }
    }
}
 
Which results in the following editor:

EditorDefinedInCode

Assigning a specific setting to a property

You can create several classes that define property settings although there can only be one marked as “Default”. If you want to assign a specific settings class to a specific prooperty, this can be done using the PropertySettings attribute.

[ServiceConfiguration(ServiceType = typeof(PropertySettings))]
    public class SimpleTinyMCESettings : PropertySettings<TinyMCESettings>
    {
        public SimpleTinyMCESettings()
        {
            DisplayName = "Simple editor";
        }
 
        public override TinyMCESettings GetPropertySettings()
        {
            var settings = new TinyMCESettings();
 
            var mainToolbar = new ToolbarRow(new List<string>() { TinyMCEButtons.Bold, TinyMCEButtons.Italic });
 
            settings.ToolbarRows.Add(mainToolbar);
 
            settings.Height = 20;
            settings.Width = 200;
 
            return settings;
        }
 
        public override System.Guid ID
        {
            get { return new System.Guid("a6fe936f-190d-45e2-b83c-ccc0501a7311"); }
        }
    }
This is how you apply the specific setting for your model property:
[PropertySettings(typeof(SimpleTinyMCESettings))]
public virtual XhtmlString Sidebar { get; set; }

Dynamically controlling the settings

Since the method is called for each content and user, it’s possible to apply personalization for the settings. Here we add the code (edit html) plug-in for users that are part of the administrators role:

using System.Collections.Generic;
using EPiServer.Core.PropertySettings;
using EPiServer.Editor.TinyMCE;
using EPiServer.ServiceLocation;
 
namespace EPiServer.Templates.Alloy.Models.Pages
{
    [ServiceConfiguration(ServiceType = typeof(PropertySettings))]
    public class DefaultTinyMCESettings : PropertySettings<TinyMCESettings>
    {
        public DefaultTinyMCESettings()
        {
            IsDefault = true;
            DisplayName = "Default settings from code";
            Description = "This is the default settings as defined in code.";
        }
 
        public override TinyMCESettings GetPropertySettings()
        {
            var settings = new TinyMCESettings();
 
            var mainToolbar = new ToolbarRow(new List<string>() { TinyMCEButtons.Bold, TinyMCEButtons.Italic, TinyMCEButtons.Cut, TinyMCEButtons.Copy, TinyMCEButtons.Paste, TinyMCEButtons.EPiServerLink, TinyMCEButtons.Unlink });
 
            if(EPiServer.Security.PrincipalInfo.CurrentPrincipal.IsInRole("administrators"))
            {
                mainToolbar.Buttons.Add(TinyMCEButtons.Code);
            }
 
            settings.ToolbarRows.Add(mainToolbar);
 
            settings.Height = 20;
            settings.Width = 200;
 
            return settings;
        }
 
        public override System.Guid ID
        {
            get { return new System.Guid("a6fe936f-190d-45e2-b83c-ccc0501a7312"); }
        }
    }
}

When logged in as an administrator you get an additional button:

PropertySettingsAsAdmin

How does settings in code relate to settings defined in admin?

Since EPiServer CMS 6 R2, it’s been possible to define property settings in the administrative interface and now also possible to define these in code. Since settings can be defined both in code and the administrative interface, similar rules as the ones that controls content types apply. This means that the settings have the following priority:

  1. A specific setting for a property defined in admin view. This can be either a custom settings for this property or pointing to a specific global setting that has been defined in admin.
  2. A specific setting for a property defined for the model in code by an attribute.
  3. A global setting defined in admin marked as the “Default” setting for the property type.
  4. A global setting defined in code.

Working with property settings

A typical use case is that the developer is responsible for defining and maintaining the settings but that the administrators have the option to override them, for instance if a tool/button needs to be added before it is possible to update the website implementation. The workflow could then look like this:

  1. The developer creates a settings class and sets this as default.
  2. If there is a need to have specific settings for some properties, this is done by creating additional settings classes and use the PropertySettings attribute.
  3. If there is a need for an administrator to change the settings for a specific property they can add a custom setting for the property in the administrative interface. This will take effect immediately.
  4. The settings in admin can be removed once the developers adds this to the code.
  5. If there is a need to change the default settings the administrator can create a new shared setting and mark this as default. This will now take precedence over the default settings from code.
  6. Once the developer has updated the settings from code the default settings in admin can be removed.

Upgrading existing sites

Given that settings defined in admin overrides settings defined in code, settings defined in admin needs to be removed if you want to control property settings in code.

Long term documentation for this can be found in the EPiServer developer guide: http://world.episerver.com/Documentation/Items/Developers-Guide/EPiServer-CMS/75/Content/Properties/Property-settings/

Oct 30, 2014

Comments

Oct 30, 2014 07:11 PM

Yay! Finally, this is awesome.

Antti Alasvuo
Antti Alasvuo Oct 31, 2014 07:01 AM

+100 Finally ;)

I couldn't find that TinyMCEButtons class you are using for the button names (constants) so had to add my own constants for the buttons (looking at the attributes in EPiServer.Editor.TinyMCE.Plugins with help of ILSpy) or TinyMCE site http://www.tinymce.com/wiki.php/TinyMCE3x:Buttons/controls

Marcus Lindblom
Marcus Lindblom Oct 31, 2014 10:09 AM

This is awesome news!

Oct 31, 2014 10:43 AM

Hi!

Actually, the idea was that this blog post should go out later today, together with the latest packages that contains some of the things above as well as some bug fixes. To get all the functionality mentioned above, both CMS core and UI should be upgraded to 7.16 which we plan to release in a few hours. These new packages contains the constant strings for all built in Tiny MCE buttons and plug-ins.

Henrik Fransas
Henrik Fransas Oct 31, 2014 01:42 PM

Great work Linus!

Andreas  Johansson
Andreas Johansson Oct 31, 2014 02:34 PM

Thanks, A lot of customers have asked for this!

Al Higgs
Al Higgs Oct 31, 2014 03:18 PM

Great feature!

Joshua Folkerts
Joshua Folkerts Oct 31, 2014 05:27 PM

BRILLIANT!!!! Been waiting for this for a long long time.

Nov 1, 2014 08:25 PM

Good stuff Linus

Johan Book
Johan Book Nov 3, 2014 12:36 PM

Äntligen! \o/

Øyvind Jonassen
Øyvind Jonassen Nov 3, 2014 09:45 PM

Nice

Nov 4, 2014 08:14 AM

Nice work!

Nov 4, 2014 09:47 AM

Nice.

Björn Olsson
Björn Olsson Nov 5, 2014 09:49 AM

Sweet!

Nov 6, 2014 10:39 PM

Awesome! Looked forward to this

Please login to comment.
Latest blogs
Multiple Anonymous Carts created from external Head front fetching custom Api

Scenario and Problem Working in a custom headless architecture where a NextJs application hosted in Vercel consumes a custom API built in a...

David Ortiz | Oct 11, 2024

Content Search with Optimizely Graph

Optimizely Graph lets you fetch content and sync data from other Optimizely products. For content search, this lets you create custom search tools...

Dileep D | Oct 9, 2024 | Syndicated blog

Omnichannel Analytics Simplified – Optimizely Acquires Netspring

Recently, the news broke that Optimizely acquired Netspring, a warehouse-native analytics platform. I’ll admit, I hadn’t heard of Netspring before,...

Alex Harris - Perficient | Oct 9, 2024 | Syndicated blog

Problem with language file localization after upgrading to Optimizely CMS 12

Avoid common problems with xml file localization when upgrading from Optimizely CMS 11 to CMS 12.

Tomas Hensrud Gulla | Oct 9, 2024 | Syndicated blog