Skip to content

Instantly share code, notes, and snippets.

@ijy
Created September 15, 2013 16:24
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ijy/6572186 to your computer and use it in GitHub Desktop.
Save ijy/6572186 to your computer and use it in GitHub Desktop.
Modified pagination utility for Symphony CMS to (optionally) allow it to work with other query string parameters. Add the pagination utiltity, import it into your page template, pass in required (and optional) paramaters, style with CSS. Examples included.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!--
Name: DATA SOURCE PAGINATION
Version: 1.5
Author: Nick Dunn <nick@nick-dunn.co.uk>,
Nils Hörrmann <post@nilshoerrmann.de>,
Ian Young <i.young@me.com>
URL: https://gist.github.com/ijy/6572186
Required Parameters:
pagination: XPath to the data source pagination element
pagination-url: URL used for page links, use $ as placeholder for the page number
Optional Parameters:
show-range: Number of pages until the list gets shortened, defaults to 5
show-navigation: Show previous or next links, defaults to true()
show-rotation: Add rotation to next and previous links, defaults to false()
label-next: Custom "Next" label text
label-previous: Custom "Previous" label text
query-string: Include the current query string minus pagination
Class options:
class-pagination: Class used for the pagination list
class-page: Class used for page items
class-next: Class used for the next page link
class-previous: Class used for the previous page link
class-selected: Class used for the selected page
class-disabled: Class used for the disabled page link
-->
<xsl:template name="pagination">
<xsl:param name="query-string" />
<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">
<!-- If there are query string params include them -->
<xsl:call-template name="query-string-check">
<xsl:with-param name="url-params" select="$query-string" />
</xsl:call-template>
<!-- Search & replace the page number. (Append to the query string if present) -->
<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="query-string" select="$query-string" />
<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">
<!-- If there are query string params include them -->
<xsl:call-template name="query-string-check">
<xsl:with-param name="url-params" select="$query-string" />
</xsl:call-template>
<!-- Search & replace the page number. (Append to the query string if present) -->
<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="query-string" />
<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">
<!-- If there are query string params include them -->
<xsl:call-template name="query-string-check">
<xsl:with-param name="url-params" select="$query-string" />
</xsl:call-template>
<!-- Search & replace the page number. (Append to the query string if present) -->
<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">
<!-- If there are query string params include them -->
<xsl:call-template name="query-string-check">
<xsl:with-param name="url-params" select="$query-string" />
</xsl:call-template>
<!-- Search & replace the page number. (Append to the query string if present) -->
<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">
<!-- If there are query string params include them -->
<xsl:call-template name="query-string-check">
<xsl:with-param name="url-params" select="$query-string" />
</xsl:call-template>
<!-- Search & replace the page number. (Append to the query string if present) -->
<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="query-string" select="$query-string" />
<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>
<!--
QUERY STRING CHECK
Check for existing query string and output
-->
<xsl:template name="query-string-check">
<xsl:param name="url-params" />
<xsl:if test="$url-params != ''" >
<xsl:value-of select="$url-params" />
</xsl:if>
</xsl:template>
</xsl:stylesheet>
<!-- Save the string value of current-query-string minus pagination (with CDATA stripped) -->
<xsl:variable name="url-params">
<xsl:value-of select="substring-before(//current-query-string, 'p=')" />
</xsl:variable>
<xsl:call-template name="pagination">
<xsl:with-param name="pagination" select="//data-source-name/pagination" />
<xsl:with-param name="pagination-url" select="'p=$'" />
<xsl:with-param name="query-string" select="$url-params" />
<xsl:with-param name="show-range" select="'5'" />
<xsl:with-param name="label-previous" select="'Previous'" />
<xsl:with-param name="label-next" select="'Next'" />
</xsl:call-template>
/* Pagination
================================================*/
ul.pagination {
margin: 0;
}
ul.pagination li {
list-style-type: none;
font-size: 1.2em;
display: inline;
}
ul.pagination li a {
display: block;
float: left;
padding: 2px 8px;
margin-right: 3px;
color: #777;
}
ul.pagination li span {
float: left;
margin-right: 4px;
}
ul.pagination li a.page {
background-color: #9FA19F;
color: #ddd;
font-weight: bold;
}
ul.pagination li a.page:hover {
text-decoration: none;
color: #fff;
}
ul.pagination li.selected a.page {
background-color: #545C5F;
color: #fff;
}
ul.pagination li.disabled a {
color: #ddd;
cursor: default;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment