I'd like to create come controls to navigate among sibling pages on my site. Actually, though, they're not direct siblings, it's a little tricky. Here's the structure:
...etc. I want to navigate, back and forward, among thse "Item" nodes. I CAN start with the parent node of the 2009, 2008, etc. and then check for a nodeTypeAlias, just FYI. I see basically how to select the right collection of nodes, I just don't know how to get the "Next" and "Previous" links. Can anyone offer some XSLT help with this?
Assuming you can get your nodesets together by creating one or multiple xpath statements, this should get you going with the paging. I've used this as an example in the past and it works a charm!
The code on Page 11 that Nik pointed me to showed the Prev and Next links but every link was to the same page that I was on.
Petr's code using preceding-sibling and following-sibling won't work for me because of the structure of my site (indicated in the first post)-- all the news items are not siblings of each other because of the individual year holder objects shown in my first post. I will need to use a for-each loop.
There's two tricks involved in solving this one: The node-set() function and the xsl:number instruction.
The node-set() function (available in the 'MSXML' namespace or in the Exslt 'Common' namespace) will collect the nodes into a single set, so that it's possible to say "Give me the 5th node in this set" and actually get the 2nd node of the 2nd "group" (following your sample data).
Since the preceding-sibling and following-sibling axes, along with the position() function, only operate on the original source tree, we'll need to find some alternative way to get the info they provide.
I generally like to keep the output code as clean as possible, so I'm performing the bulk of the logic in setting up a couple of variables for use in the output, so the actual output is easily understood.
Here's the code:
<?xml version="1.0" encoding="utf-8" ?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:umbraco.library="urn:umbraco.library"
xmlns:msxml="urn:schemas-microsoft-com:xslt"
exclude-result-prefixes="umbraco.library msxml"
>
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes" />
<xsl:param name="currentPage" />
<!--
Grab the root of the site (assumes first level is actual root, e.g. for multi-language sites, otherwise,
use "$currentPage/ancestor-or-self::root" to grab the absolute root)
-->
<xsl:variable name="siteRoot" select="$currentPage/ancestor-or-self::node[@level = 1]" />
<!-- Alias of the grouping nodes (e.g. the "2009" holder node in an archive structure) -->
<xsl:variable name="groupType" select="'CWS_NewsItem'" />
<!-- Create a special collection of nodes for paging -->
<xsl:variable name="data" select="msxml:node-set($siteRoot/node[@nodeTypeAlias = $groupType]/node)" />
<xsl:template match="/">
<xsl:apply-templates select="$currentPage" />
</xsl:template>
<xsl:template match="node">
<!-- Find the equivalent of position() but within our special collection -->
<xsl:variable name="p">
<xsl:number level="any" count="node[@nodeTypeAlias = $groupType]/node" />
</xsl:variable>
<xsl:variable name="prevNodeId">
<xsl:choose>
<xsl:when test="$currentPage/@id = $data[1]/@id">
<xsl:value-of select="$data[last()]/@id" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$data[$p - 1]/@id" />
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="nextNodeId">
<xsl:choose>
<xsl:when test="$currentPage/@id = $data[last()]/@id">
<xsl:value-of select="$data[1]/@id" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$data[$p + 1]/@id" />
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<!-- Output the links -->
<a href="{umbraco.library:NiceUrl($prevNodeId)}" rel="pre">Previous</a> | <a href="{umbraco.library:NiceUrl($nextNodeId)}" rel="next">Next</a>
</xsl:template>
</xsl:stylesheet>
This version also enables wrapping from the last item to the first and vice versa - should be fairly easy to see where that is done if you want to disable that.
You may need to change the variable 'groupType' and you'll most likely have to change the XPath in the 'data' variable if you have additional levels of nodes before the structure you are processing. When changing the XPath for the data variable, remember to keep the "count" attribute of the xsl:number instruction in sync with it...
I've use Petr's contribution to the following http://www.nibble.be/?p=44 in version 4 of Umbraco but it doesn't seem to be working for me in a 4.5 installation?
That's because the example you posted used the legacy XML schema. With version 4.5 the XML schema changed. So therefore there are many XSLT examples based on the legacy schema around the forum and elsewhere.
However there are some wiki entries about it and it's possible to make Umbraco use the legacy schema by changing it in the UmbracoSettings.config file.
However I agree with you that for people new to Umbraco and the use of XSLT in Umbraco this can be rather confusing. But hey, that's why we are in here to help each other out with questions like these :-)
previous page, next page
Hi,
I'd like to create come controls to navigate among sibling pages on my site. Actually, though, they're not direct siblings, it's a little tricky. Here's the structure:
...etc. I want to navigate, back and forward, among thse "Item" nodes. I CAN start with the parent node of the 2009, 2008, etc. and then check for a nodeTypeAlias, just FYI. I see basically how to select the right collection of nodes, I just don't know how to get the "Next" and "Previous" links. Can anyone offer some XSLT help with this?
Thanks,
Garrett
Assuming you can get your nodesets together by creating one or multiple xpath statements, this should get you going with the paging. I've used this as an example in the past and it works a charm!
http://www.nibble.be/?p=11
Hth,
Nik
I recommend this article, specially my addition :-)
http://www.nibble.be/?p=44
Petr
Hello Petr, Nik-- thanks so much for the replies.
The code on Page 11 that Nik pointed me to showed the Prev and Next links but every link was to the same page that I was on.
Petr's code using preceding-sibling and following-sibling won't work for me because of the structure of my site (indicated in the first post)-- all the news items are not siblings of each other because of the individual year holder objects shown in my first post. I will need to use a for-each loop.
So, that relegates me to the following code:
However, the links are not showing up. Can anyone offer any advice as to why this isn't working?
Thanks again and in advance,
Garrett
Hi Garrett,
There's two tricks involved in solving this one: The node-set() function and the xsl:number instruction.
The node-set() function (available in the 'MSXML' namespace or in the Exslt 'Common' namespace) will collect the nodes into a single set, so that it's possible to say "Give me the 5th node in this set" and actually get the 2nd node of the 2nd "group" (following your sample data).
Since the preceding-sibling and following-sibling axes, along with the position() function, only operate on the original source tree, we'll need to find some alternative way to get the info they provide.
I generally like to keep the output code as clean as possible, so I'm performing the bulk of the logic in setting up a couple of variables for use in the output, so the actual output is easily understood.
Here's the code:
This version also enables wrapping from the last item to the first and vice versa - should be fairly easy to see where that is done if you want to disable that.
You may need to change the variable 'groupType' and you'll most likely have to change the XPath in the 'data' variable if you have additional levels of nodes before the structure you are processing. When changing the XPath for the data variable, remember to keep the "count" attribute of the xsl:number instruction in sync with it...
Hope this helps,
/Chriztian
I've use Petr's contribution to the following http://www.nibble.be/?p=44 in version 4 of Umbraco but it doesn't seem to be working for me in a 4.5 installation?
Is there a reason for this or am I being dumb?
Regards,
Matt
Can anybody help me with this?
Not working in my 4.5.2 project.
Scrabbled around the forum and found that 'node' needs to be changed to *[@isDoc]
Easy if you know how, but where do you find out this kind of stuff?
Hi Matt
That's because the example you posted used the legacy XML schema. With version 4.5 the XML schema changed. So therefore there are many XSLT examples based on the legacy schema around the forum and elsewhere.
However there are some wiki entries about it and it's possible to make Umbraco use the legacy schema by changing it in the UmbracoSettings.config file.
I like this entry by Sebastian Janssen: http://our.umbraco.org/wiki/reference/xslt/45-xml-schema/switching-between-old-and-new-schema
Lee Kelleher has also written this blogpost just before the release of 4.5 (hence the reference for 4.1, which was the version people were expecting untill the 4.5 surprise at codegarden) http://blog.leekelleher.com/2010/04/02/working-with-xslt-using-new-xml-schema-in-umbraco-4-1/
However I agree with you that for people new to Umbraco and the use of XSLT in Umbraco this can be rather confusing. But hey, that's why we are in here to help each other out with questions like these :-)
Hope this answer is usefull to you.
/Jan
Thanks for reply and the information.
The blog post was useful to read as I've certainly been strggling to figure out what changes to make when converting old to new schemas.
Regards,
Matt
is working on a reply...