Copied to clipboard

Flag this post as spam?

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


  • suzyb 464 posts 877 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 2726 posts 8320 karma points MVP 4x 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 464 posts 877 karma points
    Oct 13, 2011 @ 22:16
    suzyb
    0

    That works.  Thank you very much.

  • This forum is in read-only mode while we transition to the new forum.

    You can continue this topic on the new forum by tapping the "Continue discussion" link below.

Please Sign in or register to post replies