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

Please Sign in or register to post replies

Write your reply to:

Draft