Nibble

A First look at Property Editors in Umbraco v5

Umbraco v5 introduces a new definition: Property Editor

From the wiki: A Property Editor is the editor that a Data Type references. In Umbraco versions previous to version 5, there was no official name given to the editor that a Data Type referenced and it was also known as a Data Type. In version 5 we differentiate between the 2 aspects of Umbraco. A Data Type is defined by the Administrator of Umbraco which references a Property Editor. A Property Editor on the other hand is defined by a developer and compiled into a DLL.

So where in previous umbraco versions we talked about creating custom datatypes this will be know as property editors in v5.

On this blog I always used the same example when creating custom datatypes, a textarea where you can set a limit on the amount of characters (like in this post).

image

So as a first attempt at creating a property editor for umbraco v5 I created the same control. Of course this is build against the CTP release so there might be changes by the time v5 is released (if so I’ll do some follow up posts)

To get started with creating property editors, take a look at the v5 Wiki: Developing Property Editors

We’ll need to implement 3 classes, PropertyEditor, EditorModel and PrevalueModel (and in this case I’ll also have a razor view for my content editor control).

image

 

Property Editor

Core class which defines the Property Editor

using Umbraco.Cms.Model.BackOffice.PropertyEditors;
 
namespace Umbraco.Addons.PropertyEditors.CharLimit
{
    [PropertyEditor("E3FAF03B-C3A5-4630-B917-9B6D9F645833", 
        "CharLimit", "Text Area with character limit")]
    public class CharLimitEditor : PropertyEditor<CharLimitEditorModel, CharLimitPreValueModel>
    {
        public CharLimitEditor()
        {       
        }
 
        public override CharLimitEditorModel CreateEditorModel(CharLimitPreValueModel preValues)
        {
            return new CharLimitEditorModel(preValues);
        }
 
        public override CharLimitPreValueModel CreatePreValueEditorModel(string preValues)
        {
            return new CharLimitPreValueModel(preValues);
        }
    }
}

 

PreValueModel

Used to provide configuration settings for the Property Editor

using Umbraco.Cms.Model.BackOffice.PropertyEditors;
using Umbraco.Cms.Model.BackOffice.Editors;
 
namespace Umbraco.Addons.PropertyEditors.CharLimit
{
    public class CharLimitPreValueModel : PreValueModel
    {
        public CharLimitPreValueModel(string preValues)
            : base(preValues)
        { }
 
        public int CharacterLimit { get; set; }
 
        [AllowDocumentTypePropertyOverride]
        public bool IsRequired { get; set; }
 
        [AllowDocumentTypePropertyOverride]
        public string RegexValidationStatement { get; set; }
 
    }
}

image

An awesome improvement here is that you can mark settings with the AllowDocumentTypePropertyOverride, doing so will make them available on the add / edit property form of the document type

image

EditorModel

The EditorModel class is the class with the properties that a CMS editor will see

using System.Collections.Generic;
using Umbraco.Cms.Model.BackOffice.PropertyEditors;
using System.ComponentModel.DataAnnotations;
using Umbraco.Cms.Model.BackOffice;
using System.Text.RegularExpressions;
using Umbraco.Cms.Web.EmbeddedViewEngine;
 
namespace Umbraco.Addons.PropertyEditors.CharLimit
{
    [EmbeddedView("Umbraco.Addons.PropertyEditors.CharLimit.Views.CharLimitEditor.cshtml", 
        "Umbraco.Addons.PropertyEditors")]
    public class CharLimitEditorModel : EditorModel<CharLimitPreValueModel>, IValidatableObject
    {
 
        public CharLimitEditorModel(CharLimitPreValueModel preValueModel)
            : base(preValueModel)
        {
            
        }
 
        [DisplayFormat(ConvertEmptyStringToNull = false)]
        [ShowLabel(false)]
        public string Value { get; set; }
 
        public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
        {
            //ensure the string is empty and never ‘null’
            if (string.IsNullOrEmpty(Value)) Value = string.Empty;
 
            if (PreValueModel.IsRequired && string.IsNullOrEmpty(Value))
            {
                yield return new ValidationResult(
                    "Value is required", new[] { "Value" });
            }
            else if (!string.IsNullOrEmpty(PreValueModel.RegexValidationStatement) && 
                !Regex.IsMatch(Value, PreValueModel.RegexValidationStatement))
            {
                yield return new ValidationResult(
                    "Value does not match the required pattern", new[] { "Value" });
            }
        }
    }
}

 

note here that you have much more control over the validation

View

@inherits System.Web.Mvc.WebViewPage<Umbraco.Addons.PropertyEditors.CharLimit.CharLimitEditorModel>
@using System.Web.Helpers;
@using System.Web.Mvc;
@using System.Web.Mvc.Ajax;
@using System.Web.Mvc.Html;
@using System.Web.Routing;
@using System.Web.WebPages;
@using Microsoft.Web.Mvc;
@using ClientDependency.Core;
@using ClientDependency.Core.Mvc;
@using Umbraco.Cms.Web;
@using Umbraco.Cms.Web.Editors;
@using Umbraco.Addons.PropertyEditors.CharLimit;
 
@Html.ValidationMessageFor(x => Model.Value)
 
@Html.TextAreaFor(x => Model.Value)
 
@if (Model.PreValueModel.CharacterLimit > 0)
{     
    <br/><span class=’limitstatus’></span>
 
    <script type="text/javascript">
    (function ($) {
        $(document).ready(function () {  
            $(‘#@Html.IdFor(x => Model.Value)’).keyup(function () {
               
                var limit = @Model.PreValueModel.CharacterLimit.ToString();
                if ($(this).val().length > limit) {
                        $(‘.limitstatus’, $(this).parent()).html(‘You cannot write more then ‘ + limit + ‘ characters!’);
                    $(this).val($(this).val().substr(0, limit));
                }
                else {
                        $(‘.limitstatus’, $(this).parent()).html(‘You have ‘ + (limit - $(this).val().length) + ‘ characters left.’);
                }
            });
        });
    })(jQuery);
    </script>
}
 

So for the content editor control I created a razor view, since I’ll need to output a textarea but also some javascript

Want to see more examples of v5 property editors, make sure to take a look at the v5 sourcecode:

http://umbraco.codeplex.com/SourceControl/list/changesets

Leave a Reply