Copied to clipboard

Flag this post as spam?

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


  • Graeme W 113 posts 289 karma points
    Jun 30, 2014 @ 15:24
    Graeme W
    0

    Razor query to retrieve pages by document type and property value

    I need to get a list of documents for a specified document type and property. In this case the document type is “NewsArticle” and the property is “articleCategory”

    I can get a query to work by hard-coding the category as in the following example

    var nodes = root.Descendants("NewsArticle").Where("ArticleCategory.Contains(\"Technology\")").OrderBy("ArticleDate desc").Take(10);
    

    What I need to do is swap the hard coded “Technology” value with a string variable However whatever I try I can’t get it to return any results if I use the variable. This is one example of about a dozen attempts I’ve tried (I’ve also tried ‘equals’, ‘==’ amongst other variations)

    var nodes = root.Descendants("NewsArticle").Where("ArticleCategory.Contains(@articleCategory)").OrderBy("ArticleDate desc").Take(10);
    

    I’ve got a feeling this should be simple - Can anyone help? Thanks

  • Mike Chambers 635 posts 1252 karma points c-trib
    Jun 30, 2014 @ 15:33
    Mike Chambers
    1

    Think you should be able to use this construct

    var nodes = root.Descendants("NewsArticle").Where("ArticleCategory.Contains(@0)", @articleCategory).OrderBy("ArticleDate desc").Take(10);

    ps:  http://our.umbraco.org/documentation/Reference/Querying/DynamicNode/Collections

  • Graeme W 113 posts 289 karma points
    Jun 30, 2014 @ 16:02
    Graeme W
    0

    Hi Mike - Thanks for the suggestion - however I now get the compiler error:

    'System.Collections.Generic.IEnumerable

  • Jeavon Leopold 3072 posts 13628 karma points MVP 10x admin c-trib
    Jul 01, 2014 @ 21:12
    Jeavon Leopold
    0

    I think your issue is only the @ before the variable name. Try this:

    var nodes = root.Descendants("NewsArticle").Where("ArticleCategory.Contains(@0)", articleCategory).OrderBy("ArticleDate desc").Take(10);
    
  • Graeme W 113 posts 289 karma points
    Jul 02, 2014 @ 12:22
    Graeme W
    0

    Thanks Jason. If I use that code I get the following error:

    System.Collections.Generic.IEnumerable

    If it's relevant I'm running the code in a partial view that inherits from Umbraco.Web.Mvc.UmbracoTemplatePage. I've tried adding a using system.linq statement

  • Jeavon Leopold 3072 posts 13628 karma points MVP 10x admin c-trib
    Jul 02, 2014 @ 12:23
    Jeavon Leopold
    0

    Could you please post your entire cshtml file?

  • Graeme W 113 posts 289 karma points
    Jul 02, 2014 @ 12:42
    Graeme W
    0

    Hi Jeavon. Code pasted below, thanks...

      @inherits Umbraco.Web.Mvc.UmbracoTemplatePage
    
    @using System.Linq 
    
    @{
    
        var root = Model.Content.AncestorOrSelf();  
    
        // value from the containing view's model...
        string articleCategory = Model.Content.GetPropertyValue("articleCategory").ToString(); //get the value we want to use in Where clause below
    
        int docID = Model.Content.Id;
    
        // following hardcoded line works for getting technology articles
       // var nodes = root.Descendants("NewsArticle").Where("articleCategory.Contains(\"Technology\")").OrderBy("ArticleDate desc").Take(10);  
    
       // need the following line to use the articleCategory variable as criteria in Where clause...
      var nodes = root.Descendants("NewsArticle").Where("articleCategory.Contains(@0)", articleCategory).OrderBy("ArticleDate desc").Take(10);
    
        }
    
        <strong>
        @articleCategory
    
        </strong>
    
    <table class="table table-striped table-condensed table-bordered">
    
        <tbody>   
    
    
          @foreach (var node in nodes)
          {
              if (node.Id != docID)  // don't want to display current doc in list of its related articles
              {
    
            <tr>
                <td>
                    <span class="label label-success">
    
                   @if (node.GetProperty("articleDate").HasValue())
                   {
                   @Convert.ToDateTime(node.GetPropertyValue("articleDate")).ToString("dd-MM-yy")
                   }
                   else
                   {                                     
                       @node.CreateDate.ToString("dd-MM-yy")
    
                   }             
    
                </span>&nbsp;
    
                <a href="@node.Url">@node.Name</a>
                <p>
                @node.GetPropertyValue("leadText")
                </p>
                </td>
    
            </tr>
               }
          }
    
    
    
        </tbody>
    
    </table>
    
  • Jeavon Leopold 3072 posts 13628 karma points MVP 10x admin c-trib
    Jul 02, 2014 @ 12:47
    Jeavon Leopold
    102

    Ah ok, you are using the strongly typed model (Model.Content) but this method is for the dynamic Model (CurrentPage). So here is the complete script using strongly typed (I've also made a few other suggestions)

    @inherits UmbracoTemplatePage
    @{
    
        var root = Model.Content.AncestorOrSelf();
    
        // value from the containing view's model...
        string articleCategory = Model.Content.GetPropertyValue("articleCategory").ToString(); //get the value we want to use in Where clause below
    
        int docId = Model.Content.Id;
    
        // following hardcoded line works for getting technology articles
        // var nodes = root.Descendants("NewsArticle").Where("articleCategory.Contains(\"Technology\")").OrderBy("ArticleDate desc").Take(10);
    
        // need the following line to use the articleCategory variable as criteria in Where clause...
        var nodes = root.Descendants("NewsArticle").Where(x => x.GetPropertyValue<string>("articleCategory") == articleCategory).OrderBy("ArticleDate desc").Take(10);
    
    }
    
    <strong>
        @articleCategory
    
    </strong>
    
    <table class="table table-striped table-condensed table-bordered">
    
        <tbody>
    
    
            @foreach (var node in nodes)
            {
                if (node.Id != docId)  // don't want to display current doc in list of its related articles
                {
    
                    <tr>
                        <td>
                            <span class="label label-success">
    
                                @if (node.HasValue("articleDate"))
                                {
                                    @(node.GetPropertyValue<DateTime>("articleDate").ToString("dd-MM-yy"))
                                }
                                else
                                {
                                    @node.CreateDate.ToString("dd-MM-yy")
    
                                }
    
                            </span>
    
                            <a href="@node.Url">@node.Name</a>
                            <p>
                                @node.GetPropertyValue("leadText")
                            </p>
                        </td>
    
                    </tr>
                }
            }
    
    
    
        </tbody>
    
    </table>
    
  • Graeme W 113 posts 289 karma points
    Jul 02, 2014 @ 13:34
    Graeme W
    0

    Brilliant - that's done the trick. Thanks for your help!

  • Jeavon Leopold 3072 posts 13628 karma points MVP 10x admin c-trib
    Jul 02, 2014 @ 13:41
    Jeavon Leopold
    0

    No worries, I hope it makes sense?

  • Arulkumar Subramaniam 12 posts 62 karma points
    Jul 21, 2014 @ 16:24
    Arulkumar Subramaniam
    0

    Hi Jeavon

    But this query doesnt work if multiple values are sent 

    for ex : 

    var searcheventtype = "Branding, Technology";

    var eventsItems = Model.Descendants("EventsItem").Where("evDateStart  >= DateTime.Now && evType.Contains(@0)&& Visible",searcheventtype ).OrderBy("evDateStart desc"); 

    The above query returns only the events which has both . but ideally , all events with either of those eventTypes should be returned

  • Jeavon Leopold 3072 posts 13628 karma points MVP 10x admin c-trib
    Jul 21, 2014 @ 16:53
    Jeavon Leopold
    0

    Hi Arulkumar,

    I looks like you are using DynamicNode with a legacy Razor Macro rather than MVC templating that this snippet was created for?

    However, in DynamicNode there was a method called ContainsAny that might suit your need.

    e.g.

    @{    
        var searcheventtype = "Branding,Technology".Split(',').ToList();
        var eventsItems = Model.Descendants("EventsItem").Where("evDateStart  >= DateTime.Now && evType.ContainsAny(@0)&& Visible", searcheventtype).OrderBy("evDateStart desc"); 
    }
    

    Jeavon

  • Arulkumar Subramaniam 12 posts 62 karma points
    Jul 21, 2014 @ 17:45
    Arulkumar Subramaniam
    0

    Thanks Jeavon

  • dan 54 posts 133 karma points
    Mar 10, 2017 @ 18:22
    dan
    0

    Hey guys,

    I'm looking to take this to the next level where instead of targeting a specific document type, I'm looking for any document type that has a specific property value.

    My differences here are:

    1. I haven't been able to get the above code work
    2. Document type needs to be any type; look for any page that has a specific property
    3. The property I'm looking for is a boolean; featured

    So for starters I have this

    Umbraco.ContentAtXPath("//newsItem").Where("featured");
    
Please Sign in or register to post replies

Write your reply to:

Draft