Copied to clipboard

Flag this post as spam?

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


  • ds 191 posts 223 karma points
    Aug 10, 2010 @ 10:03
    ds
    0

    List nodes of child node

    Hi everyone,

    I am not good at the xslt at the moment and need your guidance.

    I have such structure.

    -News

    - WriterA

    - Article of WriterA

    - Article of WriterA

    - WriterB

    - Article of WriterB

    - Article of WriterB

    and so on...

     

    What I want to achieve is to show only last added article of writers in a list or div everytime I add a new one. The code snippet which I have added in the following finds all child nodes of nodeID 1139 which is the node id of News and brings only  1 item at a time with variable maxItems but this is not what I want to achieve of course...

    <xsl:for-each select="umbraco.library:GetXmlNodeById('1139')/node [string(data [@alias='umbracoNaviHide']) != '1']">
    
    <xsl:sort select="@createDate" order="ascending" />
    <xsl:if test="position() &lt;= $maxItems">
    
    <div class="writers">
        <img src="{./data [@alias = 'writerPicture']}" />
        <a href="{umbraco.library:NiceUrl(@id)}"><span><xsl:value-of select="data [@alias = 'wCaption']"/></span></a>
        <br/><xsl:value-of select="@nodeName"/>
    </div>
    
    </xsl:if>
    
    </xsl:for-each>
  • Thomas Höhler 1237 posts 1709 karma points MVP
    Aug 10, 2010 @ 11:19
    Thomas Höhler
    0

    As I understand you correct you want to get a list of articles with max items from each writer but all together sorted by date, right?

    In principle this is a perfect senario for LinqToUmbraco. Otherwise I would recommend to implement an XsltExtension like this one

    Snippet

    using System.Collections.Generic;
    using System.Linq;
    using System.Xml.Linq;
    using System.Xml.XPath;
    using umbraco.presentation.nodeFactory;

    namespace MyMasterNamespace
    {
        public class XsltExtensions
        {
            public static XPathNodeIterator GetLastNewsItems(int maxNumberOfItemsPerWriter)
            {
                var doc = new XDocument();
                var root = new XElement("NewsItems");
                doc.Add(root);

                var rootNode = new Node(1139);
                var selectedArticles = new List<Node>();

                foreach (Node writer in rootNode.Children)
                {
                    var articles = writer.Children.Cast<Node>().OrderByDescending(x=>x.CreateDate).ToList();
                    selectedArticles.AddRange(articles.Count > maxNumberOfItemsPerWriter
                                                  ? articles.Take(maxNumberOfItemsPerWriter)
                                                  : articles);
                }

                foreach (var selectedArticle in selectedArticles.OrderByDescending(x=>x.CreateDate))
                {
                    var item = new XElement("Item");
                    root.Add(item);
                    item.Add(new XAttribute("image", selectedArticle.GetProperty("writerPicture")));
                    item.Add(new XAttribute("wCaption", selectedArticle.GetProperty("wCaption")));
                    item.Add(new XAttribute("nodeName", selectedArticle.Name));
                    item.Add(new XAttribute("id", selectedArticle.Id));
                }

                var nav = doc.CreateNavigator();
                return nav.Select("/NewsItems");
            }
        }
    }

    Then you can use this extension like this:

    <xsl:for-each select="MyExtensionAlias.GetLastNewsItems(1)/Item">

    <div class="writers">
           
    <img src="{@writerPicture}" />
           
    <a href="{umbraco.library:NiceUrl(@id)}"><span><xsl:value-of select="@wCaption"/></span></a>
           
    <br/><xsl:value-of select="@nodeName"/>
    </div>

    </xsl:for-each>

    hth, Thomas

  • ds 191 posts 223 karma points
    Aug 10, 2010 @ 13:20
    ds
    0

    Hi Thomas,

    Perhaps maxItem approach is wrong. To clarify, for example if authorA has several articles at his node, I need to show only the last created one. The process is same for other authors as well.

    By the way I am new completely to Umbraco, would you pls guide me how I can add XsltExtension to Umbraco?

  • Thomas Höhler 1237 posts 1709 karma points MVP
    Aug 10, 2010 @ 13:46
    Thomas Höhler
    0

    If you want the list of the last articles from every author sorted by author this is no problem with xslt. But if you want to have the list sorted by createDate of the article you propably would use the xsltextension.

    For a guide how to use XsltExtensions take a look here or take a look into the umbraco.tv series

    hth, Thomas

  • ds 191 posts 223 karma points
    Aug 10, 2010 @ 14:14
    ds
    0

    That was even a big help Thomas btw. As you have just pointed out, I want the list of the last articles from every author sorted by author. Based on my first post,  Where should I update code snippet in order to get that output?

  • Thomas Höhler 1237 posts 1709 karma points MVP
    Aug 10, 2010 @ 15:03
    Thomas Höhler
    0

    If you want to sort by author first you can do something like this:

    Snippet

    <xsl:for-each select="umbraco.library:GetXmlNodeById('1139')/node [string(data [@alias='umbracoNaviHide']) != '1']">
        <xsl:sort select="@nodeName" order="ascending" />
        <div class="writers">
            <xsl:for-each select="node">
                <xsl:sort order="descending" select="@createDate"/>
                <xsl:if test="position()=1">
                    <img src="{./data [@alias = 'writerPicture']}" />
                    <a href="{umbraco.library:NiceUrl(@id)}">
                        <span>
                            <xsl:value-of select="data [@alias = 'wCaption']"/>
                        </span>
                    </a>
                    <br/>
                    <xsl:value-of select="@nodeName"/>
                </xsl:if>
            </xsl:for-each>
        </div>
    </xsl:for-each>

    As you can see in line 6 the if statement checks if the item you are at is the first in the list you have.

    hth, Thomas

     

  • Thomas Höhler 1237 posts 1709 karma points MVP
    Aug 10, 2010 @ 15:05
    Thomas Höhler
    0

    To clarify the code: first you are iterating through every writer. For each writer you are starting a new div with class writer. Then you are iterating through all articles of the writer, but you are only using the first article for the output.

    hth, Thomas

  • Thomas Höhler 1237 posts 1709 karma points MVP
    Aug 10, 2010 @ 15:07
  • ds 191 posts 223 karma points
    Aug 10, 2010 @ 16:05
    ds
    0

    Thanks for help so far Thomas. It helped a lot to understand the basic of xslt.

  • Thomas Höhler 1237 posts 1709 karma points MVP
    Aug 10, 2010 @ 22:02
    Thomas Höhler
    0

    Glad I could help, enjoy Umbraco ;-)

Please Sign in or register to post replies

Write your reply to:

Draft