Skip to content

Instantly share code, notes, and snippets.

@stuartgpalmer
Last active June 29, 2018 14:55
Show Gist options
  • Save stuartgpalmer/964a1d950b7ca89d84ca5013b56984b2 to your computer and use it in GitHub Desktop.
Save stuartgpalmer/964a1d950b7ca89d84ca5013b56984b2 to your computer and use it in GitHub Desktop.
<data>
<all-products-paginated>
<pagination total-entries="42" total-pages="3" entries-per-page="18" current-page="1" />
<section id="8" handle="products">Products</section>
<entry id="486">
<title handle="issue-1">Issue 1</title>
<label handle="issue-1">Issue 1 </label>
<category>
<item id="282" handle="back-issues" section-handle="product-categories" section-name="Product categories">Back issues</item>
</category>
<price>3.75</price>
<image-1 size="7.08 MB" bytes="7425309" path="/uploads/product-images" type="image/png">
<filename>issue-1-cover-mockup.png</filename>
<meta creation="2018-06-15T11:33:44+01:00" width="2413" height="3400" />
</image-1>
</entry>
<entry id="487">
<title handle="issue-2">Issue 2</title>
<label handle="issue-2">Issue 2 </label>
<category>
<item id="282" handle="back-issues" section-handle="product-categories" section-name="Product categories">Back issues</item>
</category>
<price>3.75</price>
<image-1 size="6.16 MB" bytes="6463770" path="/uploads/product-images" type="image/png">
<filename>issue-2-cover-mockup.png</filename>
<meta creation="2018-06-15T11:33:38+01:00" width="2413" height="3400" />
</image-1>
</entry>
<entry id="488">
<title handle="issue-3">Issue 3</title>
<label handle="issue-3">Issue 3 </label>
<category>
<item id="282" handle="back-issues" section-handle="product-categories" section-name="Product categories">Back issues</item>
</category>
<price>3.75</price>
<image-1 size="202 KB" bytes="207556" path="/uploads/product-images" type="image/jpeg">
<filename>issue-3-cover-mock-up.jpg</filename>
<meta creation="2018-06-15T11:33:22+01:00" width="710" height="1000" />
</image-1>
</entry>
<entry id="489">
<title handle="issue-4">Issue 4</title>
<label handle="issue-4">Issue 4 </label>
<category>
<item id="282" handle="back-issues" section-handle="product-categories" section-name="Product categories">Back issues</item>
</category>
<price>3.75</price>
<image-1 size="4.35 MB" bytes="4564749" path="/uploads/product-images" type="image/png">
<filename>issue-4-cover-mockup.png</filename>
<meta creation="2018-06-15T11:33:31+01:00" width="2413" height="3400" />
</image-1>
</entry>
<entry id="490">
<title handle="issue-5">Issue 5</title>
<label handle="issue-5">Issue 5 </label>
<category>
<item id="282" handle="back-issues" section-handle="product-categories" section-name="Product categories">Back issues</item>
</category>
<price>3.75</price>
<image-1 size="6.10 MB" bytes="6400368" path="/uploads/product-images" type="image/png">
<filename>issue-5-magazine-cover.png</filename>
<meta creation="2018-06-15T11:33:02+01:00" width="2413" height="3400" />
</image-1>
</entry>
<entry id="491">
<title handle="issue-6">Issue 6</title>
<label handle="issue-6">Issue 6 </label>
<category>
<item id="282" handle="back-issues" section-handle="product-categories" section-name="Product categories">Back issues</item>
</category>
<price>3.75</price>
<image-1 size="4.01 MB" bytes="4201428" path="/uploads/product-images" type="image/png">
<filename>issue-6-cover-mock-up.png</filename>
<meta creation="2018-06-15T11:32:39+01:00" width="2413" height="3400" />
</image-1>
</entry>
<entry id="492">
<title handle="issue-7">Issue 7</title>
<label handle="issue-7">Issue 7 </label>
<category>
<item id="282" handle="back-issues" section-handle="product-categories" section-name="Product categories">Back issues</item>
</category>
<price>3.75</price>
<image-1 size="1.89 MB" bytes="1986991" path="/uploads/product-images" type="image/png">
<filename>issue-7-cover-mockup.png</filename>
<meta creation="2018-06-15T11:32:32+01:00" width="1000" height="1409" />
</image-1>
</entry>
<entry id="493">
<title handle="issue-8">Issue 8</title>
<label handle="issue-8">Issue 8 </label>
<category>
<item id="282" handle="back-issues" section-handle="product-categories" section-name="Product categories">Back issues</item>
</category>
<price>3.75</price>
<image-1 size="2.04 MB" bytes="2137804" path="/uploads/product-images" type="image/png">
<filename>issue-8-mockup.png</filename>
<meta creation="2018-06-15T11:32:25+01:00" width="1000" height="1409" />
</image-1>
</entry>
<entry id="494">
<title handle="issue-9">Issue 9</title>
<label handle="issue-9">Issue 9 </label>
<category>
<item id="282" handle="back-issues" section-handle="product-categories" section-name="Product categories">Back issues</item>
</category>
<price>3.75</price>
<image-1 size="3.66 MB" bytes="3832788" path="/uploads/product-images" type="image/png">
<filename>issue-9-cover-mockup.png</filename>
<meta creation="2018-06-15T11:32:19+01:00" width="2413" height="3400" />
</image-1>
</entry>
<entry id="495">
<title handle="issue-10">Issue 10</title>
<label handle="issue-10">Issue 10 </label>
<category>
<item id="282" handle="back-issues" section-handle="product-categories" section-name="Product categories">Back issues</item>
</category>
<price>3.75</price>
<image-1 size="3.93 MB" bytes="4117422" path="/uploads/product-images" type="image/png">
<filename>issue-10-cover-mockup.png</filename>
<meta creation="2018-06-15T11:32:10+01:00" width="2413" height="3400" />
</image-1>
</entry>
<entry id="496">
<title handle="issue-11">Issue 11</title>
<label handle="issue-11">Issue 11 </label>
<category>
<item id="282" handle="back-issues" section-handle="product-categories" section-name="Product categories">Back issues</item>
</category>
<price>3.75</price>
<image-1 size="4.67 MB" bytes="4895721" path="/uploads/product-images" type="image/png">
<filename>issue-11-cover.png</filename>
<meta creation="2018-06-15T11:32:04+01:00" width="2413" height="3400" />
</image-1>
</entry>
<entry id="497">
<title handle="issue-12">Issue 12</title>
<label handle="issue-12">Issue 12 </label>
<category>
<item id="282" handle="back-issues" section-handle="product-categories" section-name="Product categories">Back issues</item>
</category>
<price>3.75</price>
<image-1 size="4.37 MB" bytes="4585127" path="/uploads/product-images" type="image/png">
<filename>issue-12-cover.png</filename>
<meta creation="2018-06-15T11:31:56+01:00" width="2413" height="3400" />
</image-1>
</entry>
<entry id="499">
<title handle="issue-13">Issue 13</title>
<label handle="issue-13">Issue 13 </label>
<category>
<item id="282" handle="back-issues" section-handle="product-categories" section-name="Product categories">Back issues</item>
</category>
<price>3.75</price>
<image-1 size="1.57 MB" bytes="1650746" path="/uploads/product-images" type="image/png">
<filename>issue13cover.png</filename>
<meta creation="2018-06-15T11:31:44+01:00" width="2413" height="3400" />
</image-1>
</entry>
<entry id="500">
<title handle="issue-14">Issue 14</title>
<label handle="issue-14">Issue 14 </label>
<category>
<item id="282" handle="back-issues" section-handle="product-categories" section-name="Product categories">Back issues</item>
</category>
<price>3.75</price>
<image-1 size="4.86 MB" bytes="5100901" path="/uploads/product-images" type="image/png">
<filename>issue-14-cover.png</filename>
<meta creation="2018-06-15T11:31:33+01:00" width="2413" height="3400" />
</image-1>
</entry>
<entry id="501">
<title handle="issue-15">Issue 15</title>
<label handle="issue-15">Issue 15 </label>
<category>
<item id="282" handle="back-issues" section-handle="product-categories" section-name="Product categories">Back issues</item>
</category>
<price>3.75</price>
<image-1 size="7.42 MB" bytes="7783574" path="/uploads/product-images" type="image/png">
<filename>issue-15-cover.png</filename>
<meta creation="2018-06-15T11:31:26+01:00" width="2413" height="3400" />
</image-1>
</entry>
<entry id="506">
<title handle="issue-16">Issue 16</title>
<label handle="issue-16">Issue 16 </label>
<category>
<item id="282" handle="back-issues" section-handle="product-categories" section-name="Product categories">Back issues</item>
</category>
<price>3.75</price>
<image-1 size="4.47 MB" bytes="4689513" path="/uploads/product-images" type="image/png">
<filename>issue-16-cover.png</filename>
<meta creation="2018-06-15T11:31:17+01:00" width="2413" height="3400" />
</image-1>
</entry>
<entry id="507">
<title handle="issue-17">Issue 17</title>
<label handle="issue-17">Issue 17 </label>
<category>
<item id="282" handle="back-issues" section-handle="product-categories" section-name="Product categories">Back issues</item>
</category>
<price>3.75</price>
<image-1 size="3.36 MB" bytes="3525398" path="/uploads/product-images" type="image/png">
<filename>issue-17.png</filename>
<meta creation="2018-06-15T11:31:09+01:00" width="2413" height="3400" />
</image-1>
</entry>
<entry id="508">
<title handle="issue-18">Issue 18</title>
<label handle="issue-18">Issue 18 </label>
<category>
<item id="282" handle="back-issues" section-handle="product-categories" section-name="Product categories">Back issues</item>
</category>
<price>3.75</price>
<image-1 size="4.77 MB" bytes="5003120" path="/uploads/product-images" type="image/png">
<filename>issue-18-cover-mockup.png</filename>
<meta creation="2018-06-15T11:30:57+01:00" width="2413" height="3400" />
</image-1>
</entry>
</all-products-paginated>
</data>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:template match="data">
<xsl:call-template name="pagination">
<xsl:with-param name="pagination" select="all-products-paginated/pagination" />
<xsl:with-param name="pagination-url" select="concat($root,$current-path,'/','?p=$')" />
<xsl:with-param name="label-next" select="'&gt;'" />
<xsl:with-param name="label-previous" select="'&lt;'" />
</xsl:call-template>
</xsl:template>
<xsl:template name="pagination">
<xsl:param name="pagination" />
<xsl:param name="pagination-url" />
<xsl:param name="show-range" select="3" />
<xsl:param name="show-navigation" select="true()" />
<xsl:param name="show-rotation" select="false()" />
<xsl:param name="label-next" select="'&#187;'" />
<xsl:param name="label-previous" select="'&#171;'" />
<xsl:param name="class-pagination" select="'pagination'" />
<xsl:param name="class-page" select="'page'" />
<xsl:param name="class-next" select="'pagination-next'" />
<xsl:param name="class-previous" select="'pagination-previous'" />
<xsl:param name="class-selected" select="'selected'" />
<xsl:param name="class-ellipsis" select="'ellipsis'" />
<xsl:param name="class-disabled" select="'disabled'" />
<!-- Only show pagination if there are more than one page -->
<xsl:if test="$pagination/@total-pages &gt; 1">
<!-- Adjust range based on total page iterations -->
<xsl:variable name="range">
<xsl:choose>
<xsl:when test="$show-range &lt; 3">3</xsl:when>
<xsl:when test="$show-range &lt; $pagination/@total-pages">
<xsl:value-of select="$show-range" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$pagination/@total-pages - 1" />
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<!-- Current page -->
<xsl:variable name="page-current">
<xsl:choose>
<xsl:when test="$pagination/@current-page = ''">1</xsl:when>
<xsl:otherwise><xsl:value-of select="$pagination/@current-page" /></xsl:otherwise>
</xsl:choose>
</xsl:variable>
<!-- Previous page -->
<xsl:variable name="page-previous">
<xsl:choose>
<xsl:when test="$page-current = 1"><xsl:value-of select="$pagination/@total-pages" /></xsl:when>
<xsl:otherwise><xsl:value-of select="$page-current - 1" /></xsl:otherwise>
</xsl:choose>
</xsl:variable>
<!-- Next page -->
<xsl:variable name="page-next">
<xsl:choose>
<xsl:when test="$page-current = $pagination/@total-pages">1</xsl:when>
<xsl:otherwise><xsl:value-of select="$page-current + 1" /></xsl:otherwise>
</xsl:choose>
</xsl:variable>
<!-- Last range of page number -->
<xsl:variable name="range-last">
<xsl:value-of select="$pagination/@total-pages - $range + 1" />
</xsl:variable>
<!-- First page -->
<xsl:variable name="page-first">
<xsl:choose>
<xsl:when test="$page-current &gt;= 1 and $page-current &lt; $range">
<xsl:text>1</xsl:text>
</xsl:when>
<xsl:when test="$page-current &gt; $range-last and $page-current &lt;= $pagination/@total-pages">
<xsl:value-of select="$range-last" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$page-current - (floor($range div 2))" />
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<!-- Last page -->
<xsl:variable name="page-last">
<xsl:value-of select="$page-first + $range - 1" />
</xsl:variable>
<!-- Pagination -->
<ul class="{$class-pagination}">
<!-- Previous link -->
<xsl:if test="$show-navigation = true()">
<li>
<xsl:if test="$page-next = 2">
<xsl:attribute name="class">
<xsl:value-of select="$class-disabled" />
</xsl:attribute>
</xsl:if>
<a class="{$class-previous}">
<xsl:if test="$page-next != 2 or $show-rotation = true()">
<xsl:attribute name="href">
<xsl:call-template name="pagination-url-replace">
<xsl:with-param name="string" select="$pagination-url" />
<xsl:with-param name="search" select="'$'" />
<xsl:with-param name="replace" select="string($page-previous)" />
</xsl:call-template>
</xsl:attribute>
</xsl:if>
<xsl:value-of select="$label-previous" />
</a>
</li>
</xsl:if>
<!-- Page range -->
<xsl:call-template name="pagination-numbers">
<xsl:with-param name="pagination-url" select="$pagination-url" />
<xsl:with-param name="page-first" select="$page-first" />
<xsl:with-param name="page-last" select="$page-last" />
<xsl:with-param name="page-current" select="$page-current" />
<xsl:with-param name="page-total" select="$pagination/@total-pages" />
<xsl:with-param name="class-page" select="$class-page" />
<xsl:with-param name="class-selected" select="$class-selected" />
<xsl:with-param name="class-ellipsis" select="$class-ellipsis" />
<xsl:with-param name="iterations" select="$page-last - $page-first" />
</xsl:call-template>
<!-- Next link -->
<xsl:if test="$show-navigation = true()">
<li>
<xsl:if test="$page-next = 1">
<xsl:attribute name="class">
<xsl:value-of select="$class-disabled" />
</xsl:attribute>
</xsl:if>
<a class="{$class-next}">
<xsl:if test="$page-next != 1 or $show-rotation = true()">
<xsl:attribute name="href">
<xsl:call-template name="pagination-url-replace">
<xsl:with-param name="string" select="$pagination-url" />
<xsl:with-param name="search" select="'$'" />
<xsl:with-param name="replace" select="string($page-next)" />
</xsl:call-template>
</xsl:attribute>
</xsl:if>
<xsl:value-of select="$label-next" />
</a>
</li>
</xsl:if>
</ul>
</xsl:if>
</xsl:template>
<!--
PAGINATION NUMBERS
Generate list of pages
-->
<xsl:template name="pagination-numbers">
<xsl:param name="pagination-url" />
<xsl:param name="page-first" />
<xsl:param name="page-last" />
<xsl:param name="page-current" />
<xsl:param name="page-total" />
<xsl:param name="class-page" />
<xsl:param name="class-selected" />
<xsl:param name="class-ellipsis" />
<xsl:param name="iterations" />
<!-- Page number -->
<xsl:variable name="page" select="$page-last - $iterations" />
<!-- Generate ellipsis at the beginning -->
<xsl:if test="$page = $page-first and $page-first &gt; 1">
<li>
<a class="{$class-page}">
<xsl:attribute name="href">
<xsl:call-template name="pagination-url-replace">
<xsl:with-param name="string" select="$pagination-url" />
<xsl:with-param name="search" select="'$'" />
<xsl:with-param name="replace" select="'1'" />
</xsl:call-template>
</xsl:attribute>
<xsl:text>1</xsl:text>
</a>
</li>
<xsl:if test="$page != 2">
<li class="{$class-ellipsis}">&#8230;</li>
</xsl:if>
</xsl:if>
<!-- Generate page -->
<li>
<xsl:if test="$page = $page-current">
<xsl:attribute name="class">
<xsl:value-of select="$class-selected" />
</xsl:attribute>
</xsl:if>
<a class="{$class-page}">
<xsl:attribute name="href">
<xsl:call-template name="pagination-url-replace">
<xsl:with-param name="string" select="$pagination-url" />
<xsl:with-param name="search" select="'$'" />
<xsl:with-param name="replace" select="string($page)" />
</xsl:call-template>
</xsl:attribute>
<xsl:value-of select="$page" />
</a>
</li>
<!-- Generate ellipsis at the end -->
<xsl:if test="$page = $page-last and $page-last &lt; $page-total">
<xsl:if test="$page != ($page-total - 1)">
<li class="{$class-ellipsis}">&#8230;</li>
</xsl:if>
<li>
<a class="{$class-page}">
<xsl:attribute name="href">
<xsl:call-template name="pagination-url-replace">
<xsl:with-param name="string" select="$pagination-url" />
<xsl:with-param name="search" select="'$'" />
<xsl:with-param name="replace" select="string($page-total)" />
</xsl:call-template>
</xsl:attribute>
<xsl:value-of select="$page-total" />
</a>
</li>
</xsl:if>
<!-- Generate next page number -->
<xsl:if test="$iterations &gt; 0">
<xsl:call-template name="pagination-numbers">
<xsl:with-param name="pagination-url" select="$pagination-url" />
<xsl:with-param name="page-first" select="$page-first" />
<xsl:with-param name="page-last" select="$page-last" />
<xsl:with-param name="page-current" select="$page-current" />
<xsl:with-param name="page-total" select="$page-total" />
<xsl:with-param name="class-page" select="$class-page" />
<xsl:with-param name="class-selected" select="$class-selected" />
<xsl:with-param name="class-ellipsis" select="$class-ellipsis" />
<xsl:with-param name="iterations" select="$iterations - 1" />
</xsl:call-template>
</xsl:if>
</xsl:template>
<!--
PAGINATION URL
Replace wildcard by page number
-->
<xsl:template name="pagination-url-replace">
<xsl:param name="string" />
<xsl:param name="search" />
<xsl:param name="replace" />
<xsl:value-of select="concat(substring-before($string, $search), $replace, substring-after($string, $search))" />
</xsl:template>
</xsl:stylesheet>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment