Copied to clipboard

Flag this post as spam?

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


  • Ryan 24 posts 106 karma points
    Apr 21, 2016 @ 04:43
    Ryan
    0

    How to search for visible children?

    Hey guys, so I'm trying to create a custom controller in Umbraco 7.4 and I'm following the code on this page: https://our.umbraco.org/documentation/reference/templating/mvc/querying

    However, it's not working. It seems that RenderModel has no method named IsVisible. How can I check if IPublishedContent is currently visible so I should render it or not? Code is below, which is expected to work but shows a compile-time error:

    namespace NZ_Realty_Ltd.Controllers
    {
        public class ListingsController : Umbraco.Web.Mvc.RenderMvcController
        {
            public override ActionResult Index(RenderModel model)
            {
                var result = model.Content.Children.Where(x => x.IsVisible());
                return CurrentTemplate(result);
            }
        }
    }
    

    I guess ultimately what I want to do is this - get a list of children based on whether they are visible and have a requested property value. However I'm also getting an error saying I can't apply [] indexing to ICollection. Am I doing something horribly wrong? I included using statements too:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    using Umbraco.Web.Models;
    
    namespace NZ_Realty_Ltd.Controllers
    {
        public class ListingsController : Umbraco.Web.Mvc.RenderMvcController
        {
            public ActionResult Index(RenderModel model, string listingType)
            {
                var result = model.Content.Children.Where(x => x.IsVisible() && x.Properties["propertyType"].Value.ToString() == listingType);
                return CurrentTemplate(result);
            }
        }
    }
    

    Thanks for any help or guidance, Ryan

  • James Jackson-South 489 posts 1747 karma points c-trib
    Apr 21, 2016 @ 06:57
    James Jackson-South
    0

    Hi Ryan,

    To be honest I don't really know if IsVisible() actually does anything. As long as it is published, it is visible as far as I'm aware.

    To answer your second question, if you want to get the value of a property you need to use the following API call.

    IPublishedContent.GetPropertyValue<T>(string alias, bool recursive)
    

    This allows you to return the property value as an instance of the given type T as long as the is a PropertyValueConverter available to do the translation for you. (There's ones built in for most stuff).

    So in your code example you would use it like the following.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    using Umbraco.Web.Models;
    
    namespace NZ_Realty_Ltd.Controllers
    {
        public class ListingsController : Umbraco.Web.Mvc.RenderMvcController
        {
            public ActionResult Index(RenderModel model, string listingType)
            {
                var result = model.Content.Children.Where(x => x.IsVisible() && x.GetPropertyValue<string>("propertyType") == listingType);
                return CurrentTemplate(result);
            }
        }
    }
    

    I hope that clears things up a little.

    Cheers

    James

  • Kevin Jump 2343 posts 14890 karma points MVP 8x c-trib
    Apr 21, 2016 @ 07:10
    Kevin Jump
    0

    Hi

    IsVisible() checks content for the umbracoNaviHide property ( a true false)

    https://github.com/umbraco/Umbraco-CMS/blob/612412683527dad1cdc3dbd4df61969b4695d7b0/src/Umbraco.Web/PublishedContentExtensions.cs#L596

    if umbracoNaviHide is true, IsVisible is false

    edit: umbracoNaviHide isn't on any doctypes by default you have to add it. but once you do, IsVisible will start to work.

  • Ryan 24 posts 106 karma points
    Apr 21, 2016 @ 07:11
    Ryan
    0

    Ahh cool, thanks that helps a lot. It makes a lot of sense that it just returns visible (published) children by default. Let me try that now and get back to you.

    EDIT: it seems that GetPropertyValue doesn't exist. Do you think this would work?

    x.GetProperty("propertyType").Value.ToString()
    
  • Kevin Jump 2343 posts 14890 karma points MVP 8x c-trib
    Apr 21, 2016 @ 07:23
    Kevin Jump
    100

    hi

    i think if you add using Umbraco.Web then GetPropertyValue should be accessible.

    Kevin

  • Ryan 24 posts 106 karma points
    Apr 21, 2016 @ 07:30
    Ryan
    0

    Ahhhhhh, yes that made it show up, and also IsVisible() is now there!

    Okay so one more question about this. The parameter listingType I'm trying to receive from the default route is null (I extracted the query into a model):

    namespace NZ_Realty_Ltd.Controllers
    {
        public class ListingsController : Umbraco.Web.Mvc.RenderMvcController
        {
            public ActionResult Index(RenderModel model, string listingType)
            {
                var result = new ListingsModel(model, listingType);
                return CurrentTemplate(result);
            }
        }
    }
    

    What am I doing wrong that this string is null? I've tried everything from:

    http://localhost:52015/listings?propertyType=Residential

    To:

    http://localhost:52015/listings/Residential

    This later one would be the ideal route I would like to use, but I get a 404 error. But would I need to define a custom route for that? I thought custom routes weren't for this kind of situation, but for if you are using a non-umbraco controller?

  • Kevin Jump 2343 posts 14890 karma points MVP 8x c-trib
    Apr 21, 2016 @ 07:44
    Kevin Jump
    0

    Hi

    Yeah its a custom route thing - they are a little bit fiddly but you can then load templates up.

    The documentation is here https://our.umbraco.org/Documentation/Reference/Routing/custom-routes

    but this blog post is probably the best way to get your head around it. http://shazwazza.com/post/custom-mvc-routes-within-the-umbraco-pipeline/

    personally depending on the number of thing listing type can be i would be tempted to just create the nodes (eg. on for residential, one for commercial) and have away with the routing, just because it's simpler to see whats going on later - but if you have loads of listing types that too becomes a pain.

  • Ryan 24 posts 106 karma points
    Apr 21, 2016 @ 07:50
    Ryan
    0

    Thanks Kevin, it's great to have a second opinion as I'm working alone on this project. I'll probably end up doing something this so I still retain the MVC separation of concerns:

    namespace NZ_Realty_Ltd.Controllers
    {
        public class ResidentialListingController : Umbraco.Web.Mvc.RenderMvcController
        {
            public ActionResult Index(RenderModel model)
            {
                var result = new ListingsModel(model, "Residential");
                return CurrentTemplate(result);
            }
        }
    }
    

    But now I've got myself confused. Do I need all this stuff or should I just make different views and do my custom queries directly in the views? I may be too used to angularjs...

  • Ryan 24 posts 106 karma points
    Apr 21, 2016 @ 09:33
    Ryan
    0

    Okay since the auto routing is linked with either the document type or the template, I'm going to need to do custom routing either way. So I might as well do it how I originally planned but with custom routing. It's likely I will need to extend it soon anyway. Thanks everyone for you help!

Please Sign in or register to post replies

Write your reply to:

Draft