Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Jeroen Breuer 4908 posts 12265 karma points MVP 5x admin c-trib
    Jan 21, 2014 @ 21:30
    Jeroen Breuer
    0

    Creating a PropertyValueConverter in v7

    Hello,

    I'm working on a simple custom property editor in v7 and the property editor is already done, but I also want to add a custom PropertyValueConverter for it.

    In v6 you could do something like this (from DAMPPEVC example):

    public virtual Attempt<object> ConvertPropertyValue(object value)
    {
        return new Attempt<object>(true, new Model(value.ToString()));
    }

    How can I do this in v7? I've seen some examples, but inside the code return type is hard coded. In my example I want to do something like this:

    @(Model.Content.GetPropertyValue<List<Enum.Packages>>("enumCheckboxList"))

    I'm passing in a list of enum values and want to convert my property editor to that list. Is this possible?

    Jeroen

  • Comment author was deleted

    Jan 21, 2014 @ 21:38

    Hmm,

    Not entirely sure on your approach, but here's our PEVC:

    https://github.com/imulus/Archetype/blob/master/app/Umbraco/Umbraco.Archetype/PropertyConverters/ArchetypeValueConverter.cs

    Usage is:

    @Model.content.GetPropertyValue<Archetype>("prop");//returns an Archetype fully loaded (be sure to look around our repo)

    Hope it helps.

    Tim Geyssens may be of better help.

  • Jeroen Breuer 4908 posts 12265 karma points MVP 5x admin c-trib
    Jan 21, 2014 @ 21:40
    Jeroen Breuer
    0

    Yes I already saw your example, but in your PropertyValueConverter you just hard code that it needs to return a Archetype-object. I don't know the type which I need to convert it too. That's why I need that inside my PropertyValueConverter. In v6 that was the Attempt<object> which you got passed.

    Jeroen

  • Comment author was deleted

    Jan 21, 2014 @ 21:44

    Whoops, I didn't notice your example was to MY example.

    Sorry :)

     

  • Dan Diplo 1554 posts 6205 karma points MVP 6x c-trib
    Jan 21, 2014 @ 23:37
    Dan Diplo
    0

    I'm curious why you can't just reuturn a fixed type? Surely that is what people would want? You couldn't expect to pass any type and it convert it???

  • Jeroen Breuer 4908 posts 12265 karma points MVP 5x admin c-trib
    Jan 22, 2014 @ 06:26
    Jeroen Breuer
    0

    Hmm I could just always return a List with strings in it and convert to whatever I want in my View. I think that's the only thing that will work right now.

    Jeroen

  • Shannon Deminick 1526 posts 5272 karma points MVP 3x
    Jan 22, 2014 @ 07:03
    Shannon Deminick
    100

    First, you probably never want to return List

    .GetPropertyValue<IEnumerable<Enum.Packages>>("enumCheckboxList"))
    

    It's worth noting that currently the legacy IPropertyEditorValueConverters are still compatible in v7 so in theory you can just leave your old ones in there, but these are obsoleted.

    If you want to upgrade to the new v7 ones - which are part of how we will be supporting the 'new cache' then you'll notice there are different conversion methods:

    ConvertDataToSource = from the cache source (currently this is just the xml cache so will always be a string), this converter converts to a 'Source' object which is an intermediary object

    ConvertSourceToObject = from the 'Source' object to what MVC would use like the value in IPublishedContent

    ConvertSourceToXPath = from the 'Source' object to be used in Xpath - don't worry about his for now.

    So given this converter:

    https://github.com/umbraco/Umbraco-CMS/blob/7.0.2/src/Umbraco.Web/PropertyEditors/ValueConverters/MarkdownEditorValueConverter.cs

    it declares the 'Object' output type as IHtmlString

    [PropertyValueType(typeof(IHtmlString))]
    

    which means that the object that will be output in a view will be IHtmlString. This converter has no ConvertDataToSource because the 'intermediary' value is a string and that is what it should be.

    Given this converter:

    https://github.com/umbraco/Umbraco-CMS/blob/7.0.2/src/Umbraco.Core/PropertyEditors/ValueConverters/DatePickerValueConverter.cs

    it declares the 'Object' output type as DateTime

    [PropertyValueType(typeof(DateTime))]
    

    this converter doesn't have a ConvertDataToSource method, because the intermediary value is DateTime which is what automatically gets returned from the ConvertSourceToObject method since there's no need for conversion there.

    Given all of the above, the

    .GetPropertyValue<T> 
    

    method will try to find a converter for this property, when it finds one it will get the 'Object' result from ConvertSourceToObject, then if the result is not of type 'T' it will try to automatically convert the object result to 'T' using type converters, etc...

  • Jeroen Breuer 4908 posts 12265 karma points MVP 5x admin c-trib
    Jan 22, 2014 @ 20:34
    Jeroen Breuer
    0

    This is what my converter currently looks like:

    [PropertyValueCache(PropertyCacheValue.All, PropertyCacheLevel.Request)]
    public class EnumListsConverter : PropertyValueConverterBase
    {
        public override bool IsConverter(PublishedPropertyType propertyType)
        {
            return "EnumCheckBoxList".Equals(propertyType.PropertyEditorAlias);
        }
    
        public override object ConvertSourceToObject(PublishedPropertyType propertyType, object source, bool preview)
        {
            if (source == null)
            {
                return null;
            }    
    
            try
            {
                return JsonConvert.DeserializeObject<IEnumerable<string>>(source.ToString());
            }
            catch (Exception ex)
            {
                return null;
            }
    
        }
    }

    I can use it like this in Razor:

    var list = Model.Content.GetPropertyValue<IEnumerable<string>>("enumCheckboxList").Select(x => (Packages)Enum.Parse(typeof(Packages), x));

    @foreach(var item in list) { if(item == Packages.Archetype) { <p>You have chosen the Archetype package.</p> } } 

    Thanks for the help.

    Jeroen

Please Sign in or register to post replies

Write your reply to:

Draft