I have a list I successfully display grouped by year and month. Now the list is getting huge. I need to paginate the results. I've looked at the examples but none combine the two. How would I take the code below and convert it to support pagination?
<xsl:key name="years" match="* [@isDoc and (name()='LegalNewsHeadline' or name()='ArizonaAttorneyNewsCenterArticle')]" use="umbraco.library:FormatDateTime(publicationDate, 'yyyy')"/> <xsl:key name="months" match="* [@isDoc and (name()='LegalNewsHeadline' or name()='ArizonaAttorneyNewsCenterArticle')]" use="umbraco.library:FormatDateTime(publicationDate, 'yyyyMMMM')"/>
Large chunk of code - hard job to "just paginate", but I've got something you can try:
I have created a "_PaginationHelper.xslt" file that should be suitable for this - currently it's on GitHub - you can get it here: _PaginationHelper.xslt
What you need to do is:
1. Include the helper with <xsl:include href="_PaginationHelper.xslt" /> (just add that in the bottom of the main XSLT file)
2. Take the chunk of HTML you're generating in the innermost for-each, and extract that to a separate template
3. Instead of the <xsl:for-each> you then collect the node ids that needs to be output, and put them in a "proxy" variable (we need to create a new sorted set because the nodes will otherwise render in document order).
4. Call the PaginateSelection template and send it your proxy to render a page of data
Something like this:
<xsl:stylesheet>
<xsl:template match="/">
<xsl:for-each select="...">
<xsl:for-each select="...">
<!-- This is where the innermost <xsl:for-each> was -->
<xsl:variable name="sortedDataProxy">
<xsl:for-each select="key('months', umbraco.library:FormatDateTime(publicationDate,'yyyyMMMM'))">
<xsl:sort select="publicationDate" order="descending" />
<xsl:sort select="@sortOrder" data-type="number" order="ascending" />
<!-- Just record the id -->
<nodeId><xsl:value-of select="@id" /></nodeId>
</xsl:for-each>
</xsl:variable>
<!-- Need to convert to nodeset for XPath navigation in proxy -->
<xsl:variable name="sortedData" select="msxml:node-set($sortedDataProxy)/nodeId" />
<!-- Do the magic thing -->
<xsl:call-template name="PaginateSelection">
<xsl:with-param name="selection" select="$sortedData" />
</xsl:call-template>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
<!-- Template for each item in the paginated set -->
<xsl:template match="LegalNewsHeadline | ArizonaAttorneyNewsCenterArticle">
<!-- Chunk from innermost <xsl:for-each> here -->
</xsl:template>
<!-- Template to invoke the template above on the nodes from the sorted set -->
<xsl:template match="nodeId">
<xsl:apply-templates select="umbraco.library:GetXmlNodeById(.)" />
</xsl:template>
<!-- Get help ... -->
<xsl:include href="_PaginationHelper.xslt" />
</xsl:stylesheet>
Now this may seem like a lot of hoopla - but that's because of two things: 1: Your XSLT has everything inside a single template which isn't the optimal scenario for my helper; and 2: We need to pre-sort the nodes because we can't specify sorting inside the select statement.
Hopefully you get to a point where something's working and we can take it from there :-)
<xsl:key name="years" match="* [@isDoc and (name()='LegalNewsHeadline' or name()='ArizonaAttorneyNewsCenterArticle')]" use="umbraco.library:FormatDateTime(publicationDate, 'yyyy')"/> <xsl:key name="months" match="* [@isDoc and (name()='LegalNewsHeadline' or name()='ArizonaAttorneyNewsCenterArticle')]" use="umbraco.library:FormatDateTime(publicationDate, 'yyyyMMMM')"/>
<xsl:for-each select="key('months',umbraco.library:FormatDateTime(publicationDate,'yyyyMMMM'))"> <!-- This is where the innermost <xsl:for-each> was --> <xsl:variable name="sortedDataProxy"> <xsl:for-each select="key('months', umbraco.library:FormatDateTime(publicationDate,'yyyyMMMM'))"> <xsl:sort select="publicationDate" order="descending" /> <xsl:sort select="@sortOrder" data-type="number" order="ascending" /> <!-- Just record the id --> <nodeId><xsl:value-of select="@id" /></nodeId> </xsl:for-each> </xsl:variable> <!-- Need to convert to nodeset for XPath navigation in proxy --> <xsl:variable name="sortedData" select="msxml:node-set($sortedDataProxy)/nodeId" /> <!-- Do the magic thing --> <xsl:call-template name="PaginateSelection"> <xsl:with-param name="selection" select="$sortedData" /> </xsl:call-template>
</xsl:for-each> </div> </xsl:for-each> <br /> </xsl:for-each> </xsl:template> <!-- Template for each item in the paginated set --> <xsl:template match="LegalNewsHeadline | ArizonaAttorneyNewsCenterArticle"> <p><xsl:value-of select="headline"/></p> </xsl:template> <!-- Template to invoke the template above on the nodes from the sorted set --> <xsl:template match="nodeId"> <xsl:apply-templates select="umbraco.library:GetXmlNodeById(.)" /> </xsl:template> <!-- Get help ... --> <xsl:include href="_PaginationHelper.xslt" /> </xsl:stylesheet>
Grouping and pagination
I have a list I successfully display grouped by year and month. Now the list is getting huge. I need to paginate the results. I've looked at the examples but none combine the two. How would I take the code below and convert it to support pagination?
<?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" xmlns:Exslt.ExsltCommon="urn:Exslt.ExsltCommon" xmlns:Exslt.ExsltDatesAndTimes="urn:Exslt.ExsltDatesAndTimes" xmlns:Exslt.ExsltMath="urn:Exslt.ExsltMath" xmlns:Exslt.ExsltRegularExpressions="urn:Exslt.ExsltRegularExpressions" xmlns:Exslt.ExsltStrings="urn:Exslt.ExsltStrings" xmlns:Exslt.ExsltSets="urn:Exslt.ExsltSets" xmlns:Designit.VideoEmbed="urn:Designit.VideoEmbed" xmlns:PS.XSLTsearch="urn:PS.XSLTsearch"
exclude-result-prefixes="msxml umbraco.library Exslt.ExsltCommon Exslt.ExsltDatesAndTimes Exslt.ExsltMath Exslt.ExsltRegularExpressions Exslt.ExsltStrings Exslt.ExsltSets PS.XSLTsearch ">
<xsl:output method="html" omit-xml-declaration="yes"/>
<xsl:param name="currentPage"/>
<xsl:param name="previewWidth" select="16" />
<xsl:param name="previewHeight" select="16" />
<xsl:param name="videoWidth" select="640" />
<xsl:param name="videoHeight" select="480" />
<xsl:key name="years" match="* [@isDoc and (name()='LegalNewsHeadline' or name()='ArizonaAttorneyNewsCenterArticle')]" use="umbraco.library:FormatDateTime(publicationDate, 'yyyy')"/>
<xsl:key name="months" match="* [@isDoc and (name()='LegalNewsHeadline' or name()='ArizonaAttorneyNewsCenterArticle')]" use="umbraco.library:FormatDateTime(publicationDate, 'yyyyMMMM')"/>
<xsl:template match="/">
<xsl:value-of select="umbraco.library:RegisterJavaScriptFile('fancybox', '/scripts/Designit.VideoEmbed/jquery.fancybox-1.3.1.pack.js')"/>
<xsl:value-of select="umbraco.library:RegisterStyleSheetFile('cssFancyBox', '/css/Designit.VideoEmbed/jquery.fancybox-1.3.1.css')"/>
<xsl:for-each select="$currentPage/..//* [@isDoc and (name()='LegalNewsHeadline' or name()='ArizonaAttorneyNewsCenterArticle')][(generate-id()=generate-id(key('years', umbraco.library:FormatDateTime(publicationDate,'yyyy'))))]">
<xsl:sort select="publicationDate" order="descending"/>
<xsl:sort select="@sortOrder" data-type="number" order="ascending" />
<h3><strong><xsl:value-of select="Exslt.ExsltDatesAndTimes:year(publicationDate)"/></strong></h3>
<xsl:for-each select="key('years',Exslt.ExsltDatesAndTimes:year(publicationDate)) [(generate-id()=generate-id(key('months', umbraco.library:FormatDateTime(publicationDate,'yyyyMMMM'))[1]))]">
<xsl:sort select="publicationDate" order="descending"/>
<xsl:sort select="@sortOrder" data-type="number" order="ascending" />
<div style="margin-left:20px;">
<h3><xsl:value-of select="Exslt.ExsltDatesAndTimes:monthname(publicationDate)"/></h3>
<xsl:for-each select="key('months',umbraco.library:FormatDateTime(publicationDate,'yyyyMMMM'))">
<xsl:sort select="publicationDate" order="descending"/>
<xsl:sort select="@sortOrder" data-type="number" order="ascending" />
<div style="margin-left:10px;">
<div style="width:60px; float:left;"><xsl:value-of select="umbraco.library:FormatDateTime(publicationDate,'M/d/yy')"/></div>
<div style="width:24px; float:left;">
<xsl:if test="string(videoURL) != ''">
<xsl:value-of select="Designit.VideoEmbed:VideoEmbedInLightBox(videoURL, headline, $videoHeight, $videoWidth, $previewHeight, $previewWidth, 1)" disable-output-escaping="yes"/>
</xsl:if>
</div>
<div style="width:24px; float:left;">
<xsl:if test="string(photo) != ''">
<xsl:element name="a">
<xsl:attribute name="href">
<xsl:value-of select="umbraco.library:GetMedia(photo, 0)/umbracoFile"/>
</xsl:attribute>
<xsl:attribute name="title">
<xsl:value-of select="headline"/>
</xsl:attribute>
<xsl:attribute name="class">photoThumb</xsl:attribute>
<img src="/images/icons/picture.png" alt="View Photo" name="photo" width="16" height="16" hspace="0" vspace="0" border="0" id="photo" title="Click to view photo" />
</xsl:element>
</xsl:if>
</div>
<div style="margin-left:84px;">
<p>
<xsl:element name="a">
<xsl:if test="name() = 'LegalNewsHeadline'">
<xsl:if test="string(link/url-picker/new-window) = 'True'">
<xsl:attribute name="target">_blank</xsl:attribute>
</xsl:if>
<xsl:attribute name="href">
<xsl:choose>
<xsl:when test="link/url-picker/@mode = 'URL'">
<xsl:value-of select="link/url-picker/url"/>
</xsl:when>
<xsl:when test="link/url-picker/@mode= 'Content'">
<xsl:value-of select="umbraco.library:NiceUrl(link/url-picker/node-id)"/>
</xsl:when>
<xsl:when test="link/url-picker/@mode = 'Media'">
<xsl:value-of select="umbraco.library:GetMedia(link/url-picker/node-id,false())/umbracoFile"/>
</xsl:when>
<xsl:when test="link/url-picker/@mode = 'Upload'">
<xsl:value-of select="link/url-picker/url"/>
</xsl:when>
<xsl:otherwise></xsl:otherwise>
</xsl:choose>
</xsl:attribute>
</xsl:if>
<xsl:if test="name() = 'ArizonaAttorneyNewsCenterArticle'">
<xsl:attribute name="href">
<xsl:value-of select="umbraco.library:NiceUrl(@id)"/>
</xsl:attribute>
</xsl:if>
<xsl:value-of select="headline"/>
</xsl:element></p>
</div>
</div>
</xsl:for-each>
</div>
</xsl:for-each>
<br />
</xsl:for-each>
<script type="text/javascript">
$("a.photoThumb").fancybox({
'padding': 1,
'autoScale': true,
'transitionIn': 'none',
'transitionOut': 'none',
'hideOnOverlayClick': true,
'hideOnContentClick': true,
'titlePosition': 'inside',
'centerOnScroll': true,
'title': this.title
})
$.fancybox.resize;
</script>
</xsl:template>
</xsl:stylesheet>
Hi Connie,
Large chunk of code - hard job to "just paginate", but I've got something you can try:
I have created a "_PaginationHelper.xslt" file that should be suitable for this - currently it's on GitHub - you can get it here: _PaginationHelper.xslt
What you need to do is:
1. Include the helper with <xsl:include href="_PaginationHelper.xslt" /> (just add that in the bottom of the main XSLT file)
2. Take the chunk of HTML you're generating in the innermost for-each, and extract that to a separate template
3. Instead of the <xsl:for-each> you then collect the node ids that needs to be output, and put them in a "proxy" variable (we need to create a new sorted set because the nodes will otherwise render in document order).
4. Call the PaginateSelection template and send it your proxy to render a page of data
Something like this:
Now this may seem like a lot of hoopla - but that's because of two things: 1: Your XSLT has everything inside a single template which isn't the optimal scenario for my helper; and 2: We need to pre-sort the nodes because we can't specify sorting inside the select statement.
Hopefully you get to a point where something's working and we can take it from there :-)
/Chriztian
Close but not quite. This is giving me Prev/Next for each date instead of for the entire result set.
Also, the Prev/Next and page numbers render as a bulleted list.
Here is a simpler version of my original script without all the bells and whistles. This still has the grouping by year and then by month.
Here's a condensed chunk of how to do this (from this discussion on GitHub):
The thing to notice: When using a pre-sorted, the advanced grouping stuff is no longer necessary...
/Chriztian
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.