Copied to clipboard

Flag this post as spam?

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


  • Simone Chiaretta 134 posts 541 karma points c-trib
    Apr 12, 2016 @ 08:57
    Simone Chiaretta
    0

    How to access a "Content Picker" value using ModelBuilder

    I've been playing with the new ModelBuilder and I was wondering I could access a node that is referenced via a Content Picker using the strongly-typed model.

    At the moment, if I do myDocument.myContentPickerContent I get the id of the node referenced via the content picker, just like I would get when using the IPublishedContent interface. But with the TypedContent approach I could do:

    .GetPropertyValue<IPublishedContent>("contentPicker")
    

    And I would get the node.

    How can I obtain the same result using ModelBuilder?

    Ideally I'd like to do

    MyRelatedNode node = myDocument.myContentPickerContent;
    

    Is it good practice, the wiki says that is "ugly" to reference another model from within another model? Or shall I resolve the related node in the controller?

    Thx Simone

  • Jeavon Leopold 3074 posts 13632 karma points MVP 11x admin c-trib
    Apr 12, 2016 @ 09:00
    Jeavon Leopold
    101

    Hi Simone,

    I would recommend using my Core Value Converters v3 package which will strongly type your content pickers as IPublishedContent or you can go further and extend with your own Models.

    v3 is currently available as a alpha on MyGet but I'm getting close to release now

    There is documentation about the advanced conversions you can do with v3 for Model Builder here

    Jeavon

    p.s. v2 will work just fine with converting Content Picker to IPublishedContent too but you can use the advanced stuff with v2

  • Simone Chiaretta 134 posts 541 karma points c-trib
    Apr 12, 2016 @ 09:11
    Simone Chiaretta
    0

    Yeah, I was using the Core Value converters with the "normal" approach.

    But thinking about it, not sure having the model refer another model is a good idea... how does cache behave in this case? if the main node changes, the cache will refresh, but what if the "linked" model changes?

  • Stephen 767 posts 2273 karma points c-trib
    Apr 12, 2016 @ 09:59
    Stephen
    1

    Let's try to clarify the situation...

    If the property contains an identifier, and what it should return is something else, then that is the job of a PropertyValueConverter. Which is basically what Jeavon has implemented.

    Core should ship with a proper value converter for pickers, that would return an instance of the picked content item. However, that would break compatibility for many sites. This is the sole reason why the current converter still returns an integer. In most cases you will want to replace it by a converter such as Jeavon's.

    Keeping a reference to another content item, within a model, can indeed cause caching issues (such as, that other content item is republished but your model isn't aware of it). This is why it is generally considered "ugly".

    However, property value converters can declare how they want to cache the value that they return, and there is a mechanism in Core to manage that cache. It is far from perfect but good enough. So what happens is: the property value converter declares that its value should only be cached for the duration of the request, because it is another content item.

    Next piece of the puzzle: the converter knows that you have picked "a content item". Unless you write your own specific converter, it cannot know which type of content item your are picking. So the converter, in most cases, declares that it returns an IPublishedContent. And the Models Builder generates:

    public IPublishedContent ThatContent
    {
        get 
        {
            return this.GetPropertyValue<IPublishedContent>("thatContent");
        }
    }
    

    What-if you know that in your special content, the content picker has been configured to pick content items of type "Pickable"? Either you write you own custom property value converter... or you override the property in a partial class:

    [ImplementPropertyType("thatContent")]
    public Pickable ThatContent
    {
        get
        {
            return this.GetPropertyValue<Pickable>("thatContent");
        }
    }
    

    When you rebuild the models, the Models Builder will detect that you have implemented the property, and will not implement it.

    Making sense?

  • Jeavon Leopold 3074 posts 13632 karma points MVP 11x admin c-trib
    Apr 12, 2016 @ 11:03
    Jeavon Leopold
    0

    Exactly what Stephen said!

    In core property value converters we declare our cache level, e.g. https://github.com/Jeavon/Umbraco-Core-Property-Value-Converters/blob/v2/Our.Umbraco.PropertyConverters/ContentPickerPropertyConverter.cs#L159

    In v3 we have tried to make it super easy for people to define their special models types and for the rest return IPublishedContent, the multinode tree picker example here is a good one

Please Sign in or register to post replies

Write your reply to:

Draft