Copied to clipboard

Flag this post as spam?

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


  • Tim Bennett 23 posts 155 karma points
    Aug 10, 2020 @ 11:27
    Tim Bennett
    0

    Umbraco n00b - unable to render Composition Properties for children within foreach loop

    Hiya!

    I'm pretty new to Umbraco and MVC and so please excuse my stupidity and/or sloppy use of terminology!

    I'm banging my head against the wall trying to get shared Properties from a Composition to render for children within a series of foreach loops.

    Essentially, I have a blog (it's not a blog, but for argument's sake y'know) that has 4 categories that I'm rendering on the page as individual collections of Bootstrap Card-alike HTML objects.

    To do this I've got four Document Types that all share the same Parent and pull their Properties from a single Composition. On the parent Template I've built 4 Queries, one for each category, and then perform a foreach to loop through the categories, and then a second foreach loop within the first to loop through the individual posts for each category and render them to page. This all works fine, my problem is that using @item.Value("something") to render any of the shared properties from the Composition do not render on the page. I can get a unique Property to render, and @item.Name will work too. As far as I can deduce, my loops are working, i.e. accessing the correct post instance, but the shared Properties are perhaps undefined because something about the loop is causing a conflict? I can see in dev tools that no code has been inserted into the HTML where it should be for those Properties. I can get the exact same inner foreach code to render correctly outside of the loop.

    I hope this all makes sense, and thanking you in advance for any help!

    Here is my code:

    @{ var retouch = Umbraco.Content(Guid.Parse("941f42da-7a1d-4450-9dba-a679c3fbafb7")) .ChildrenOfType("retouchService") .Where(x => x.IsVisible());

    var design = Umbraco.Content(Guid.Parse("941f42da-7a1d-4450-9dba-a679c3fbafb7"))
    .ChildrenOfType("designService")
    .Where(x => x.IsVisible());
    
    var print = Umbraco.Content(Guid.Parse("941f42da-7a1d-4450-9dba-a679c3fbafb7"))
    .ChildrenOfType("printService")
    .Where(x => x.IsVisible());
    
    var technical = Umbraco.Content(Guid.Parse("941f42da-7a1d-4450-9dba-a679c3fbafb7"))
    .ChildrenOfType("technicalService")
    .Where(x => x.IsVisible());
    <!-- .// queries-->
    
    <!-- array to store service names -->
    string[] services = {"retouch", "print", "design", "techical"};
    }
    
    <!-- loop services in array-->
    @foreach (var service in services)
        {
        string queryName = @service.ToString();
    
        <h1>@service</h1>
    
        <div class="container-fluid">
            <div class="row justify-content-center">
                <!-- loop service posts-->
                @foreach (var item in retouch)
                {
                var serviceDetails = item.Value("serviceDetails");
                var color = item.Value("color");
                <div class="col-12 col-md-6 col-lg-3 my-4">
                    <div class="event" href="link.html">
                        <img class="img-fluid" src="https://via.placeholder.com/640" alt="@item.Name main image" />
                        <div class="content text-center">
                            <div class="col-12 d-inline upton">@item.Name</div>
                            <div class="rollover">
                                <p>@serviceDetails</p>
                                <div class="row">
                                    <div class="col-12">
                                        <a href="/portfolio#@item.Name"><div class="rolllover-btn my-3">@item.Name portfolio</div></a>
                                    </div>
                                    <div class="col-12">
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
                } <!-- .//end service posts loop -->
            </div>
        </div><hr class="rainbow" />
        } <!-- .//end services loop-->
    
  • Marc Goodson 2155 posts 14408 karma points MVP 9x c-trib
    Aug 10, 2020 @ 20:07
    Marc Goodson
    0

    Hi Tim

    Trying to visualise what your setup is here, to try and work out why it's going awry...

    would I be right in thinking that you have a 'blog' section with 'four categories' underneath, and underneath each category... many blog posts?

    BlogSection (that has a guid: 941f42da-7a1d-4450-9dba-a679c3fbafb7)

    • retouch (retouchService)
      • BlogPost1
      • BlogPost2
      • BlogPost3
    • design (designService)
      • BlogPost4
      • BlogPost5
      • BlogPost6
    • technical (technicalService)
    • print (printService)

    ??

    If so then in your code you are setting a variable for each 'category'

    var retouch = Umbraco.Content(Guid.Parse("941f42da-7a1d-4450-9dba-a679c3fbafb7")) .ChildrenOfType("retouchService") .Where(x => x.IsVisible())
    

    which looks to be getting the node with the 941 guid... which feels like possibly the 'Blog' node, and then finding the children of 'retouchService' underneath, which is the 'Category' node?

    Then when you write out your cards your foreach is:

     @foreach (var item in retouch)
            {
    

    but the 'retouch' is just the category node?, it isn't the blogposts? the blogposts are underneath?

    so should it be:

     @foreach (var item in retouch.Children())
            {
    

    ???

    or are you writing out the Children 'just fine' and can see the @item.Name is correct for each blog post? and it's just the custom properties you can't see?

    if so how are they added to the blog post? or the category?

    If it's for the category, then those properties won't exist on the blog post, and you'll need to fallback to ancestors to read the values from the parent 'category' nodes if that makes sense!!!

    eg

    item.Value("serviceDetails", fallback: Fallback.ToAncestors));
    

    or have I totally misunderstood!

    regards

    Marc

  • Tim Bennett 23 posts 155 karma points
    Aug 10, 2020 @ 21:19
    Tim Bennett
    0

    Hi Marc, thanks for your response!

    You're close in your analysis of how I've structured my build, but not quite right, I'll try and explain my build in the terms you put it and see if that helps!

    or are you writing out the Children 'just fine' and can see the @item.Name is correct for each blog post? and it's just the custom properties you can't see?

    Exactly this! The custom properties that are not rendering are coming from the blog posts. item.Name renders no problem.

    I have a Document Type called Services, and it has four Children: retouchService, printService, designService, and technicalService. These children then have a number of "blog posts" of their own. Those Children all inherit their Properties from a Composition. It's these properties that won't render within my loop. The content for the Properties is coming from the blog post, e.g. Services>Retouch Services>Beauty).

    On the Service page template (the code in OP) I have four separate guid's, one for each Children of Services. I then manually create a string array of the names of the Service categories services. Next I foreach through services to run the second foreach that runs through the "blog posts".

    After reading your suggestions it does seems like

    Here is the Services page in a basic wireframe. Worth mentioning that in the image the blogposts are just looping through the first category regardless of the heading : layout example

  • Marc Goodson 2155 posts 14408 karma points MVP 9x c-trib
    Aug 11, 2020 @ 10:46
    Marc Goodson
    0

    Hi Tim

    What is the document type for a blog post? is it blogPost, or is it different for each category? eg is retouchService the alias of blog posts you've created in the retouch category or the alias of the category.

    When you talk about the doc types sharing a common parent, but using a composition - does that mean you are combining 'nested document types' with compositions... as that does complicate things! Best to use either ONLY nested document types or Compositions as the approach for building out your doc types.

    So the Composition which features the 'serviceDetail' and 'color' property - is that added to the Blog Post document type or to the Category Doc Type - or to a Parent Doc Type?

    With the code you have posted, it doesn't look like you are looping through the blog posts?

    Sorry just trying to get my head around it :-)

    regards

    Marc

  • Tim Bennett 23 posts 155 karma points
    Aug 11, 2020 @ 11:58
    Tim Bennett
    0

    No, it's fine, I'm sure I'm doing a terrible job of explaining myself!

    Hopefully this helps:

    enter image description here

    You are correct, in my example code I'm only looping through the retouch services posts on each iteration of the main loop; my intention is to change the condition for that loop so that it is iterating through the values of the services string array 12 lines above (and also utilising the queryName variable - I think I've made a right pig's ear of that though?), and thus iterating through the the guid's and returning the different posts for each service category.

  • Tim Bennett 23 posts 155 karma points
    Aug 11, 2020 @ 12:01
    Tim Bennett
    0

    oh, and I should add, my intention is for none of this data to be rendered other than on this page, the posts won't lead to their own pages, rather to a relevantly filtered version of the portfolio page.

  • Tim Bennett 23 posts 155 karma points
    Aug 11, 2020 @ 12:23
    Tim Bennett
    0

    I've just knocked this together as a rough example of what I'm trying to achieve, albeit styled like my earlier screenshot.

    enter image description here

        <ul>
        @foreach (var item in retouch)
        {
        var color = @item.Value("color");
        <li>
            <h3><a href="@item.Url">@item.Name</a></h3>
            <h5>Service Name: @item.Value("serviceName")</h5>
            <h5 class="d-inline" style="background-color:@color">Colour: @color</h5>
        </li>
        }
    </ul>
    
    <ul>
        @foreach (var item in print)
        {
        var color = @item.Value("color");
        <li>
            <h3><a href="@item.Url">@item.Name</a></h3>
            <h5>Service Name: @item.Value("serviceName")</h5>
            <h5 class="d-inline" style="background-color:@color">Colour: @color</h5>
        </li>
        }
    </ul>
    
    <ul>
        @foreach (var item in design)
        {
        var color = @item.Value("color");
        <li>
            <h3><a href="@item.Url">@item.Name</a></h3>
            <h5>Service Name: @item.Value("serviceName")</h5>
            <h5 class="d-inline" style="background-color:@color">Colour: @color</h5>
        </li>
        }
    </ul>
    
    <ul>
        @foreach (var item in technical)
        {
        var color = @item.Value("color");
        <li>
            <h3><a href="@item.Url">@item.Name</a></h3>            
            <h5>Service Name: @item.Value("serviceName")</h5>
            <h5 class="d-inline" style="background-color:@color">Colour: @color</h5>
        </li>
        }
    </ul>
    
  • Tim Bennett 23 posts 155 karma points
    Aug 11, 2020 @ 16:16
    Tim Bennett
    0

    Well, I've been tinkering away all day and I've managed to get some of the composition properties to render, I just don't know how!

    I can get each individual guid to render perfectly outside of the main loop, but I can't get images to render within the loop, and I can't get the inner loop to iterate through each of the guid's in turn.

    I've commented the code below, marking the two lines of code in question.

    @inherits Umbraco.Web.Mvc.UmbracoViewPage<ContentModels.Prototyping>
    @using ContentModels = Umbraco.Web.PublishedModels;
    @{
    Layout = "master.cshtml";
    }
    
    @{
    <!-- data queries for service posts-->
    var retouch = Umbraco.Content(Guid.Parse("941f42da-7a1d-4450-9dba-a679c3fbafb7"))
    .ChildrenOfType("retouchService")
    .Where(x => x.IsVisible());
    
    var design = Umbraco.Content(Guid.Parse("941f42da-7a1d-4450-9dba-a679c3fbafb7"))
    .ChildrenOfType("designService")
    .Where(x => x.IsVisible());
    
    var print = Umbraco.Content(Guid.Parse("941f42da-7a1d-4450-9dba-a679c3fbafb7"))
    .ChildrenOfType("printService")
    .Where(x => x.IsVisible());
    
    var technical = Umbraco.Content(Guid.Parse("941f42da-7a1d-4450-9dba-a679c3fbafb7"))
    .ChildrenOfType("technicalService")
    .Where(x => x.IsVisible());
    <!-- .// queries-->
    
    <!-- array to store service categories -->
    string[] services = {"retouch", "print", "design", "technical"};
    }
    
    <!-- loop service categories-->
    @foreach (var service in services)
    {
    <div class="container-fluid" id="@service"> <!-- uses service to define id -->
        <div class=" d-inline headerFont kruger">@service</div>
        <div class="row justify-content-center">
            <!-- loop service posts-->
            <!-- this should be looping though items in service -->
            @foreach (var item in retouch)
            {
            var serviceDetails = item.Value("serviceDetails");
            <div class="col-12 col-md-6 col-lg-3 my-4">
                <div class="event" href="link.html">
                    <img class="img-fluid" src="https://via.placeholder.com/640" alt="@item.Name main image" /> <!-- this should be rendering item.value = mainImage -see workign example at bottom of page -->
                    <div class="content text-center">
                        <div class="col-12 d-inline upton">@item.Name</div>
                        <!-- Rollover content -->
                        <div class="rollover">
                            <p>@serviceDetails</p>
                            <div class="row">
                                <div class="col-12">
                                    <a href="/portfolio#@item.Name"><div class="rolllover-btn my-3">@item.Name portfolio</div></a>
                                </div>
                                <div class="col-12">
                                </div>
                            </div>
                        </div><!-- .// end rollover content -->
                    </div>            
                </div>
            </div>
            } <!-- .//end service posts loop -->
        </div>
    </div><hr class="rainbow" />
    } <!-- .//end services loop-->
    
    
    <!-- working example outside loop -->
    <div class="container-fluid">
        <div class="row justify-content-center">
            @foreach (var item in design)
            {
            var mainImage = item.Value<IPublishedContent>("mainimage");<!-- Main image defined-->
                var serviceName = item.Value("serviceName");
                var serviceDetails = item.Value("serviceDetails");
                var color = item.Value("color");
                <div class="col-12 col-md-6 col-lg-3 my-4">
                    <div class="event" href="link.html">
                        <img class="img-fluid" src="@mainImage.Url" alt="@item.Name main image" />
                        <div class="content text-center">
                            <div class="col-12 d-inline upton">@serviceName</div>
                            <div class="rollover">
                                <p>@serviceDetails</p>
                                <div class="row">
                                    <div class="col-12">
                                        <a href="/portfolio#@item.Name"><div class="rolllover-btn my-3">@item.Name portfolio</div></a>
                                    </div>
                                    <div class="col-12">
    
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
                }
        </div>
    </div>
    <!-- .// end working example -->
    
  • Marc Goodson 2155 posts 14408 karma points MVP 9x c-trib
    Aug 13, 2020 @ 08:02
    Marc Goodson
    100

    Hi Tim

    Good to see that you are writing out the custom properties successfully.

    Image wise? is the alias 'mainimage" or "mainImage" the case is important I think when reading the properties by alias... if not, do you have a 'single' media picker or multiple media picker - if it's multiple you'll want:

    var mainImage = item.Value<IEnumerable<IPublishedContent>>("mainimage");
    

    Finally what you are trying to do isn't necessarily the best way to achieve what you are after - although context is everything - there are several other approaches that might work out better - but if I were you I'd get this to work first, as you are learning much as you work things out...

    So taking your approach instead of having 4 different variables holding the blog posts for each category 'you could' keeping close to your planned approach have a single dictionary variable instead...

    var blogPostsByCategory = new Dictionary<string,IEnumerable<string>>();
    

    You could then add to this dictionary like so, the different blog posts per category:

    blogPostsByCategory.Add("retouch",Umbraco.Content(Guid.Parse("941f42da-7a1d-4450-9dba-a679c3fbafb7")) .ChildrenOfType("retouchService") .Where(x => x.IsVisible()));
    blogPostsByCategory.Add("technical",Umbraco.Content(Guid.Parse("941f42da-7a1d-4450-9dba-a679c3fbafb7"))
    .ChildrenOfType("technicalService")
    .Where(x => x.IsVisible()));
    
    etc
    

    The dictionary 'key' would match the 'text' in your services array... but you might find you don't need that now with this approach... because now you can loop through the dictionary object keys...

    @foreach (var serviceKey in blogPostsByCategory.Keys){
         string queryName = @serviceKey;
    <h1>@serviceKey</h1>
    <div class="container-fluid">
            <div class="row justify-content-center">
                <!-- loop service posts-->
                @foreach (var item in blogPostsByCategory[serviceKey])
                {
                    // you are now reading the blog posts for this particular category...
    

    Hopefully makes sense, I think it's true to what you are trying to do...

    But there are other approaches too , using the power of Grouping in Linq statements, and using Partial Views for each grouping, etc the best approach depends a lot on the number of blog posts in each category and whether editors need control over the order that that they are written out on the page... but for now I'd get the images written out nicely with different blog posts for each category to cement your understanding.

    regards

    marc

  • Tim Bennett 23 posts 155 karma points
    Aug 13, 2020 @ 19:39
    Tim Bennett
    0

    Hi Marc,

    funnily enough, what you have suggested is exactly what my friend showed me how to do yesterday! I intended to upload the code last night but ended up melting in the heat instead. I think part of my confusion is coming from JS I'm used to just throwing anything at a var and it coming out the other end intact!

    The one thing we couldn't solve was the rendering the image, I have tried every variation from the Umbraco docs and web searches to no avail - including your snippet above. Every time it returns a value of null. e.g. this is returned from your snippet:

    'Umbraco.Web.PublishedModels.RetouchService' does not contain a definition for 'Value'

    Here's the current code, which will load the page but with placeholder images instead:

    @{
        var retouch = Umbraco.Content(Guid.Parse("941f42da-7a1d-4450-9dba-a679c3fbafb7"))
        .ChildrenOfType("retouchService")
        .Where(x => x.IsVisible());
    
        var design = Umbraco.Content(Guid.Parse("941f42da-7a1d-4450-9dba-a679c3fbafb7"))
        .ChildrenOfType("designService")
        .Where(x => x.IsVisible());
    
        var print = Umbraco.Content(Guid.Parse("941f42da-7a1d-4450-9dba-a679c3fbafb7"))
        .ChildrenOfType("printService")
        .Where(x => x.IsVisible());
    
        var technical = Umbraco.Content(Guid.Parse("941f42da-7a1d-4450-9dba-a679c3fbafb7"))
        .ChildrenOfType("technicalService")
        .Where(x => x.IsVisible());
    
    
        var services = new Dictionary<string, dynamic>
        ();
        services.Add("retouch", retouch);
        services.Add("print", print);
        services.Add("design", design);
        services.Add("technical", technical);
    
        foreach (var service in services) {
        <div class="container-fluid mt-5" id="@service.Key">
            <div class="row justify-content-center mt-2 mb-2">
                <div class=" d-inline upton">
    
                    @service.Key Services
                </div>
            </div>
            <div class="row justify-content-center">
    
                @foreach (var item in service.Value) {
    
                var mainImage = Model.Value<IPublishedContent>("mainImage") == null ? "http://via.placeholder.com/640" : Model.Value<IPublishedContent>
                        ("mainImage").Url;
                        <div class="col-12 col-md-6 col-lg-3 my-4">
                            <div class="event" href="link.html">
                                <img class="img-fluid" src="@mainImage" alt="@item.Name main image" /> <!-- this should be rendering item.value = mainImage -see workign example at bottom of page -->
                                <div class="content text-center">
                                    <div class="col-12 d-inline upton">@item.Name</div>
                                    <!-- Rollover content -->
                                    <div class="rollover">
                                        <p>@item.ServiceDetails</p>
                                        <div class="row">
                                            <div class="col-12">
                                                <a href="/portfolio#@item.Name"><div class="rolllover-btn my-3">@item.Name portfolio</div></a>
                                            </div>
                                            <div class="col-12">
                                            </div>
                                        </div>
                                    </div><!-- .// end rollover content -->
                                </div>
                            </div>
                        </div>
    
                        } @* // end item in service.Value *@
    
            </div>
        </div>
    
        } @* // end services foreach *@
    
        }
    
  • Amir Khan 1287 posts 2744 karma points
    Aug 13, 2020 @ 20:26
    Amir Khan
    0

    Is it possible that instead of Model.Value

  • Marc Goodson 2155 posts 14408 karma points MVP 9x c-trib
    Aug 13, 2020 @ 20:37
    Marc Goodson
    0

    Hi Tim

    Getting there then!

       Model.Value<IPublishedContent>("mainImage")
    

    will be looking for the value on the current model, eg the page the template loads, but you are looping through the blogposts and 'item' refers to the individual post so

    item.Value<IPublishedContent>("mainImage")
    

    would look for that property with alias mainImage on the item.

    for debugging @item.HasProperty("mainImage") will tell you if the alias is correct @item.HasValue("mainImage") to tell you if the value exists and @item.Value<string>("mainImage") should give you the raw value... before the attempt to convert to IPublishedContent - if it has been set...

    if you get true for the first two, then the third one may give a clue as to why it is null...

    regards

    Marc

  • Amir Khan 1287 posts 2744 karma points
    Aug 13, 2020 @ 20:55
    Amir Khan
    0

    Thanks Marc, my copy / paste didn't carry over in my reply.

  • Marc Goodson 2155 posts 14408 karma points MVP 9x c-trib
    Aug 14, 2020 @ 07:55
    Marc Goodson
    0

    Hi Amir

    Sorry I didn't notice your reply, but looks like we had almost the same realisation at almost exactly the same time!! :-P

    regards

    Marc

  • Tim Bennett 23 posts 155 karma points
    Aug 13, 2020 @ 22:29
    Tim Bennett
    0

    Hi Marc & Amir,

    Yeah, item.Value was my first approach and then when that didn't work I tried Model.Value. I've tried debugging item.HasProperty and item.HasValue and the're returning false: enter image description here enter image description here

    I feel like you're pushing me towards the notion that mainImage may be the incorrect Property name, but I've checked that, and I've had it render fine outside of this loop previously. Colour me confused. Here's the Document Type, the other properties render and I've checked that there are definitely image files uploaded!

    enter image description here

  • Marc Goodson 2155 posts 14408 karma points MVP 9x c-trib
    Aug 14, 2020 @ 06:19
    Marc Goodson
    0

    Hi Tim

    The three debug things, will test whether item has the property, whether it has a value, and what it's raw value is - so not just about the alias! just to help pinpoint where it's falling down and useful to know!

    It is definately the item variable that refers to the blogpost.

    It looks like you might have 'Modelsbuilder' turned on?

    And consequently ChildrenOfType is returning the generated PublishedModel for the blog post (which is what the underlying item is... eg Umbraco.Web.PublishedModels.RetouchService).

    Now these generated Models should implement IPublishedContent - and it is the PublishedContent Extensions here:

    https://github.com/umbraco/Umbraco-CMS/blob/0886ada39c4651fcd0a8bec5bce4358972791c45/src/Umbraco.Web/PublishedContentExtensions.cs

    that have the helper methods for .Value and .HasValue and they are in the Umbraco.Web namespace

    So I'm wondering if you add

    @using Umbraco.Web

    to the top of your view whether your methods begin to work?

    regards

    Marc

  • Tim Bennett 23 posts 155 karma points
    Aug 14, 2020 @ 09:13
    Tim Bennett
    0

    Hiya, Adding @using Umbraco.Web didn't work :( here's the top of my file:

    @inherits Umbraco.Web.Mvc.UmbracoViewPage<ContentModels.Prototyping>
    @using ContentModels = Umbraco.Web.PublishedModels;
    @using System.Dynamic;
    @using Umbraco.Web;
    
  • Tim Bennett 23 posts 155 karma points
    Aug 14, 2020 @ 09:22
    Tim Bennett
    0

    I've just noticed this in debugging though: enter image description here

    I have no idea why that has capitalised the property name! I've tried calling it via and again no joy.

    There is a entry for mainImage outside item too scratches head

    enter image description here

    I'd just like to add that I'm really appreciative of the help, and I'm paying it forward by helping someone else write JavaScript for Photoshop because you've inspired me to be helpful! Thanks!

  • Marc Goodson 2155 posts 14408 karma points MVP 9x c-trib
    Aug 14, 2020 @ 11:47
    Marc Goodson
    0

    Hi Tim

    Modelsbuilder I think has turned it into a property in its own right...

    so try:

    @item.MainImage.Url
    

    but I think if you add the using Umbraco.Web statement at the top of the view you'll still be able to use the IPublishedContent HasValue extensions...

    (I don't tend to use Modelsbuilder - for very convoluted reasons - but it is hopefully making it easier here!)

    regards

    Marc

  • Tim Bennett 23 posts 155 karma points
    Aug 14, 2020 @ 13:05
    Tim Bennett
    0

    I just whooped for joy so loud my kids came running to see what was happening! That absolutely nailed it and for once I (mostly) understand why haha!

    I cannot thank you enough for your time and patience, and I really appreciate you trying to lead me to solving it myself rather than just giving me a block of code to thoughtlessly paste in.

  • Marc Goodson 2155 posts 14408 karma points MVP 9x c-trib
    Aug 15, 2020 @ 09:49
    Marc Goodson
    0

    Yey!

    Sorry I think I probably should have spotted that earlier!

    Anyway there are now two main ways for writing out values from properties in an Umbraco Template/View, one approach using 'Modelsbuilder' and one approach using 'IPublishedContent'.

    Modelsbuilder: https://our.umbraco.com/documentation/reference/templating/modelsbuilder/

    IPublishedContent: https://our.umbraco.com/Documentation/Reference/Querying/IPublishedContent/Properties/#custom-properties

    The Modelsbuilder approach 'generates' c# models to represent each Document Type structure you have in your Umbraco site, and in turn makes it easier to 'remember' what properties are called, if using the likes of VisualStudio to author your templates you get 'intellisense' to suggest the name of the property, which reduces typo errors in property alias names...

    It makes the writing out of property values simpler.

    But for this to work - Models need to be regenerated whenever changes to Document Types are made, and this can lead to 'one more thing to consider' when moving releases between different environments and you 'need to know' what type of Model you are using in a particular Views/Partial Views context, to add to the correct @Inherits UmbracoViewPage<MyCustomModel> statement at the top of the view.

    With IPublshedContent you have a generic content model, that doesn't have any custom properties generated for you, and you have to use

    Model.Value<string>("propertyAlias") when writing out properties, so it's easy to make a typo in 'propertyAlias' but that might be an easier problem to debug than your Modelsbuilder models not being generated correctly for 'some reason'. So you have to remember the names of the alias, and it's more to type, but in many ways the IPublishedContent approach is 'less complex' - you can just have @Inherits UmbracoViewPage at the top of every template and partial view, and it will all 'just work' - and no models to regenerate between environments.

    There is no real difference in performance, the Modelsbuilder generated model properties are just wrappers around Model.Value... which means the approach you prefer to take, probably depends more on what makes sense to you... I type fast and remember things so I prefer IPublishedContent - but there are real benefits to using Modelsbuilder too - a lot depends on the complexity of the site you are building and how much custom extension you need to make to properties being written out in a template. You'll have a stronger opinion once you've built a couple of sites!

    Anyway in short... glad you got it working!

    regards

    Marc

  • Tim Bennett 23 posts 155 karma points
    Aug 15, 2020 @ 09:59
    Tim Bennett
    0

    That's actually a very clear explanation and a better contextual example than any I've read or watched on YouTube. For my own personal approach to coding IPublishedContent seems better suited, but in this instance I'm just gonna leave it well alone until I've got a better grasp of MVC!

Please Sign in or register to post replies

Write your reply to:

Draft