Copied to clipboard

Flag this post as spam?

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


  • Richard Thompson 100 posts 336 karma points
    Jun 16, 2017 @ 11:59
    Richard Thompson
    0

    Loading models builder models in surface controller

    Say in my site I have a document type called News and I've used Models Builder to create a news model. I'm using the AppData mode of Models Builder.

    I'd like to have a list of news items with a future date so I'd create a partial to display them and a surface controller to load the data.

    How would I load the data in my surface controller so that I have a list of news items that are of the strongly typed news model?

  • Tim Watts 90 posts 395 karma points
    Jun 16, 2017 @ 12:31
    Tim Watts
    0

    Hi Richard,

    The document type of News, is that a single item or does it contain a list of news items, for example within a container such as Nested Content?

    The ModelsBuilder models will be in the Umbraco.Web.PublishedContentModels namespace. It should be easy enough to reference the models from your container.

    Regards,

    Tim

  • Richard Thompson 100 posts 336 karma points
    Jun 16, 2017 @ 13:49
    Richard Thompson
    0

    Thanks for getting back to me Tim.

    The news model would be a single item. I'm thinking of circumstances like trying to load a couple of news items in a partial on the homepage.

    In short I'm looking for a way in a surface controller to load some items of content as a list of strongly typed models builder models.

  • Tim Watts 90 posts 395 karma points
    Jun 16, 2017 @ 14:47
    Tim Watts
    0

    Hi Richard,

    So the news items will exist somewhere else on your site such as beneath a News Items parent node, and the partial on the homepage will load the 5 most recent?

    There's an article here which might help. Look in particular for the section headed "Alternatives" as this talks specifically about Models Builder.

    If you need some code samples post again and I'll try to have a look over the weekend.

    Regards,

    Tim

  • Richard Thompson 100 posts 336 karma points
    Jun 19, 2017 @ 10:18
    Richard Thompson
    0

    Hi Tim,

    Thanks for the Assistance. I had a look at the article you linked to which led me to https://www.zpqrtbnk.net/posts/strongly-typed-models-4 and https://github.com/zpqrtbnk/Zbu.ModelsBuilder/wiki/IPublishedContentModelFactory.

    For reference my site structure is homepage > news area > news items.

    After setting up a PublishedContentModelFactoryResolver, on my hompage if I get the grandchildren then I get back an IEnumerable<IPublishedContent>. Each item in the list is then of the NewsItem model type.

    What I'd like to do at this point is to get an IEnumerable<NewsItem> rather than an IEnumerable<IPublishedContent>.

  • Richard Thompson 100 posts 336 karma points
    Jun 19, 2017 @ 11:43
    Richard Thompson
    0

    So to answer my own question, adding .Cast<NewsItem> gives an enumerable of NewsItems e.g.:

    IEnumerable<NewsItem> newsItems = CurrentPage.Children.FirstOrDefault().Children.Cast<NewsItem>();
    
  • Tim Watts 90 posts 395 karma points
    Jun 19, 2017 @ 13:04
    Tim Watts
    1

    Hi Richard,

    I sounds like you're getting there (or perhaps even totally sorted now).

    You could use AutoMapper to sort out your casting between data types.

    Take the following view model classes as an example:

        public class HomePageViewModel
        {
            public string SiteName { get; set; }
            public string Keywords { get; set; }
    
            public IEnumerable<NewsAreaViewModel> newsAreas { get; set; }        
        }
    
        public class NewsAreaViewModel
        {
            public string Title { get; set; }
    
            public IEnumerable<NewsItemViewModel> NewsItems { get; set; }
        }
    
        public class NewsItemViewModel
        {
            public string Headline { get; set; }
            public string Body { get; set; }
            public DateTime DatePublished { get; set; }
        }
    

    You can then define the object mappings somewhere in your startup code as follows:

    Mapper.CreateMap<HomePage, HomePageViewModel>()
        .ForMember(dest => dest.newsAreas, opt => opt.MapFrom(src => src.Children().Where(x => x.DocumentTypeAlias == "newsArea")));
    Mapper.CreateMap<NewsArea, NewsAreaViewModel>()
        .ForMember(dest => dest.NewsItems, opt => opt.MapFrom(src => src.Children().Where(x => x.DocumentTypeAlias == "newsItem")));
    Mapper.CreateMap<NewsItem, NewsItemViewModel>();
    

    And then in your controller, simply map from the HomePage to the HomePageViewModel:

    HomePage content = model.Content as HomePage;
    HomePageViewModel vm = Mapper.Map<HomePageViewModel>(content);
    
    return View(vm);
    

    All of this deals with strongly typed models throughout, either from ModelsBuilder, or the view models you define. As with most things, there are many different approaches available!

    Regards,

    Tim

  • Richard Thompson 100 posts 336 karma points
    Jun 21, 2017 @ 08:17
    Richard Thompson
    0

    Hi Tim,

    Yes I solved it as follows:

    var availableNewsItems = homePage.Descendants("newsItem").Where("Visible") as List<NewsItem>;
    

    I've previously used UmbracoMapper for this but I figured there had to way to do this completely in Models Builder.

    Thanks for the help I really appreciate it.

    Richard

Please Sign in or register to post replies

Write your reply to:

Draft