Copied to clipboard

Flag this post as spam?

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


  • Eddie Foreman 215 posts 288 karma points
    Jul 07, 2011 @ 09:51
    Eddie Foreman
    0

    Archive Links Menus - Improve Xslt

    Hi Guys,

    Trying to create a menu which displays links to press articles for previous years.  So the links would look like:

    • 2010 (9)
    • 2009 (5)

    The following xslt produces the correct year and number of items per year for the past two years. I've achieved this with a for-each and template-call for each year.   Although this is fine, and I could add additional for-each and template elements for each year. I was wondering if someone could advise on how I could improve or achieve the same result, but without the need of the additional elements for each previous year.

    <xsl:variable name="documentTypeAlias" select="string('Media Item')"/>
    <xsl:variable name="curYr" select="Exslt.ExsltDatesAndTimes:year()"/>
    <xsl:variable name="curUrl" select="umbraco.library:NiceUrl($currentPage/@id)"/>

    <xsl:template match="/">
    <xsl:if test="count($currentPage/node [@nodeTypeAlias = $documentTypeAlias and string(data [@alias='umbracoNaviHide']) != '1' and Exslt.ExsltDatesAndTimes:year(./data [@alias = 'publishedDate']) != $curYr]) &gt; 0">
    <div class="archive-wrapper">
    <h3>Archive</h3>
    <ul>
    <xsl:for-each select="$currentPage/node [@nodeTypeAlias = $documentTypeAlias and string(data [@alias='umbracoNaviHide']) != '1' and Exslt.ExsltDatesAndTimes:year(./data [@alias = 'publishedDate']) != $curYr and Exslt.ExsltDatesAndTimes:year(./data [@alias = 'publishedDate']) = ($curYr - 1)]">
    <xsl:if test="position() &lt; 2">
    <xsl:variable name="yr" select="Exslt.ExsltDatesAndTimes:year(./data [@alias = 'publishedDate'])" />
    <li>
    <a>
    <xsl:attribute name="href">
    <xsl:value-of select="$curUrl"/>?yr=<xsl:value-of select="$yr"/>
    </xsl:attribute>
    <xsl:value-of select="$yr"/>
    (
    <xsl:call-template name="OneYearAgo" />
    )
    </a>
    </li>
    </xsl:if>
    </xsl:for-each>
    <xsl:for-each select="$currentPage/node [@nodeTypeAlias = $documentTypeAlias and string(data [@alias='umbracoNaviHide']) != '1' and Exslt.ExsltDatesAndTimes:year(./data [@alias = 'publishedDate']) != $curYr and Exslt.ExsltDatesAndTimes:year(./data [@alias = 'publishedDate']) = ($curYr - 2)]">
    <xsl:if test="position() &lt; 2">
    <xsl:variable name="yr" select="Exslt.ExsltDatesAndTimes:year(./data [@alias = 'publishedDate'])" />
    <li>
    <a>
    <xsl:attribute name="href">
    <xsl:value-of select="$curUrl"/>?yr=<xsl:value-of select="$yr"/>
    </xsl:attribute>
    <xsl:value-of select="$yr"/>
    (
    <xsl:call-template name="TwoYearsAgo" />
    )
    </a>
    </li>
    </xsl:if>
    </xsl:for-each>
    </ul>
    </div>
    </xsl:if>
    </xsl:template>

    <xsl:template name="OneYearAgo">
    <xsl:value-of select="count($currentPage/node [@nodeTypeAlias = $documentTypeAlias and string(data [@alias='umbracoNaviHide']) != '1' and Exslt.ExsltDatesAndTimes:year(./data [@alias = 'publishedDate']) != $curYr and Exslt.ExsltDatesAndTimes:year(./data [@alias = 'publishedDate']) = ($curYr - 1)])"/>
    </xsl:template>

    <xsl:template name="TwoYearsAgo">
    <xsl:value-of select="count($currentPage/node [@nodeTypeAlias = $documentTypeAlias and string(data [@alias='umbracoNaviHide']) != '1' and Exslt.ExsltDatesAndTimes:year(./data [@alias = 'publishedDate']) != $curYr and Exslt.ExsltDatesAndTimes:year(./data [@alias = 'publishedDate']) = ($curYr - 2)])"/>
    </xsl:template>

    This is on a site running Umbraco 4.0.4.2

    Thanks,

    Eddie

     

  • Stuart Burrows 61 posts 110 karma points
    Jul 07, 2011 @ 18:49
    Stuart Burrows
    0

    I've got an idea of what could be done but I'm uncertain of your xml - anyway you could provide a snippet?

  • Chriztian Steinmeier 2800 posts 8791 karma points MVP 8x admin c-trib
    Jul 07, 2011 @ 22:37
    Chriztian Steinmeier
    2

    Hi Eddie,

    Here's a heavily refactored version that should help you in expanding it further without too much duplication.

    Note especially that I only use the extension function once, and that I start out creating a set of all the relevant nodes (by doctype alias, unhidden), and then subsequently select from that set - helps immensely on the readability of XPaths and performance too.

       <xsl:variable name="documentTypeAlias" select="'Media Item'" />
        <xsl:variable name="curYr" select="Exslt.ExsltDatesAndTimes:year()" />
        <xsl:variable name="curUrl" select="umbraco.library:NiceUrl($currentPage/@id)" />
    
        <!-- Grab all the non-hidden $documentTypeAlias nodes -->
        <xsl:variable name="nodes" select="$currentPage/node[@nodeTypeAlias = $documentTypeAlias][not(data[@alias = 'umbracoNaviHide'] = 1)]" />
        <!-- Nodes from this year -->
        <xsl:variable name="nodesFromThisYear" select="$nodes[substring(data[@alias = 'publishedDate'], 1, 4) = $curYr]" />
        <!-- Nodes from last year -->
        <xsl:variable name="nodesFromLastYear" select="$nodes[substring(data[@alias = 'publishedDate'], 1, 4) = $curYr - 1]" />
        <!-- Nodes from ... well, u get it by now :-) -->
        <xsl:variable name="nodesFromYore" select="$nodes[substring(data[@alias = 'publishedDate'], 1, 4) = $curYr - 2]" />
    
        <xsl:template match="/">
            <!-- If the combined set has nodes... -->
            <xsl:if test="$nodesFromLastYear | $nodesFromYore">
                <div class="archive-wrapper">
                    <h3>Archive</h3>
                    <ul>
                        <xsl:apply-templates select="$nodesFromLastYear[1]">
                            <xsl:with-param name="total" select="count($nodesFromLastYear)" />
                        </xsl:apply-templates>
    
                        <xsl:apply-templates select="$nodesFromYore[1]">
                            <xsl:with-param name="total" select="count($nodesFromYore)" />
                        </xsl:apply-templates>
                    </ul>
                </div>
            </xsl:if>
        </xsl:template>
    
        <xsl:template match="node">
            <xsl:param name="total" />
            <xsl:variable name="yr" select="substring(data[@alias = 'publishedDate'], 1, 4)" />
            <li>
                <a href="{$curUrl}?yr={$yr}">
                    <xsl:value-of select="concat($yr, ' (', $total, ')')" />
                </a>
            </li>
        </xsl:template>
    

    /Chriztian

  • Eddie Foreman 215 posts 288 karma points
    Jul 07, 2011 @ 23:09
    Eddie Foreman
    0

    Hi Chriztian,

    Thanks for supplying a refactored version of the code.  More then I was expecting, much appreciated.  Have since updated my xslt with paging and filtering. Away at a web conference tomorrow, but will let you know how it goes over the weekend.

    Thanks,

    Eddie

  • 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