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 3921 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 4908 posts 12265 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 3921 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 3921 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 4908 posts 12265 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 4908 posts 12265 karma points MVP 5x admin c-trib
    Dec 12, 2013 @ 17:49
    Jeroen Breuer
    0

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

Please Sign in or register to post replies

Write your reply to:

Draft