Copied to clipboard

Flag this post as spam?

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


  • Ben Grice 24 posts 176 karma points
    Jan 26, 2016 @ 17:12
    Ben Grice
    0

    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")) {

    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

    string myFeaturedArticles = page.featuredArticles.RawXmlElement.ToString();//.Descendants("NewsArticle");//.AncestorOrSelf().Descendants();// "featuredArticles");//.OrderBy("UpdateDate desc");
    
        myFeaturedArticles = myFeaturedArticles.Replace("<MultiNodePicker type=\"content\">", "");
        myFeaturedArticles = myFeaturedArticles.Replace("</MultiNodePicker>", "");
        myFeaturedArticles = myFeaturedArticles.Replace("\r\n", "");
        myFeaturedArticles = myFeaturedArticles.Replace(" ", "");
    
        List<string> featuredarts = new List<string>();
        //int closingindex;
    
        while (myFeaturedArticles.Length > 0)
        {
            //closingindex = myFeaturedArticles.IndexOf("</nodeId>");
            string x = myFeaturedArticles.Substring(8, 4);// closingindex - 8);
            featuredarts.Add(x);
    
            myFeaturedArticles = myFeaturedArticles.Substring(21, myFeaturedArticles.Length - 21);
    
        }
    

    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?

  • Alex Skrypnyk 6163 posts 24143 karma points MVP 8x admin c-trib
    Jan 26, 2016 @ 21:59
    Alex Skrypnyk
    0

    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

  • Ben Grice 24 posts 176 karma points
    Jan 28, 2016 @ 10:25
    Ben Grice
    0

    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

     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;
    
    }
    
Please Sign in or register to post replies

Write your reply to:

Draft