Copied to clipboard

Flag this post as spam?

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


  • karen 186 posts 461 karma points
    Oct 04, 2017 @ 19:27
    karen
    0

    Pass Model.Content to helper

    I want to create a helper function that will do some lookup to find the site level node of the currentpage (it can be any one of a # of doc types). I have to find the information on both the template and some views, so I want to put the code in 1 place as well as keep the result request context so the lookup only has to happen once. My plan was to pass the Model.Content object to the function, but I can't figure out how to declare it in the function. Basically from my template I want to call:

    IPublishedContent site = MyHelper.getSiteNode(Model.Content);
    

    And the function declaration (tried this and many other variations)

    public static IPublishedContent getSiteNode(IPublishedContent requestedPage) { ... }
    

    However, once in the function, I need to call AncestorOrSelf and Where

    var nodeList = requestedPage.AncestorOrSelf().Where(x => iSiteDocTypesList.Contains(x.DocumentTypeId));
    

    but won't compile in the helper class because I can't figure out the correct Type for requestedPage, either it doesn't like AncestorOrSelf or the Where.

    This works fine in the template:

    var nodeList = Model.Content.AncestorsOrSelf().Where(x => iSiteDocTypesList.Contains(x.DocumentTypeId));
    

    All help appreciated! Thanks!

  • Marc Goodson 2127 posts 14219 karma points MVP 8x c-trib
    Oct 04, 2017 @ 20:32
    Marc Goodson
    2

    Hi Karen

    I'd normally create an extension method on IPublishedContent for this kind of thing:

    using Umbraco.Web;
        namespace YourProject.Application
        {
            public static class PublishedContentExtensions
            {
                public static IPublishedContent GetSiteNode(this IPublishedContent content)
                {
                    //if site has a doctype of HomePage
                     return content.AncestorOrSelf("HomePage");
    
                    //if site is always at the first level
                    //return content.AncestorOrSelf(1);
    
                    // or if you have some kind of different possibilities for document types
                   // var siteDocTypes = new String[] { "homePage", "territoryPage" };
                   // return content.AncestorsOrSelf().Where(f => siteDocTypes.Contains(f.DocumentTypeAlias)).FirstOrDefault();
    
        }
        }
        }
    

    Then anywhere you want to use this, have an @using statement at the top of your template @using YourProject.Application

    and you will be able to get the site node via:

    var siteNode = Model.Content.GetSiteNode();

    If you want to stick with your Helper approach, then just check you have the using Umbraco.Web at the top of your class, as this is where AncestorOrDefault comes from (it will be included in all template files in the web.config)

    or the only other thought is your iSiteDocTypesList - is that declared in your helper class anywhere?

    Also in later versions of Umbraco, they have added a Site() helper already for you, so you can write

    var site = Model.Content.Site();

    it uses the AncestorOrSelf(1) approach;

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

    regards

    Marc

  • karen 186 posts 461 karma points
    Oct 04, 2017 @ 21:00
    karen
    0

    Hi Marc

    Thanks!

    I did have Umbraco.Web included, but the issue was then with .Where( ... ), (IPublishedContent does not contain a definition for Where...)

    BUT just realized I forgot the S, so was using AncestorOrSelf, when I should have been using AncestorsOrSelf .... So that was my error, and it is working now.

    But to answer your questions:

    I want to have a helper class, because there are a bunch of different things I have to 'find' in numerous views/partials, so would like to cache it in the HttpContext.Current and only have to find/look up each item once per request (and keep all those things in the same helper class together). iSiteDocTypesList was another list of things that had to be found.

    I can't really use the new .Site() because in this set up it might not always bet at AncestorOrSelf(1).

    Thank you for the extension method idea - that is good to know for future reference!

    Thanks! Karen

  • Marc Goodson 2127 posts 14219 karma points MVP 8x c-trib
    Oct 04, 2017 @ 21:03
    Marc Goodson
    0

    Ace, glad you got it working, the number of times I've missed the s!

Please Sign in or register to post replies

Write your reply to:

Draft