Copied to clipboard

Flag this post as spam?

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


  • suzyb 474 posts 932 karma points
    Oct 13, 2011 @ 21:12
    suzyb
    0

    Grouping by year / month under certain parent node

    I am trying to display a new archive on my site that lists the years that have news and under them the months with the article count.  Something like...

    2011
    -- Jan (1)
    -- Feb (3)

    My issue is that I have archives in two different places and the archive is showing all the months that have articles not just those months in this section.  I'm using muenchian grouping and think I need to add the node id of the sections news index page to the key (from reading this page) but just can't work out how.

    <xsl:key name="years" match="NewsArticle" use="umbraco.library:FormatDateTime(articleDate, 'yyyy')"/>
    <xsl:key name="months" match="NewsArticle" use="umbraco.library:FormatDateTime(articleDate, 'yyyy-MM')"/>

    <xsl:for-each select="umbraco.library:GetXmlAll()/descendant-or-self::NewsArticle [(generate-id() = generate-id(key('years', Exslt.ExsltDatesAndTimes:year(articleDate))[1]))]">
    <xsl:sort select="articleDate" order="descending" />
    ... display year

    <xsl:variable name="months" select="key('years', Exslt.ExsltDatesAndTimes:year(articleDate))" />
    <!-- Iterate over all nodes with a month-id similar to the first in every group -->
    <xsl:for-each select="$months[generate-id() = generate-id(key('months',umbraco.library:FormatDateTime(articleDate, 'yyyy-MM'))[1])]">
    <xsl:sort select="articleDate" order="descending" />

    <xsl:value-of select="umbraco.library:FormatDateTime(articleDate, 'MMMM')"/>
    <!-- count all nodes in a group, i.e. with the same months-key -->
    <xsl:value-of select="concat(' (', count(key('months',umbraco.library:FormatDateTime(articleDate, 'yyyy-MM'))), ')')"/>
    </xsl:for-each>

    </xsl:for-each>

    Can anyone help?

  • Chriztian Steinmeier 2800 posts 8790 karma points MVP 8x admin c-trib
    Oct 13, 2011 @ 21:56
    Chriztian Steinmeier
    1

    Hi suzyb,

    You're correct in needing to include the news index - you can do that by concatenating it into the key's value. Here's a way to do it which assumes that the "news index" is a document type named "News", and that $currentPage is either that page, or a descendant of it... so you may need to tweak some of it:

    <xsl:param name="currentPage" />
    <xsl:variable name="siteRoot" select="$currentPage/ancestor-or-self::*[@level = 1]" />
    
    <xsl:key name="years" match="NewsArticle" use="concat(ancestor::News/@id, ':', substring(articleDate, 1, 4))" />
    <xsl:key name="months" match="NewsArticle" use="concat(ancestor::News/@id, ':', substring(articleDate, 1, 7))" />
    
    <xsl:template match="/">
        <xsl:variable name="newsSection" select="$currentPage/ancestor-or-self::News/@id" />
    
        <xsl:for-each select="$siteRoot/descendant-or-self::NewsArticle[generate-id() = generate-id(key('years', concat($newsSection, ':', substring(articleDate, 1, 4)))[1])]">
            <xsl:sort select="articleDate" order="descending" />
    
            <h2>Year: <xsl:value-of select="substring(articleDate, 1, 4)" /></h2>
            <xsl:variable name="months" select="key('years', concat($newsSection, ':', substring(articleDate, 1, 4)))" />
    
            <!-- Iterate over all nodes with a month-id similar to the first in every group -->
            <xsl:for-each select="$months[generate-id() = generate-id(key('months', concat($newsSection, ':', substring(articleDate, 1, 7)))[1])]">
                <xsl:sort select="articleDate" order="descending" />
    
                <p>
                    <xsl:value-of select="umbraco.library:FormatDateTime(articleDate, 'MMMM')" />
                    <!-- count all nodes in a group, i.e. with the same months-key -->
                    <xsl:value-of select="concat(' (', count(key('months', concat($newsSection, ':', substring(articleDate, 1, 7)))), ')')" />
                </p>
            </xsl:for-each>
    
        </xsl:for-each>
    </xsl:template>
    

    PS: I've substituted simple substring() expressions all the places where you were calling an extension function that does the same thing. 

    /Chriztian

  • suzyb 474 posts 932 karma points
    Oct 13, 2011 @ 22:16
    suzyb
    0

    That works.  Thank you very much.

Please Sign in or register to post replies

Write your reply to:

Draft