Copied to clipboard

Flag this post as spam?

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


  • Craig O'Mahony 364 posts 918 karma points
    Jul 06, 2015 @ 10:37
    Craig O'Mahony
    0

    Unique list of nodes XSLT

    Hi all,

    I'm trying desperately to get a unique list of year/month published dates from my content. All the examples that I've seen are advising me to use 'keys' but however hard I try I can't get any output whatsoever using this approach.

    Here's my basic XSLT what produces a list of yyyy-mm outputs.

    <xsl:for-each select="$news">
        <xsl:value-of select="substring(@updateDate, 0,8)"/><br/>
    </xsl:for-each>
    

    Could someone give me some pointers please on how I can get a distinct list of yyyy-mm please?

    thanks, Craig

  • Chriztian Steinmeier 2800 posts 8790 karma points MVP 8x admin c-trib
    Jul 06, 2015 @ 10:52
    Chriztian Steinmeier
    0

    Hi Craig,

    Yeah, it's not the simplest thing in the world, but here's a starter to get you going:

    <xsl:param name="currentPage" />
    
    <!-- Index documents by their year+month combination -->
    <xsl:key name="documentsByMonth" match="*[@isDoc]" use="substring(@updateDate, 1, 7)" />
    
    <!-- Grab news from somewhere -->
    <xsl:variable name="news" select="$currentPage/*[@isDoc]" />
    
    <xsl:template match="/">
        <xsl:for-each select="$news/*[@isDoc][count(. | key('documentsByMonth', substring(@updateDate, 1, 7))[1]) = 1]">
            <xsl:sort select="@updateDate" data-type="text" order="descending" />
    
            <!-- Render stuff for "group" only (e.g., a header or similar) -->
            <xsl:apply-templates select="." mode="group" />
    
            <!-- Render items in group -->
            <xsl:apply-templates select="key('documentsByMonth', substring(@updateDate, 1, 7))" mode="item">
                <xsl:sort select="@updateDate" data-type="text" order="descending" />
            </xsl:apply-templates>
        </xsl:for-each>
    </xsl:template>
    
    <xsl:template match="*[@isDoc]" mode="group">
        <!-- Output for header -->
        <xsl:value-of select="substring(@updateDate, 1, 7)" />: <xsl:text />
    </xsl:template>
    
    <xsl:template match="*[@isDoc]" mode="item">
        <!-- Output for a single item -->
        <xsl:value-of select="@nodeName" />, <xsl:text />
    </xsl:template>
    

    If all your "news" nodes have the same document type alias, you can substitute *[@isDoc] for that document type alias (everywhere) to optimize the thing (probably only noticable with huge sets of nodes, though).

    Hope that helps,

    /Chriztian

  • Craig O'Mahony 364 posts 918 karma points
    Jul 06, 2015 @ 11:07
    Craig O'Mahony
    0

    Hi Chriztian,

    Thanks for that but I'm not getting any output whatsoever! (no errors either though!).

    The nodetype is NewsItem and this is an image of my content tree

    enter image description here

    Thanks again

  • Chriztian Steinmeier 2800 posts 8790 karma points MVP 8x admin c-trib
    Jul 06, 2015 @ 11:15
    Chriztian Steinmeier
    0

    Hi Craig,

    Alright - then we'll need to do some debugging...

    Could you post your XSLT - either here or perhaps a link to a Gist - keys only return results within the document that contains the current context node, which is mangled a little by the way Umbraco does XSLT transforms.

    So I'll need to see exactly what's going on to give any good pointers...

    /Chriztian

  • Craig O'Mahony 364 posts 918 karma points
    Jul 06, 2015 @ 11:19
    Craig O'Mahony
    0

    Hi, here's my full XSLT (which is basically what you've pointed me to with a couple of amendments)

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE xsl:stylesheet [ <!ENTITY nbsp "&#x00A0;"> ]>
    <xsl:stylesheet 
        version="1.0" 
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
        xmlns:msxml="urn:schemas-microsoft-com:xslt"
        xmlns:umbraco.library="urn:umbraco.library" xmlns:Exslt.ExsltCommon="urn:Exslt.ExsltCommon" xmlns:Exslt.ExsltDatesAndTimes="urn:Exslt.ExsltDatesAndTimes" xmlns:Exslt.ExsltMath="urn:Exslt.ExsltMath" xmlns:Exslt.ExsltRegularExpressions="urn:Exslt.ExsltRegularExpressions" xmlns:Exslt.ExsltStrings="urn:Exslt.ExsltStrings" xmlns:Exslt.ExsltSets="urn:Exslt.ExsltSets" xmlns:Examine="urn:Examine" 
        exclude-result-prefixes="msxml umbraco.library Exslt.ExsltCommon Exslt.ExsltDatesAndTimes Exslt.ExsltMath Exslt.ExsltRegularExpressions Exslt.ExsltStrings Exslt.ExsltSets Examine ">
    
    
    <xsl:output method="xml" omit-xml-declaration="yes"/>
    
    <xsl:param name="currentPage" />
    
    <!-- Index documents by their year+month combination -->
    <xsl:key name="documentsByMonth" match="*[@isDoc]" use="substring(@updateDate, 1, 7)" />
    
    <!-- Grab news from somewhere -->
    <xsl:variable name="news" select="$currentPage/*[@isDoc]" />
    
    <xsl:template match="/">
        <xsl:for-each select="$news/*[@isDoc][count(. | key('documentsByMonth', substring(@updateDate, 1, 7))[1]) = 1]">
            <xsl:sort select="@updateDate" data-type="text" order="descending" />
    
            <!-- Render stuff for "group" only (e.g., a header or similar) -->
            <xsl:apply-templates select="." mode="group" />
    
            <!-- Render items in group -->
            <xsl:apply-templates select="key('documentsByMonth', substring(@updateDate, 1, 7))" mode="item">
                <xsl:sort select="@updateDate" data-type="text" order="descending" />
            </xsl:apply-templates>
        </xsl:for-each>
    </xsl:template>
    
    <xsl:template match="*[@isDoc]" mode="group">
        <!-- Output for header -->
        <xsl:value-of select="substring(@updateDate, 1, 7)" />: <xsl:text />
    </xsl:template>
    
    <xsl:template match="*[@isDoc]" mode="item">
        <!-- Output for a single item -->
        <xsl:value-of select="@nodeName" />, <xsl:text />
    </xsl:template>
    
    </xsl:stylesheet>
    
  • Chriztian Steinmeier 2800 posts 8790 karma points MVP 8x admin c-trib
    Jul 06, 2015 @ 11:28
    Chriztian Steinmeier
    0

    I just spotted an error right away:

    In the for-each, remove the /*[@isDoc] from the select, as it tries to get all nodes that are children of the news items. It should look like this:

    <xsl:for-each select="$news[count( ...

    /Chriztian

  • Craig O'Mahony 364 posts 918 karma points
    Jul 06, 2015 @ 11:36
    Craig O'Mahony
    0

    Done that mate but still nothing :(

  • Chriztian Steinmeier 2800 posts 8790 karma points MVP 8x admin c-trib
    Jul 06, 2015 @ 11:46
    Chriztian Steinmeier
    0

    I don't believe you - it should work! :-)

    Kidding aside - one reason could be that it's not running as a macro on the "News Repository" node?

    The $news variable selects all the children of $currentPage, which forces it to only work on the repository node - if you need it to work from everywere, you need to do something like this:

    <xsl:param name="currentPage" />
    
    <xsl:variable name="siteRoot" select="$currentPage/ancestor-or-self::*[@level = 1]" />
    
    <xsl:variable name="newsRepository" select="$siteRoot/PATH-TO-NEWS_REPOSITORY" />
    <xsl:variable name="news" select="$newsRepository/NewsItem" />
    

    /Chriztian

  • Craig O'Mahony 364 posts 918 karma points
    Jul 06, 2015 @ 12:06
    Craig O'Mahony
    0

    Hi Mate (Sorry for the trouble!) but still not getting any output.

    Here's a picture of my content tree showing the NewsRepository and the NewsItems (it's the NewsItem's that I'm trying to get a unique list of published/updated dates.

    enter image description here

    thanks again

  • Chriztian Steinmeier 2800 posts 8790 karma points MVP 8x admin c-trib
    Jul 06, 2015 @ 12:11
    Chriztian Steinmeier
    0

    No worries :)

    So with that content tree, you'd need to set the newsRepository variable like this:

    <xsl:variable name="newsRepository" select="$siteRoot/NewsRepository" />
    

    (assuming the others are set according to the earlier post)

    /Chriztian

  • Craig O'Mahony 364 posts 918 karma points
    Jul 06, 2015 @ 12:26
    Craig O'Mahony
    0

    Oooh think we might be getting somewhere.....

    I think that you've nailed it matey :) Now I just gotta convert the month year to full month and year and it's all happy days!

Please Sign in or register to post replies

Write your reply to:

Draft