XSLT previous,next example
Say you have a structure like this on your site.
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 [ <!ENTITY nbsp “ ”> ]>
<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 < $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>
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
Hi Tim,
Thanks for tip,
I have another solution :
previous
next
I think it has better performance and don’t need for-each.
Petr
OOPS
my xslt is missing, I send it by email…
Hello,
Nice example but when we want to apply sorting then we have to use two for-each loops.
Thanks a lot, and you too Petr.
Above code did not worked for me. Here is the code that worked for me
previous
next
oops code did not paste properly
previous
next
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.
I can’t seem to be able to reach this post from my iphone!!
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!