Extending the HyperLink editor in Optimizely 11

Anders Hattestad described in his blog post how you can create a custom implementation for the HyperLink editor in Optimizely CMS. However for the newer versions of the CMS an updated solution is required because the internal functionality has changed. It's still a popular request so I decided to share the updated code that works for CMS 11.

Note that I only post the code that has been updated, for the full example please refer to the blog post: world.optimizely.com/blogs/Anders-Hattestad..

First here is the updated code for the custom HyperLink model.

internal class HyperLinkModel
{
    public string Name { get; set; }

    public string DisplayName { get; set; }

    public string Title { get; set; }

    public IEnumerable<ContentReference> Roots { get; set; }

    public string WidgetType { get; set; }

    public IDictionary<string, object> WidgetSettings { get; set; }

    public IEnumerable<Type> LinkableTypes { get; set; }

    public bool Invisible { get; set; }

    public string SearchArea { get; set; }
}

Next is the custom editor descriptor that will initialize the existing fields followed by a new custom text field with the name Other. You can find the code for the custom field in the blog post linked above.

[EditorDescriptorRegistration(TargetType = typeof (string), UIHint = "HyperLink",
EditorDescriptorBehavior = EditorDescriptorBehavior.OverrideDefault)]
public class LinkEditorDescriptor : EditorDescriptor
{
    private readonly LocalizationService _localizationService;

    public LinkEditorDescriptor() : this(LocalizationService.Current)
    {
    }

    public LinkEditorDescriptor(LocalizationService localizationService)
    {
        _localizationService = localizationService;
    }

    public override void ModifyMetadata(ExtendedMetadata metadata, IEnumerable<Attribute> attributes)
    {
        base.ModifyMetadata(metadata, attributes);
        IEnumerable<IContentRepositoryDescriptor> allInstances =
            ServiceLocator.Current.GetAllInstances<IContentRepositoryDescriptor>();
        List<HyperLinkModel> list = (
            from r in allInstances
            orderby r.SortOrder
            where r.LinkableTypes != null && r.LinkableTypes.Any<Type>()
            select new HyperLinkModel
            {
                Name = (r.CustomSelectTitle ?? r.Name),
                Roots = r.Roots,
                WidgetType = "epi-cms/widget/ContentSelector",
                LinkableTypes = r.LinkableTypes,
                SearchArea = r.SearchArea
            }).ToList<HyperLinkModel>();
        list.InsertRange(list.Count, new HyperLinkModel[]
        {
            new HyperLinkModel
            {
                Name = "Email",
                Title = _localizationService.GetString("/episerver/cms/widget/editlink/emailtooltip"),
                DisplayName = _localizationService.GetString("/episerver/cms/widget/editlink/email"),
                WidgetType = "epi-cms/form/EmailValidationTextBox",
                WidgetSettings = new Dictionary<string, object>
                {
                    {
                        "addMailTo",
                        true
                    }
                }
            },
            new HyperLinkModel
            {
                Name = "FreeTextLink",
                Title = "Other links",
                DisplayName = "Other",
                WidgetType = "alloy/TextBoxMustHaveValue"
            },
            new HyperLinkModel
            {
                Name = "ExternalLink",
                Title = _localizationService.GetString("/episerver/cms/widget/editlink/externallinktooltip"),
                DisplayName = _localizationService.GetString("/episerver/cms/widget/editlink/externallink"),
                WidgetType = "epi-cms/form/UrlValidationTextBox"
            },
            new HyperLinkModel
            {
                Name = "Anchor",
                Title = _localizationService.GetString("/episerver/cms/widget/editlink/anchortooltip"),
                DisplayName = _localizationService.GetString("/episerver/cms/widget/editlink/anchor"),
                WidgetType = "epi-cms/form/AnchorSelectionEditor",
                Invisible = true
            }
        });
        metadata.EditorConfiguration["providers"] = list;
        metadata.DisplayName = string.Empty;
        metadata.ClientEditingClass = "epi-cms/widget/HyperLinkSelector";
    }
}