Iterate Library.NodeById within UmbracoApiController
I have written a WebApi controller to render out some content as JSON. The purpose of the code is, I have a number of new items on a page, and, I wish to exclude the "featured articles" from that list, before returning the list of items as json.
I have rewritten an existing .cshtml file which gets calls Library.NodeById to access the featuredArticles property on the page (and later checks against the list of articles to see if the Id exists and if so, excludes the article). The underlying data type of featuredArticles is a Multi-Node tree picker. The original .cshtml code, which works fine, is here:
if (Model.AncestorOrSelf().HasValue("featuredArticles"))
{
foreach (var item in Model.AncestorOrSelf().featuredArticles)
{
var node = Library.NodeById(item.InnerText);
if (node.Id != 0)
{
newNodeList.Add(node);
featuredArticlesCount = featuredArticlesCount + 1;
}
}
}
Unfortunately, I am unable to call Library.NodeById from within an UmbracoApiController, so my current working equivalent is parse the RawXmlElement myself, as follows
In the webApi you can use Umbraco Services.
Of course you don't need to parse XML.
Please, can you describe more clear how your structure has been organized ?
Thanks for your reply Alex. I have read through the link that you sent but am unsure which method to use - my issue seems to be parsing content which is added using the "Multi-Node Tree Picker". I have now supplied the full method within my UmbracoApiController (with comments regarding the structure/document type/data type).
The bit which is clearly wrong is getting the reference to the featuredArticles on the page
I would rather do something like this.... but I'm unsure of the code to write for data type property editor "Multi-Node Tree Picker"
var articles = page.AncestorOrSelf().Descendants("NewsArticle").Where("articlePhotoImage != \"\"").OrderBy("UpdateDate desc");
Anyway, here is the code
public IEnumerable<NewsItem> GetNews(int pageNumber, int pageSize, string iaith)
{
int currentPageId;
if (iaith == "en-GB")
{
currentPageId = 1051;
}
else
{
currentPageId = 1052;
}
// Get a reference to the page
var page = Umbraco.Content(currentPageId);
// The document type of the page is "Homepage".
// The "Homepage" document type contains a property named "featuredArticles".
// When looking at the field information of "featuredArticles", the type shows as "News Article Picker"
// The Data Type "News Article Picker" uses Property Editor "Multi-Node Tree Picker", adn the Property editor GUID is 7e062c13-7c41-4ad9-b389-41d88aeef87c
// The Data Type "News Article Picker" has the following properties:
// Select tree type : Content
// XPath type : Global
// XPath expression : $ancestorOrSelf//NewsArchiveLandingPage
// XPath filter type : enable
// XPath filter : /*[self::NewsArticle]
// Maximum node selections : 3
// Minimum node selections : 3
// Data as CSV or XML : XML
// get a reference to RawXmlElement
string myFeaturedArticles = page.featuredArticles.RawXmlElement.ToString();
// clean it up a bit
myFeaturedArticles = myFeaturedArticles.Replace("<MultiNodePicker type=\"content\">", "");
myFeaturedArticles = myFeaturedArticles.Replace("</MultiNodePicker>", "");
myFeaturedArticles = myFeaturedArticles.Replace("\r\n", "");
myFeaturedArticles = myFeaturedArticles.Replace(" ", "");
// create a string list featuredArts to hold a list of the articles which we will later remove from the articles list
List<string> featuredArts = new List<string>();
// loop through the list, building up featuredArts
while (myFeaturedArticles.Length > 0)
{
string x = myFeaturedArticles.Substring(8, 4);// closingindex - 8);
featuredArts.Add(x);
myFeaturedArticles = myFeaturedArticles.Substring(21, myFeaturedArticles.Length - 21);
}
// get a reference to all of the Descendants of the page of type "NewsArticle" matching the where clause
var articles = page.AncestorOrSelf().Descendants("NewsArticle").Where("articlePhotoImage != \"\"").OrderBy("UpdateDate desc");
// count them....
int count = 0;
foreach (var item in articles)
{
count++;
}
// loop backwards, removing any articles which exist in the featuredArts list.
for (int i = count - 1; i >= 0; i--)
{
var article = articles[i];
if (featuredArts.Contains(article.Id.ToString()))
{
articles.Remove(article);
}
}
List<NewsItem> ls = new List<NewsItem>();
// now loop through the remaining articles, builing up a list of NewsItem.
// get the appropriate number of items based on pageNumber and pageSize
foreach (var item in articles.Skip((pageNumber - 1) * pageSize).Take(pageSize))
{
NewsItem news = new NewsItem();
string trimmedContent = "ERROR LOADING CONTENT";
try
{
trimmedContent = Regex.Match(Regex.Replace(Regex.Replace(item.articleContent.ToString(), @"<[^>]*>", ""), @"\r\n?|\n", String.Empty), @"^.{1,120}\b(?<!\s)").Value + " ...";
}
catch
{
trimmedContent = "ERROR LOADING CONTENT";
}
news.Id = item.Id.ToString();
news.Url = item.Url;
news.Title = item.articleHeadline.ToString();
news.Excerpt = trimmedContent;// item.articleContent.ToString();
news.Image = item.articlePhotoImage.ToString();
news.UpdateDate = item.UpdateDate.ToString();
news.UpdateDateUTC = item.UpdateDate;
ls.Add(news);
}
return ls;
}
Iterate Library.NodeById within UmbracoApiController
I have written a WebApi controller to render out some content as JSON. The purpose of the code is, I have a number of new items on a page, and, I wish to exclude the "featured articles" from that list, before returning the list of items as json.
I have rewritten an existing .cshtml file which gets calls Library.NodeById to access the featuredArticles property on the page (and later checks against the list of articles to see if the Id exists and if so, excludes the article). The underlying data type of featuredArticles is a Multi-Node tree picker. The original .cshtml code, which works fine, is here:
@inherits umbraco.MacroEngines.DynamicNodeContext @using System.Text.RegularExpressions; @using umbraco.MacroEngines @inherits DynamicNodeContext
@{
var newNodeList = new List
if (Model.AncestorOrSelf().HasValue("featuredArticles")) {
}
Unfortunately, I am unable to call Library.NodeById from within an UmbracoApiController, so my current working equivalent is parse the RawXmlElement myself, as follows
I assume there must be a much cleaner way of doing this, so can anyone let me know the correct way of building my list of featuredarts?
Hi Ben,
In the webApi you can use Umbraco Services. Of course you don't need to parse XML. Please, can you describe more clear how your structure has been organized ?
Read about services: https://our.umbraco.org/documentation/reference/management/services/contentservice
Thanks
Thanks for your reply Alex. I have read through the link that you sent but am unsure which method to use - my issue seems to be parsing content which is added using the "Multi-Node Tree Picker". I have now supplied the full method within my UmbracoApiController (with comments regarding the structure/document type/data type).
The bit which is clearly wrong is getting the reference to the featuredArticles on the page
string myFeaturedArticles = page.featuredArticles.RawXmlElement.ToString();
I would rather do something like this.... but I'm unsure of the code to write for data type property editor "Multi-Node Tree Picker"
var articles = page.AncestorOrSelf().Descendants("NewsArticle").Where("articlePhotoImage != \"\"").OrderBy("UpdateDate desc");
Anyway, here is the code
is working on a reply...