Copied to clipboard

Flag this post as spam?

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


  • Ault Nathanielsz 87 posts 407 karma points c-trib
    Jun 20, 2018 @ 09:50
    Ault Nathanielsz
    0

    Nav from Multinode Tree Picker... Ancestor or Self

    I have a working top nav partial - it is populated by a multinode-tree-picker datatype named "wtgcTopNav" from a "Global Content" node at root.

    NB: I am using two different doctypes: wtWebPage (for pages) and wtGlobalContent (for global content)

    Issue: As I cycle through items in wtgcTopNav, I would like to determine if the item is "ancestor or self" of the current page. However, as the partial inherits a different model, I am not sure how to test for this.

    Relevant code:

    In the starting code

    var globalSettings = Umbraco.TypedContentAtRoot().FirstOrDefault(x => x.ContentType.Alias.Equals("wtGlobalContent"));

    When I call the partial:

    @Html.Partial("header/wtHeaderTopNav", globalSettings)

    The partial inherits:

        @inherits Umbraco.Web.Mvc.UmbracoTemplatePage<ContentModels.WtGlobalContent>
    @using ContentModels = Umbraco.Web.PublishedContentModels;
    @{
        Layout = null;
    }
    

    I'm sure this has been solved elsewhere, but a half-hour of Google leaves me none the wiser... feel free to post a relevant link in reply.

  • Alex Brown 129 posts 620 karma points
    Jun 21, 2018 @ 09:51
    Alex Brown
    0

    Umbraco.Web.Mvc.UmbracoTemplatePage lets you use the Model.Content.AncestorOrSelf() method. This method has a couple of overloads which you could use to detect if the current page has the ancestor your referring to.

    There's also the Model.Content.IsAnchestor() method, which lets you pass in an IPublishedContent to determine if X is an ancestor.

  • Ault Nathanielsz 87 posts 407 karma points c-trib
    Jun 22, 2018 @ 10:32
    Ault Nathanielsz
    0

    Only problem is, I am outside the model... (I think)

    Before I enumerate my list, I use the following:

                        var headerBlocks = Model.Content.Site().GetPropertyValue<IEnumerable<IPublishedContent>>("WtgcTopNav");
                    foreach (var item in headerBlocks)
    

    I though that I might be able to somehow pass the current page id into the partial, and then test to see if it was a descendent of each item... but when I try:

    class="@item.IsDescendant(Umbraco.Content(1506), "true", "false"))"
    

    I get:

    'Umbraco.Core.Models.IPublishedContent' has no applicable method named 'IsDescendant' but appears to have an extension method by that name. Extension methods cannot be dynamically dispatched. Consider casting the dynamic arguments or calling the extension method without the extension method syntax.

    Any thoughts? (NB I wasn't sure whether IsAncestor or IsDescendant should be used, but in either case, I seem to be calling it wrongly.)

  • MM 29 posts 125 karma points
    Jun 22, 2018 @ 10:57
    MM
    101

    It looks like Umbraco.Content is returning a dynamic object, which is IsDecendent method doesn't like. You can use

    Umbraco.TypedContent(1506)

    instead which casts to an IPublishedContent

  • Nik 1593 posts 7151 karma points MVP 6x c-trib
    Jun 22, 2018 @ 11:29
    Nik
    1

    Hi Ault,

    Okay, so first thing.

    On your partial, I would change your inherits to be the following:

    @inherits Umbraco.Web.Mvc.UmbracoViewPage<ContentModels.WtGlobalContent>
    

    This means you can just do @Model.GetPropertyValue..... etc, instead of @Model.Content.GetPropertyValue.

    It's just a nicer way to work if I'm honest.

    Okay, that aside.

    I'm assuming you are calling this partial in your master layout file in order to render a navigation.

    So, what you should be able to do is use

    @Umbraco.AssignedContentItem
    

    This should give you the actual page you are rendering for I believe, although best to put a null check in place.

    Then you can try the following (assuming you are looping through your navigation and the current loop variable is called menuItem:

    var isChildOfMenuItem = Umbraco.AssignedContentItem != null ?
         menuItem.IsAnchestor(Umbraco.AssignedContentItem) ? false;
    

    Cheers,

    Nik


    Follow up comment

    It is best to avoid using @Umbraco.Content and @Umbraco.Media. These return dynamic objects and I believe will be removed in later version of Umbraco. It is best to used the methods that start with Typed, e.g. @Umbraco.TypedContent instead as these will return you strongly typed models of IPublishedContent.

  • Ault Nathanielsz 87 posts 407 karma points c-trib
    Jun 22, 2018 @ 14:50
    Ault Nathanielsz
    1

    Hi Nik,

    Thanks for the generous answer. The @inherits tip is a good one.

    My original code was sorted by Matthew's suggestion of .TypedContent, but I will have a go at implementing your suggestion as it seems far more elegant.

    Thanks again.

Please Sign in or register to post replies

Write your reply to:

Draft