Nibble

XSLT previous,next example

Say you have a structure like this on your site.

xslt

Multiple content items of the same documenttype, like news items. And you want to display a previous and a next link on those news items.

This can be done with some xslt. Here is an example:

<?xml version=”1.0″ encoding=”UTF-8″?>
<!DOCTYPE xsl:stylesheet [ &lt;!ENTITY nbsp “&#x00A0;”> ]>
<xsl:stylesheet 
    version=”1.0″ 
    xmlns:xsl=”http://www.w3.org/1999/XSL/Transform” 
    xmlns:msxml=”urn:schemas-microsoft-com:xslt”
    xmlns:umbraco.library=”urn:umbraco.library”
    exclude-result-prefixes=”msxml umbraco.library”>
 
<xsl:output method=”xml” omit-xml-declaration=”yes” />
 
<xsl:param name=”currentPage”/>
 
<xsl:template match=”/”>
 
<!– The fun starts here –>
 
<xsl:for-each select=”$currentPage/ancestor-or-self::node [@nodeTypeAlias = ‘NewsPage’]/node”>
 
<xsl:if test=”$currentPage/@id = current()/@id”>
 
 <xsl:call-template name=”prevnext”>
    <xsl:with-param name=”count” select=”count($currentPage/ancestor-or-self::node [@nodeTypeAlias = ‘NewsPage’]/node)”/>
    <xsl:with-param name=”itemindex” select=”position()”/>
  </xsl:call-template>
</xsl:if>
 
</xsl:for-each>
 
</xsl:template>
 
<xsl:template name=”prevnext” >
<xsl:param name=”count” />
<xsl:param name=”itemindex” />
 
<xsl:if test=”$itemindex > 1″>
<a href=”{umbraco.library:NiceUrl($currentPage/ancestor-or-self::node [@nodeTypeAlias = ‘NewsPage’]/node[$itemindex-1]/@id)}”>
Previous</a>
</xsl:if>
 
<xsl:if test=”$itemindex &lt; $count”>
<a href=”{umbraco.library:NiceUrl($currentPage/ancestor-or-self::node [@nodeTypeAlias = ‘NewsPage’]/node[$itemindex +1]/@id)}”>
Next </a>
</xsl:if>
 
</xsl:template>
 
</xsl:stylesheet>

The Key is to know how many nodes(newsitems) there are and what the position of the current node is (first, second, .. last) because you don’t need to display a previous link if it’s the first item or a next link if it’s the last.

UPDATE:

Petr Snobelt mailed me the following snippet, which shows another technique (no for-each loop, so should be faster)

<xsl:if test=”count($currentPage/preceding-sibling::node) != 0″>
previous
<a href=”{umbraco.library:NiceUrl($currentPage/preceding-sibling::node[1]/@id)}”>
 <xsl:value-of select=”$currentPage/preceding-sibling::node[1]/@nodeName”/>
</a>
<br />
</xsl:if>
 
<xsl:if test=”count($currentPage/following-sibling::node) != 0″>
next
<a href=”{umbraco.library:NiceUrl($currentPage/following-sibling::node[1]/@id)}”>
 <xsl:value-of select=”$currentPage/following-sibling::node[1]/@nodeName”/>
</a>
</xsl:if>

10 Comments so far

  1. Warren Buckley on September 4th, 2008

    Yet again a useful post for beginners and handy for old timer’s who forget how to do this.

    Nice one Tim - keep up this good work & enthusiasm!

    Warren

  2. Petr Snobelt on September 4th, 2008

    Hi Tim,

    Thanks for tip,

    I have another solution :

    previous

    next

    I think it has better performance and don’t need for-each.

    Petr

  3. Petr Snobelt on September 4th, 2008

    OOPS :-( my xslt is missing, I send it by email…

  4. Wojciech on April 6th, 2010

    Hello,

    Nice example but when we want to apply sorting then we have to use two for-each loops.

  5. Matt on June 17th, 2010

    Thanks a lot, and you too Petr.

  6. Pinal Bhatt on December 28th, 2010

    Above code did not worked for me. Here is the code that worked for me

    previous

           

    next

  7. Pinal Bhatt on December 28th, 2010

    oops code did not paste properly

    previous

           

    next

  8. Matt taylor on January 18th, 2011

    I’m not hot on XSLT or the differences between the old and new schema but I think you’ll find that ‘node’ needs to be changed to *[@isDoc] to work with V4.5 and above.

  9. shamtest on May 14th, 2011

    I can’t seem to be able to reach this post from my iphone!!

  10. Jon Dunfee on September 4th, 2012

    This post helped me when I was trying to perform next/previous on product catalog. Initially, I went for the minimalistic approach Petr submitted; unfortunately, the method doesn’t provide sorting capability. I ended up with a solution much similar to the original solution adding . Perhaps the sort order is a new schema addition, not sure. Either way, thanks!

Leave a Reply