Hide menu Last updated: Sep 21 2015

Most common property types have built-in persisting and rendering support. 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 also can 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.

C#
[PropertyDefinitionTypePlugIn] 
public class LinkingProperty : PropertyLongString 
{ 
    public IEnumerable<ContentReference> LinkedReferences 
    { 
        get 
        { 
            if (!String.IsNullOrEmpty(String)) 
            { 
                var entries = String.Split(';'); 
                return entries.Select(e => ContentReference.Parse(e)); 
            } 
            return null; 
        } 
        set 
        { 
            base.String = 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.String; } 
}

Indexing references to other content from a custom property

If the custom property stores references to other content instances, you also should 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:

C#
[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 = ContentSoftLinkIndexer.CreateSoftLinkForContent(owner); 
            softLink.ReferencedContentLink = link; 
            softLink.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.

Comments

As of version 9.12.3 (may be before this) the method 'ContentSoftLinkIndexer.CreateSoftLinkForContent' is obsolete.  The message directs you to the SoftLinkFactory which is an Interal API.

I do not think that a method should be marked as obsolete if the alternate approach is and internal API which will change.