Copied to clipboard

Flag this post as spam?

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


  • Dan 1288 posts 3942 karma points c-trib
    Dec 11, 2013 @ 16:18
    Dan
    0

    Best way to filter node-set within razor query

    Hi,

    I have a node containing FAQ nodes. The FAQs are rendered simply on a page with a partial view, and may be filtered by a category id (or several) passed in via a querystring.

    The code I have works nicely, like this:

    // Create array of category id(s) from querystring values
    string categoryId = Request.QueryString["category"];
    categoryId = categoryId.IsNullOrWhiteSpace() ? "" : categoryId;
    string[] categoryIds = categoryId.Split(',');
    
    // Get faq nodes
    var faqs = @Model.Children.Where("Visible").OrderBy("date");
    
    // Loop through nodes
    foreach (var faq in faqs)
    {
        // Get category(/ies) current node belongs to
        var category = faq.GetPropertyValue("category").ToString();
        string[] categories = category.Split(',');
    
        // If there's a category filter from querystring, select only nodes in those categories
        if (String.IsNullOrEmpty(categoryId) || categories.Any(categoryIds.Contains)){
    
            // Output mark-up here
            <p>@faq.Name</p>
    
        }
    }
    

    Now though, I want to paginate this. So I really would like to combine the following two lines into a single query if possible:

    var faqs = @Model.Children.Where("Visible").OrderBy("date");
    

    and

    if (String.IsNullOrEmpty(categoryId) || categories.Any(categoryIds.Contains))
    

    Otherwise it'll mean doing two loops of the node-set, each with a check for categories; one to count the number of records for pagination and another to output the mark-up later on the page.

    So essentially the 'if' logic becomes part of the 'where' part of the node selector.

    The other alternative is to do one loop and create a temporary variable of nodes and count and loop that, which feels better than two separate loops, but not as ideal as being able to just have a single selector that takes the category filter into account.

    Is it possible to do such a selector as part of the node-set gathering? Any pointers much appreciated.

    Thanks folks!

  • Jeroen Breuer 4909 posts 12266 karma points MVP 5x admin c-trib
    Dec 12, 2013 @ 12:28
    Jeroen Breuer
    100

    It might be easier to use IPublishedContent for this which support strongly typed queries. Some more info here: http://our.umbraco.org/forum/developers/api-questions/46706-Razor-How-to-check-if-content-is-in-the-recycle-bin?p=0#comment167514

    Jeroen

  • Dan 1288 posts 3942 karma points c-trib
    Dec 12, 2013 @ 17:45
    Dan
    1

    Thanks Jeroen.

    I've not been able to combine this into a single statement unfortunately - it just won't seem to accept the 'or' (||) part of the expression. The closest I've got is this:

    if (String.IsNullOrEmpty(categoryId))
    {
        faqs = Umbraco.TypedContent(Model.Id).Children.Where(x => x.IsVisible()).OrderBy(sort);
    }else{
        faqs = Umbraco.TypedContent(Model.Id).Children.Where(x => x.IsVisible() && x.GetPropertyValue<string>("category", "").Split(',').Any(categoryIds.Contains)).OrderBy(sort);
    }
    

    However, I'm struggling to declare the correct type on the 'faqs' variable. I can't do var faqs; as "implicitly typed local variables must be initialized" and it errors if I do IPublishedContent faqs; saying "Cannot implicitly convert system.linq.iqueryable

    Any ideas on this?

    Thanks.

  • Dan 1288 posts 3942 karma points c-trib
    Dec 12, 2013 @ 17:48
    Dan
    0

    Actually, just got the last part - IEnumerable<IPublishedContent> faqs; sets the correct type.

  • Jeroen Breuer 4909 posts 12266 karma points MVP 5x admin c-trib
    Dec 12, 2013 @ 17:48
    Jeroen Breuer
    1

    Your linq query will return an IEnumerable so try this:

    IEnumerable<IPublishedContent> faqs;

    That will return multiple IPublishedContent items you can loop through.

    Jeroen

  • Jeroen Breuer 4909 posts 12266 karma points MVP 5x admin c-trib
    Dec 12, 2013 @ 17:49
    Jeroen Breuer
    0

    Wow I think you were a few seconds faster :-)

  • This forum is in read-only mode while we transition to the new forum.

    You can continue this topic on the new forum by tapping the "Continue discussion" link below.

Please Sign in or register to post replies