Umbraco foreach children of a child page - c#

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

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.

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>
}
}

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.

I had the exact scenario, this is how I got mine working. NodeByID was very useful nad -1 indicates the root
#foreach(var item in Model.NodeById(-1).Children)
{
string itemName = item.Name;
switch(itemName)
{
case "News":
#* News *#
<div id="News">
<h3>#item.Name</h3>
#foreach (var newsPost in item.Children.OrderBy("UpdateDate desc").Take(4).Items)
{
<p>
#newsPost.Title
</p>
}
</div>
}
}

Related

Get data to MVC 4 View from SQL Table with using Split() method

My question would be complicated but I will try to ask clearly.
I want to keep tags in a data at SQL, as using the comma in a cell. Then, try to call two different way on my MVC 4 project. One way (basic one) is working. But another one is hard to run. I will give my codes one by one.
SQL Table:
Controller:
public ActionResult Portfolio()
{
return View(db.Portfolios.ToList());
}
View:
#model IEnumerable<emirhanozkan.Models.Portfolio>
#{
foreach (var pot in Model)
{
<p>#pot.Tags.Split(',')[0]</p>
<p>#pot.Tags.Split(',')[1]</p>
<p>#pot.Tags.Split(',')[2]</p>
}
}
In same View one more foraech is running:
#foreach (var po in Model)
{
<li class="item #po.Tags.ToLower().Trim().Replace(",","")">
<img src="#po.Image" />
#po.Title
</li>
}
So, What I want to do with Split method:
<p>AngularJS</p>
<p>MVC</p>
<p>C#</p>
<p>Wordpress</p>
<p>MVC</p>
I guess my #pot.Tags.Split(',')[0], #pot.Tags.Split(',')[1] and #pot.Tags.Split(',')[2] code is wrong to list them but my brain not working anymore than that one. Please help me get them like my dream. Also, if you now to get just one from repeat words like <p>MVC</p> <p>MVC</p>, to just <p>MVC</p> please add to new code.
You can just loop on the array returned by Split() method and then render the tags:
foreach (var pot in Model)
{
var tags = #pot.Tags.Split(',');
foreach(var tag in tags)
{
<p>#tag</p>
}
}
sorry for errors, I write without compile:
List<Portfolio> Model = new List<Portfolio>();
StringBuilder finaltags= new StringBuilder();
foreach (var pot in Model)
{
finaltags.AppendLine("<p>" + #pot.Tags.Split(',') + "</p>");
}
#Html.Raw(finaltags.ToString());
foreach (var pot in Model)
{
var tags = #pot.Tags.Split(new []{','}, StringSplitOptions.RemoveEmptyEntries);
foreach(var tag in tags)
{
<p>#tag</p>
}
}
foreach (var pot in Model)
{
<li>
<img src="#po.Image" />
<a href="#po.Url" target="_blank" class="md-button md-primary">
#po.Title</a>
</li>
}
Thank you for your suggestions. But I found the answer to my question:
#{
foreach (var pot in Model)
{
string str = pot.Tags;
string[] strT = str.Split(',');
foreach (var poo in strT) {
<p>#poo</p>
}
}
}

Creating a CSV string in Razor foreach

I am trying to parse multiple page IDs into a cookie in Umbraco Razor.
I have this piece of code
#{
var siteroot = Model.AncestorOrSelf(1);
HttpCookie eventCookie = new HttpCookie("eventCookie");
}
#foreach (var child in siteroot.Descendants("Event").OrderBy("Date"))
{
if (DateTime.Today <= child.Date)
{
#RenderPage("~/macroscripts/RenderEventBox.cshtml", child, false)
}
}
#{
Response.Cookies.Add(eventCookie);
}
What I want to do is to create a CSV string in the foreach, with page IDs.
The page IDs should then be inserted in a cookie in which I can check for new IDs since the last time the user visited - for a "This is the new pages since your last visit" functionality.
But I am not sure how to do this.
The outcome that I want should look like
2525,4587,4789,4790,5858,5782,7899
which I then can put into a cookie.
Got it solved quite simple with
#{
var csv = "";
}
#foreach (var child in siteroot.Descendants("Event").OrderBy("Date"))
{
csv += "," + #child.Id;
}

Sort child nodes by date - Razor Umbraco

