Category Archives: Custom Properties

Simplifying allowed content types in Editor Descriptor

Update 2: About a week I noticed that this functionality already exists according to Linus Ekström. But you can take this example on how to simplify attributes with UI hints and being able to read information directly from the Content Type.

Update: Updated to correct code

One of the new things in EPiServer 7.5 is the ability to restrict available content in ContentAreas (and similar Properties). A great way that prevents content to be dragged to a ContentArea compared to the validator option that is common in EPiServer 7 and 7.1 sites.

EPiServer developer Ben McKernan has written a blog post about this.

I’ve simplified this to make it easier for a developer to understand the purpose of the Editor Descriptor and being able to control exactly which types that are allowed from the Content Type.

Cut to the code!

This is how it will look on the accual Content Type when adding a ContentArea Property:

[AllowedContentTypes(typeof(StandardPage))]
public virtual ContentArea StandardPages { get; set; }

The code for the AllowedContentTypes attribute looks like this:

[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = true)]
public class AllowedContentTypesAttribute : UIHintAttribute
{
  public AllowedContentTypesAttribute(params Type[] types) : base("AllowedContentTypes")
  {
    this.Types = types;
  }

  public Type[] Types { get; set; }
}

And the code for the Editor Descriptor – this is a merge between Ben’s code and the original ContentArea Editor Descriptor from the EPiServer.Cms.Shell.UI assembly.

[EditorDescriptorRegistration(TargetType = typeof(ContentArea), UIHint = "AllowedContentTypes")]
public class AllowedContentTypes : EditorDescriptor
{
  public AllowedContentTypes()
  {
    this.ClientEditingClass = "epi-cms.contentediting.editors.ContentAreaEditor";
    this.OverlayConfiguration.Add("customType", "epi-cms.widget.overlay.ContentArea");
  }

  public override void ModifyMetadata(ExtendedMetadata metadata, IEnumerable attributes)
  {
    base.ModifyMetadata(metadata, attributes);

    var attribute = metadata.Attributes.OfType<AllowedContentTypesAttribute>().SingleOrDefault();
    if (attribute != null)
    {
      this.AllowedTypes = attribute.Types;
    }

    metadata.OverlayConfiguration["customType"] = (object)"epi-cms.widget.overlay.ContentArea";
    metadata.CustomEditorSettings["converter"] = (object)"epi-cms.propertycontentarea";
  }
}

Using PropertyDropDownList with EPiServer Dynamic Content

I’m creating a “widget” where the client is supposed to be able to change color to a Teaser. The color options should be editable quite easily.

The widget is added to the page by using Dynamic Content.
So I’m using the PropertyDropDownList added in EPiServer CMS 6 R2 so an administrator can edit the options through the Administrator Mode (or when PagetTypeBuilder 2 comes, a developer by creating a class deriving from IUpdateGlobalPropertySettings<MultipleOptionsListSettings>).

But since all ways to change the Property’s Settings values are locked from external binaries, I couldn’t find any other way to connect my Global Setting to the DropDownList in my Dynamic Content except creating a Custom Property that derives from PropertyDropDownList.

After that I create a Global Setting for DropDownList with some colors which I set as default for my PropertyTeaserColorDropDownList.

So by adding a Property of type PropertyTeaserColorDropDownList in my Dynamic Content class, I can let my Editor select a color from a list managed by the Administrator.

Code examples

public class PropertyTeaserColorDropDownList : PropertyDropDownList
{
}

[DynamicContentPlugIn(DisplayName = "Front Teaser", ViewUrl = "~/Widgets/FrontTeaserWidget/FrontTeaserWidget.ascx")]
public partial class FrontTeaserWidgetControl : WidgetControlBase
{
    public PropertyTeaserColorDropDownList TeaserColor { get; set; }
}

It feels a bit cumbersome to create a Custom Property for this. It would be nice if I could set the SettingsId somehow or if it could be set by some attribute.