Custom properties
Shows how to implement a custom property by selecting a suitable base type.
Most common property types in Optimizely Content Management System (CMS) have built-in persisting and rendering support. In most cases you should not need to create custom properties. You can change the editorial experience without creating a custom property. However, if you need a custom property, you select a proper base type from which you can inherit, depending on the type of your data. You can also create a template for the data type (if you want the property to be visible on templates).
The following example shows how to implement a custom property by selecting a suitable base type (for example, PropertyString
, PropertyNumber
); a property holds an enumerable of ContentReference
and stores it as a serialized string.
[PropertyDefinitionTypePlugIn]
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(PropertyDataCollection properties)
{ return base.LongString; }
}
Index references to other content from a custom property
If the custom property stores references to other content instances, you should also have a "soft" link indexer for the type. In that case, when an editor tries to delete a content item, a warning appears if a property on another content item holds a reference to the item to be deleted. If the custom property is inheriting PropertyContentReference
, PropertyUrl
, or PropertyXhtml
, then the soft indexing is handled by the base type indexer. The following example shows a soft link indexer for the previous custom property above:
[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 is registered with the IOC container for the IPropertySoftLinkIndexer
interface, which implements the generic IPropertySoftLinkIndexer<T>
interface where the generic argument is the PropertyValueType
for the property implementation.
Updated 5 months ago