Custom properties
Shows how to implement a custom property by selecting a suitable base type.
Most common Optimizely Content Management System (CMS) property types have built-in persisting and rendering support. In most cases, creating custom properties is unnecessary. Change the editorial experience without creating a custom property. However, if a custom property is needed, select a proper base type to inherit from, depending on your data type. Create a template for the data type to make the property visible on templates.
When defining a custom property:
PropertyDefinitionTypePlugInAttributeis now sealed and cannot be inherited.- Use
PropertyDefinitionTypeAttributevia composition to register your custom property. - For types directly inheriting from
PropertyData, you must specify theDataTypeproperty.
Use ContentReference<T> for typed references
ContentReference<T> stores references to a specific content type. The generic type ensures compile-time safety and better clarity when the property is bound to a known content type.
For example:
public IEnumerable<ContentReference<MyPageType>> LinkedPages { get; set; }The following example implements a custom property by selecting a suitable base type (for example, PropertyString, PropertyNumber). The property holds an enumerable of ContentReference and stores it as a serialized string.
[PropertyDefinitionType]
public class LinkingProperty: PropertyLongString {
public IEnumerable<ContentReference> LinkedReferences {
get {
if (!String.IsNullOrEmpty(LongString)) {
var entries = LongString.Split(';');
return entries.Select(e => ContentReference.Parse(e));
}
return null;
}
set {
LongString = String.Join(";", value.Select(r => r.ToString()));
}
}
public override object Value {
get {
return LinkedReferences;
}
set {
IEnumerable<ContentReference> links = value as IEnumerable<ContentReference>;
if (links != null) {
LinkedReferences = links;
} else {
base.Value = value;
}
}
}
public override Type PropertyValueType {
get {
return typeof (IEnumerable<ContentReference>);
}
}
public override object SaveData() {
return LongString;
}
}PropertyDefinitionType for blocks
Block properties use the common PropertyDefinitionType. The block type is now defined using PropertyDefinition.ItemTypeReference, rather than directly on the property type.
For example:
[PropertyDefinitionType]
public class BlockLinkingProperty : PropertyContentReference
{
public ItemTypeReference BlockType { get; set; }
}
NoteThis standardizes block references across CMS 13 and allows consistent binding in the Visual Builder.
Index references to other content from a custom property
A soft link indexer ensures data integrity when the custom property stores references to other content instances. When an editor tries to delete a content item, a warning displays if another content item holds a reference to it. If the custom property inherits PropertyContentReference, PropertyUrl, or PropertyXhtmlString, the base type indexer handles soft indexing. The following example shows a soft link indexer for the previous custom property:
[ServiceConfiguration(typeof (IPropertySoftLinkIndexer))]
public class LinkingPropertyIndexer: IPropertySoftLinkIndexer<IEnumerable<ContentReference>> {
public IEnumerable<SoftLink> ResolveReferences(IEnumerable<ContentReference> propertyValue, IContent owner) {
var softLinks = new List<SoftLink> ();
foreach(var link in propertyValue) {
var softLink = new SoftLink {
OwnerContentLink = owner.ContentLink.ToReferenceWithoutVersion(),
OwnerLanguage = (owner as ILocalizable)?.Language,
ReferencedContentLink = link,
SoftLinkType = ReferenceType.PageLinkReference
};
softLinks.Add(softLink);
}
return softLinks;
}
}The indexer registers with the IOC container for the IPropertySoftLinkIndexer interface. It implements the generic IPropertySoftLinkIndexer<T> interface where the generic argument is the PropertyValueType for the property implementation.
Updated 17 days ago
