I'm trying to combine the xslt approaches used in this post and this post, to print out prev/next links (but if I'm on the first item, not prev, and if I'm on the last, no next).
The docType structure has "Program" docTypes and underneath those, there are 3 levels of docType 'systemDateFolder' (year->month->day), and finally at the leaf level, "show" docType. I want prev/next on my show items.
The default ordering of the nodes seems to be by createDate, but I am running into instances where this is causing problems. So I need to sort on 'displayDate'. I'm most familiar with sorting inside for-loops like this:
I would really like to try and not use loops, and use apply-templates, but I'm getting stuck in a couple of places. Here's what I've got:
<xsl:output method="xml" omit-xml-declaration="yes"/>
<xsl:param name="currentPage"/>
<!-- get the parent program root for this show i'm on -->
<xsl:variable name="programRoot" select="$currentPage/ancestor-or-self::cprProgramItem" />
<!-- Use that root to get all the shows. 1) I need to figure out how to sort this using apply-templates I think -->
<xsl:variable name="data" select="msxml:node-set($programRoot/systemDateFolder/systemDateFolder/systemDateFolder/show)" />
<xsl:template match="/">
<xsl:apply-templates select="$currentPage" />
</xsl:template>
<!-- 2) 'node' here is part of the old schema? I change it to 'show' because those are the alias of the leaves I want to match -->
<xsl:template match="show">
<!-- Find the equivalent of position() but within our special collection -->
<!-- 3) This appears to give me the absolute position of this node in the entire content tree? It's like 2603 on the first item and there's only
a couple of hundred of 'shows' in this program. Obviously, I can't use this '$p' to position links from $data. I created a for loop here in order
to look up what my currentPage/@id position is inside $data, but I should just get the select syntax right I think? I want to not use loops.
-->
<xsl:variable name="p">
<xsl:number level="any" count="show" />
</xsl:variable>
<!--
<xsl:variable name="p">
<xsl:for-each select="$data">
<xsl:if test="$currentPage/@id = ./@id">
<xsl:value-of select="position()" />
</xsl:if>
</xsl:for-each>
</xsl:variable>
-->
<xsl:variable name="prevNodeId">
<xsl:choose>
<xsl:when test="$currentPage/@id = $data[1]/@id">
<xsl:value-of select="'0'"/>
</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="'0'"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$data[$p + 1]/@id" />
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:if test="$prevNodeId != '0'">
<h3 style="background-color:#e4e1e0;padding:.5em .7em;float:left;display:inline;border: 1px solid #ccc;">
<a>
<xsl:attribute name="href">
<xsl:value-of select="umbraco.library:NiceUrl($prevNodeId)" />
</xsl:attribute> OLDER SHOW
</a>
</h3>
</xsl:if>
<xsl:if test="$nextNodeId != '0'">
<h3 style="background-color:#e4e1e0;padding:.5em .7em;float:right;display:inline;border: 1px solid #ccc;">
<a>
<xsl:attribute name="href">
<xsl:value-of select="umbraco.library:NiceUrl($nextNodeId)" />
</xsl:attribute>NEWER SHOW
</a>
</h3>
</xsl:if>
<textarea>
p:<xsl:value-of select="$p" />
currentPage/id:<xsl:value-of select="$currentPage/@id" />
prevNodeId:<xsl:value-of select="$prevNodeId" />
nextNodeId:<xsl:value-of select="$nextNodeId" />
</textarea>
</xsl:template>
So my questions are in the xslt, but basically:
1) How do I sort $data with another apply-templates while still being able to match to the other apply-templates?
2) When I go to find my position in data in a template match, the old schema example was 'node[@nodeTypeAlias = $groupType]/node'
I tried systemDateFolder/show, systemDateFolder/systemDateFolder/systemDateFolder/show, and other variations, but I think I'm not understanding the context of what I'm trying to select with the count variable:
prev/next + sort + msxml:node-set
Hi,
I'm trying to combine the xslt approaches used in this post and this post, to print out prev/next links (but if I'm on the first item, not prev, and if I'm on the last, no next).
The docType structure has "Program" docTypes and underneath those, there are 3 levels of docType 'systemDateFolder' (year->month->day), and finally at the leaf level, "show" docType. I want prev/next on my show items.
The default ordering of the nodes seems to be by createDate, but I am running into instances where this is causing problems. So I need to sort on 'displayDate'. I'm most familiar with sorting inside for-loops like this:
But I have eventually found that I cannot sort my set like this when using msxml:nodeset.
So I kind of have it working using the way I would normally do it, but I want to make it closer to the examples in the links above:
I would really like to try and not use loops, and use apply-templates, but I'm getting stuck in a couple of places. Here's what I've got:
So my questions are in the xslt, but basically:
1) How do I sort $data with another apply-templates while still being able to match to the other apply-templates? 2) When I go to find my position in data in a template match, the old schema example was 'node[@nodeTypeAlias = $groupType]/node'
I tried systemDateFolder/show, systemDateFolder/systemDateFolder/systemDateFolder/show, and other variations, but I think I'm not understanding the context of what I'm trying to select with the count variable:
3) I guess if I can figure out 2), three really works itself out.
Hi Jacob,
It sounds like you could try my Pagination Helper — even if you're only showing 1 result per page, and you don't want to show individual page links.
It was designed to take all the calculation logic out of this typical problem, and just let you focus on having a template for the output.
Maybe worth a shot?
/Chriztian
PS: Here's a direct link to the helper file in the dist directory, just in case :)
Thanks Chriztian,
I got what I had working, I had to move on from this quickly.
I'll keep this in mind in the future.
is working on a reply...