Umbraco foreach children of a child page

15,415

Solution 1

I ended up getting the news page by its id and then getting it's children from there. The below code worked for me. Thanks guys.

@{
    var node = Umbraco.Content(1094);    
    <p>@node.Id</p> // output is 1094  
    foreach (var item in node.Children.Where("Visible").Take(3))

    {

         <p>@item.exampleText</p>

    }
    }

Solution 2

When you're walking the tree you have to remember that a property (or method) like Children or Descendants() will return a collection of objects, so you can't just call Children of a collection. You can only call Children on a single object.

You can find the correct child of the homepage by using something like var newsPage = CurrentPage.Children.Where(x => x.DocumentTypeAlias == "NewsListingPage") and then extract the children of that page.

Solution 3

You need to reference the required node by NodeTypeAlias of it's Document Type.

So assuming the alias of the DocType of your News Posts is “NewsPosts” then...

@foreach (var homenews in @Model.Descendants().Where("NodeTypeAlias == \"NewsPosts\"")).Take(3)
{       
    <p>@homenews.Name<p>
}   

...should return the name of the first 3 news posts.

Share:
15,415
Phil
Author by

Phil

Just some guy.

Updated on June 16, 2022

Comments

  • Phil
    Phil almost 2 years

    I have news posts within a news page within a homepage on my content structure

    Example:

    Homepage
    - News
    -- News Posts

    I'm looking to have some of the news feed on my homepage in a foreach statement. In my head it should be as simple as:

    @foreach (var homenews in CurrentPage.Children.Children)
    {
         if (homenews.Name == "News Post")
         {
             //Do some stuff//
         }
    }
    

    Obviously that doesn't work so has anybody got any ideas? Thanks

  • Phil
    Phil almost 10 years
    The logic of this makes perfect sense but I am struggling get my code to work. @{ var newsPage = CurrentPage.Children.Where(x => x.DocumentTypeAlias == "News"); foreach (var homepost in newsPage.Children) { }}
  • Digbyswift
    Digbyswift almost 10 years
    Is it outputting anything at all? The code looks ok. You probably need to step through it with the debugger.
  • Digbyswift
    Digbyswift almost 10 years
    I also tend to add in null checks on the node collections .WhereNotNull() or .Where(x => x != null). Also make sure that you have all the relevant references in your view. You could also try the .Children() method extension instead of the property call.
  • Digbyswift
    Digbyswift almost 10 years
    This won't work because you are assuming that the News page is a child of the root which it isn't. It's a child of the homepage (which is a child of the root). It's bad practice to have your top level nodes as immediate children of the root.
  • Phil
    Phil almost 10 years
    I get a server error: Cannot use a lambda expression as an argument to a dynamically dispatched operation without first casting it to a delegate or expression tree type
  • Digbyswift
    Digbyswift over 9 years
    IMO it's bad practice to reference by ID. What happens if the page is replaced? It's much better to walk the tree and find the page by doc type alias.
  • Phil
    Phil over 9 years
    The page I accessed by ID will never need to be changed for my project. So the above code is just what I want.
  • Digbyswift
    Digbyswift over 9 years
    Absolutely fine, as I said only an opinion. Pages being replaced is not the only reason it's a bad idea though. E.g. Someone picking up the code will have no idea what page 1094 is. Where as 'walking the tree' will give the developer a clear relationship between the code and the target node. Also, as a developer, never say never :)
  • csharpforevermore
    csharpforevermore about 9 years
    Just remember that this approach is not considered good practice. Putting logic in your view is always considered a bad option. Instead, do the logic in a surface controller and assign the results to a view model / poco property,
  • Kunal
    Kunal over 6 years
    I got Model.Content.Children.Where(x => x.DocumentTypeAlias == "NewsListingPage").Where("Visible") working
  • Digbyswift
    Digbyswift over 6 years
    @Kunal Yes, that would work if you only had access to the RenderModel passed to the view. The CurrentPage member is a property of the RenderMvcController (and SurfaceController) class so is only accessible in the controller.