Conditionally hiding properties from editors in CMS 7

Completely hiding properties from editors is simple enough – just add the [ScaffoldColumn(false)] attribute to the property. However there are times when I want to show the property in some situations, and hide it in others. A typical scenario is sharing a local block between several page types. For example, let’s say we have a local block called PromoBlock. PromoBlock has two properties:

  • Title
  • Image

It is used on two page types, LandingPage and ContentPage.

However it has become vital that the PromoBlock on LandingPage has an optional video. We could add the property VideoUrl to PromoBlock, but then it would be presented to editors on the ContentPage, and we don’t want a video there.

One option is to simply make another block for this purpose. In most situations this is the route I’d advise, but it isn’t always the most appropriate. My example is deliberately simplified, and in reality PromoBlock could be used on many pages and have complex behaviour. It could also already be in production and used on many pages, making its replacement a tedious editing task.

Another option is to programmatically hide the VideoUrl property on the ContentPage. In CMS 6 this was easily achieved using the EPiServer.UI.Edit.EditPanel.LoadedPage event. This is no longer available in CMS 7, so we need a different approach. That approach is to use an EditorDescriptor:

[EditorDescriptorRegistration(TargetType = typeof(Url))]
public class HidePromoVideoUrl : EditorDescriptor
{
  public override void ModifyMetadata(
    ExtendedMetadata metadata,
    IEnumerable<Attribute> attributes)
  {
    base.ModifyMetadata(metadata, attributes);
    if (metadata.PropertyName == "VideoUrl" && metadata.Parent.ContainerType == typeof(ContentPage))
    {
      metadata.ShowForEdit = false;
    }
  }
}

The main points of interest here are:

  • EditorDescriptorRegistation attribute needs its TargetType setting to the type of the property we are modifying. In this case it is a Url.
  • metaData.Parent.ContainerType gives the type of the page containing the local block which in turn contains the property we are modifying. metaData.ContainerType would give the type of the block itself, in this case PromoBlock.
  • Once we’ve determined we’re in the right place, hiding the property is a simple matter of setting metadata.ShowForEdit to false.

Leave a Reply

Your email address will not be published. Required fields are marked *