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.
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>
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.
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:
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]) > 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() < 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() < 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
I've got an idea of what could be done but I'm uncertain of your xml - anyway you could provide a snippet?
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
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
is working on a reply...
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.