· CMS13 Optimizely CMS

Optimizely CMS 13 breaking changes: GetContentTypePropertyDisplayName

When upgrading from Optimizely CMS 12 to CMS 13, you’ll encounter several breaking changes.

In Optimizely CMS 12, you could get the translated/localized property name like this:

var localizationService = ServiceLocator.Current.GetInstance<LocalizationService>();
var propertyDisplayName = localizationService.GetContentTypePropertyDisplayName(contentData.GetType().Name, property.Name);

This will still work if you have your (localized) property names stored in XML files like this:

<icontentdata>
    <properties>
        <mainbody>
            <caption>Tekstinnhold</caption>
        </mainbody>
    </properties>
</icontentdata>

However, if your editors only use one language, you might not have your property names defined in XML files.

Instead, they may be defined directly using the Display attribute, as shown below. In that case, the code above will no longer return the display name of the property.

[Display(Name = "Tekstinnhold", GroupName = GroupNames.Content, Order = 10)]
public virtual XhtmlString MainBody { get; set; }

If you are using this approach, you can access PropertyDefinition.EditCaption to get the property display name.

public class ImageValidator : IValidate<PageData>
{
    IEnumerable<ValidationError> IValidate<PageData>.Validate(PageData pageData)
    {
        var localizationService = ServiceLocator.Current.GetInstance<LocalizationService>();
        var propertyDefinitionRepository = ServiceLocator.Current.GetInstance<IPropertyDefinitionRepository>();
        var contentLoader = ServiceLocator.Current.GetInstance<IContentLoader>();

        foreach (var property in pageData.Property)
        {
            var xhtmlString = (property as PropertyXhtmlString)?.XhtmlString;
            if (xhtmlString == null)
            {
                continue;
            }

            var hasImage = xhtmlString.Fragments
                .OfType<UrlFragment>()
                .SelectMany(f => f.ReferencedPermanentLinkIds)
                .Any(guid => contentLoader.TryGet(guid, out ImageData _));

            if (!hasImage)
            {
                continue;
            }

            var propertyDefinition = propertyDefinitionRepository.Load(property.PropertyDefinitionID);
            var propertyDisplayName = propertyDefinition?.EditCaption ?? propertyDefinition?.Name ??  property.Name;
            yield return new ValidationError
            {
                ErrorMessage = $"The property {propertyDisplayName} shouldn't contain any images!",
                PropertyName = property.Name,
                Severity = ValidationErrorSeverity.Error
            };
        }
    }
}

With the above update, the resulting validation message still look like this:

Graphical user interface, PowerPoint