For the following examples, I'm using a content tree which looks like this:
Content tree
#inherits Umbraco.Web.Mvc.UmbracoTemplatePage
#{
var home = Model.Content.Descendants().Where(x => x.DocumentTypeAlias == "BlogContainer");
<div class="container">
<ul>
#foreach (var item in home)
{
foreach (var items in item.Children)
{
foreach (var baby in items.Children.OrderBy("date desc"))
{
var date = baby.GetPropertyValue<DateTime>("date");
<li>#items.Name - #baby.Name - #date</li>
}
}
}
</ul>
</div>
}
And the result is Result three I need to collect all items and set order by date
Try and do something like
var allItems = homePage.Descendants("YourItemNodeType")
.Where(item => item.HasValue("date")
&& item.GetPropertyValue<DateTime>
("date") != DateTime.MinValue)
.ToList()
.OrderByDescending(item => item.GetPropertyValue<DateTime>("date"));
This should get you all your items in both category 1 and category 2, i always tend to check if my date is actually set ( you wouldnt need to do that for create date mentioned by #bowserm as that is always there with a value).
Once u got them to List then you can sort them by their set date, i do this on when i list news articles in different parent pages, then you can just have one loop to go through all of them.
First of all, what Umbraco version are you using? It looks like you are using 6+? Is that right? My answer below should work for 6 and 7.
The property you are looking for is called createDate, so you would use something like baby.GetPropertyValue<DateTime>("createDate"). Even better, you should be able to just type baby.CreateDate. Umbraco has exposed all of the default properties that you might want on the IPublishedContent as properties, so you can get at those without having to use GetPropretyValue(...).
Take a look at this Umbraco v6 MVC Razor Cheatsheet. It lists the default properties you can get off of the nodes in Umbraco. The razor syntax for v6 will also be applicable to v7, so this cheat sheet works for both.

Checking Umbraco node length

I have a panel that is created and filled via a vacancy page I have created. Im doing it as follows:
#{
var root = CurrentPage.AncestorOrSelf(1);
var newsNode = root.Descendants("News").First();
var vacanciesNode = root.Descendants("Vacancies").First();
string shortenedSummary = string.Empty;
}
<ul>
#foreach (var vacancyItem in vacanciesNode.Descendants("Vacancy").Take(3).OrderBy("postDate desc"))
{
<p>here we are 2</p>
#vacanciesNode.Count().ToString()
<li>
<h4>#vacancyItem.jobTitle</h4> <span>Posted on #vacancyItem.postDate.ToString("dd/MM/yyyy")</span>
<p>
#if (vacancyItem.jobSummary.Length <= 182)
{
#vacancyItem.jobSummary
}
else
{
shortenedSummary = vacancyItem.jobSummary.Substring(0, 182) + "...";
#shortenedSummary
}
</p>
Read More..
</li>
}
</ul>
However, when there are no vacancy items, my list is empty. Should this be the case, I'm wanting it to read "sorry no vacancies just now" but I don't know how to check if my vacanciesNode has any items in it.
Could someone show me how I could achieve this?
Since the .Descendants() method returns a DynamicContentList (a collection) you can simply do a .Count() on the collection and check whether it's more than or equal to 1.
If there's more than 0 items in the collection, it's not empty.
So, what you need to do is surround your #foreach with an #if statement which checks on this, and an else statement after that prints whatever html you want to show if there's no vacancies
#if( vacanciesNode.Descendants("Vacancy").Take(3).OrderBy("postDate desc").Count() > 0) {
//Do foreach
}
else
{
//Write message about missing vacancies
}

Why does Response.Write() only write the first element in list?

I am trying to write some syndication onto my page,
I use the .Net class to get the rss content into a list
<div>
<%
var r = System.Xml.XmlReader.Create("http://www.huffingtonpost.com/feeds/verticals/small-business/index.xml");
System.ServiceModel.Syndication.SyndicationFeed albums = System.ServiceModel.Syndication.SyndicationFeed.Load(r);
r.Close();
foreach (System.ServiceModel.Syndication.SyndicationItem album in albums.Items)
{
Response.Write(album.Title.Text);
}
%>
</div>
Well the foreach is only functioning as a forfirst here, because it only writes the first SyndicationItem in the list. As you can see, there are many items in that list. Where can be my mistake?
Just to make sure there is not only 1 item in my album list, I did a count on it.
<div>
<%
var r = System.Xml.XmlReader.Create("http://www.huffingtonpost.com/feeds/verticals/small-business/index.xml");
System.ServiceModel.Syndication.SyndicationFeed albums = System.ServiceModel.Syndication.SyndicationFeed.Load(r);
r.Close();
int i = albums.Items.ToList().Count;
Response.Write(i);
/* foreach (System.ServiceModel.Syndication.SyndicationItem album in albums.Items)
{
Response.Write(album.Title.Text);
} */
%>
</div>
Result:
I am wondering if the title output your seeing is "small business on huffingtonpost.com". If it is, then it is working correctly. You have one item in the list with many entries. Do another iteration inside your current iteration and you should be good to go.
Update
I just pasted your code in a forms page and it came through with all 15 results.

Categories