Skip to content

Commit

Permalink
Merge pull request #19 from greystate/custom-sort
Browse files Browse the repository at this point in the history
Implements the custom sorting idea from #18
  • Loading branch information
greystate committed Sep 17, 2013
2 parents 7ad0e3e + dd0d170 commit d3ad718
Show file tree
Hide file tree
Showing 11 changed files with 140 additions and 64 deletions.
4 changes: 3 additions & 1 deletion Release Notes.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Release Notes

* v0.8.6: Pagination Helper updated to 1.4
* v0.8.5: Pagination Helper updated to 1.3
* v0.8.4: Pagination Helper updated to 1.2
* v0.8.3: Calendar Helper updated to 1.1, Media Helpers updated to 1.3
Expand All @@ -22,7 +23,8 @@

## Pagination Helper

* v1.3: Support sorting with pagination by way of the `sortBy` parameter
* v1.4: Support custom sorting in pagination
* v1.3: Support sorting pagination by way of the `sortBy` parameter
* v1.2: Use `pageLinksBeside` to specify number of links to show before & after current in the Pager
* v1.1: `perPage` parameter can now be overridden

Expand Down
2 changes: 1 addition & 1 deletion dist/xslt/_CalendarHelper.xslt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<!-- You need to set this to the name of the property/attribute on your event nodes that holds the "date" value -->
<!ENTITY eventDate "eventStartDateTime">
]>
<?umbraco-package XSLT Helpers v0.8.5 - CalendarHelper v1.1?>
<?umbraco-package XSLT Helpers v0.8.6 - CalendarHelper v1.1?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:umb="urn:umbraco.library" xmlns:freeze="http://xmlns.greystate.dk/2012/freezer" xmlns:date="urn:Exslt.ExsltDatesAndTimes" xmlns:make="urn:schemas-microsoft-com:xslt" version="1.0" exclude-result-prefixes="umb date make freeze">

<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
Expand Down
2 changes: 1 addition & 1 deletion dist/xslt/_GroupingHelper.xslt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0"?>
<?umbraco-package XSLT Helpers v0.8.5 - GroupingHelper v1.0?>
<?umbraco-package XSLT Helpers v0.8.6 - GroupingHelper v1.0?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<!-- 'Groupify' template -->
Expand Down
2 changes: 1 addition & 1 deletion dist/xslt/_MediaHelper.xslt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
Enables simple retrieval of media by handling the GetMedia() call and error-checking
-->
<?umbraco-package XSLT Helpers v0.8.5 - MediaHelper v1.3?>
<?umbraco-package XSLT Helpers v0.8.6 - MediaHelper v1.3?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:umb="urn:umbraco.library" xmlns:freeze="http://xmlns.greystate.dk/2012/freezer" xmlns:get="urn:Exslt.ExsltMath" xmlns:make="urn:schemas-microsoft-com:xslt" xmlns:cropup="urn:Eksponent.CropUp" version="1.0" exclude-result-prefixes="umb get make cropup freeze">

<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
Expand Down
2 changes: 1 addition & 1 deletion dist/xslt/_NavigationHelper.xslt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<!-- You can change this to suit your environment -->
<!ENTITY subPages "*[@isDoc][not(@template = 0) and not(umbracoNaviHide = 1)]">
]>
<?umbraco-package XSLT Helpers v0.8.5 - NavigationHelper v1.1?>
<?umbraco-package XSLT Helpers v0.8.6 - NavigationHelper v1.1?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:umb="urn:umbraco.library" xmlns:freeze="http://xmlns.greystate.dk/2012/freezer" version="1.0" exclude-result-prefixes="umb freeze">

<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
Expand Down
75 changes: 47 additions & 28 deletions dist/xslt/_PaginationHelper.xslt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0"?>
<?umbraco-package XSLT Helpers v0.8.5 - PaginationHelper v1.3?>
<?umbraco-package XSLT Helpers v0.8.6 - PaginationHelper v1.4?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:umb="urn:umbraco.library" xmlns:str="urn:Exslt.ExsltStrings" xmlns:make="urn:schemas-microsoft-com:xslt" version="1.0" exclude-result-prefixes="umb str make">

<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
Expand Down Expand Up @@ -269,36 +269,55 @@
<xsl:param name="sortBy"/>

<nodes>
<xsl:if test="normalize-space($sortBy)">
<xsl:variable name="sortNode">
<xsl:value-of select="substring-before($sortBy, ' ')"/>
<xsl:if test="not(contains($sortBy, ' '))">
<xsl:value-of select="$sortBy"/>
</xsl:if>
</xsl:variable>
<xsl:variable name="sortDirection">
<xsl:value-of select="substring-after($sortBy, ' ')"/>
<xsl:if test="not(contains($sortBy, ' '))">
<xsl:value-of select="'ASC'"/>
</xsl:if>
</xsl:variable>
<xsl:variable name="direction" select="translate(concat($sortDirection, 'ending'), 'ACDES', 'acdes')"/>
<xsl:choose>
<xsl:when test="starts-with($sortNode, '@')">
<xsl:apply-templates select="$selection" mode="presort">
<xsl:sort select="@*[name() = substring-after($sortNode, '@')]" data-type="text" order="{$direction}"/>
</xsl:apply-templates>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="$selection" mode="presort">
<xsl:sort select="*[name() = $sortNode]" data-type="text" order="{$direction}"/>
</xsl:apply-templates>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
<xsl:choose>
<xsl:when test="$sortBy = '$CUSTOM'">
<xsl:call-template name="customSort">
<xsl:with-param name="selection" select="$selection"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="normalize-space($sortBy)">
<xsl:variable name="sortNode">
<xsl:value-of select="substring-before($sortBy, ' ')"/>
<xsl:if test="not(contains($sortBy, ' '))">
<xsl:value-of select="$sortBy"/>
</xsl:if>
</xsl:variable>
<xsl:variable name="sortDirection">
<xsl:value-of select="substring-after($sortBy, ' ')"/>
<xsl:if test="not(contains($sortBy, ' '))">
<xsl:value-of select="'ASC'"/>
</xsl:if>
</xsl:variable>
<xsl:variable name="direction" select="translate(concat($sortDirection, 'ending'), 'ACDES', 'acdes')"/>
<xsl:choose>
<xsl:when test="starts-with($sortNode, '@')">
<xsl:apply-templates select="$selection" mode="presort">
<xsl:sort select="@*[name() = substring-after($sortNode, '@')]" data-type="text" order="{$direction}"/>
</xsl:apply-templates>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="$selection" mode="presort">
<xsl:sort select="*[name() = $sortNode]" data-type="text" order="{$direction}"/>
</xsl:apply-templates>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
</xsl:choose>
</nodes>
</xsl:template>

<!--
This is the template that gets called when you ask for custom sorting.
It should just apply templates to the $selection parameter in "presort" mode,
and of course add a special sort element or more to accomplish the task.
-->
<xsl:template name="customSort">
<xsl:param name="selection"/>
<xsl:apply-templates select="$selection" mode="presort">
<xsl:sort select="." data-type="text" order="ascending"/>
</xsl:apply-templates>
</xsl:template>

<xsl:template match="*" mode="presort">
<nodeId><xsl:value-of select="generate-id()"/></nodeId>
</xsl:template>
Expand Down
25 changes: 23 additions & 2 deletions paginationhelper/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ Sometimes, the data you want to paginate is actually also being sorted when rend
</xsl:apply-templates>
```

The problem with introducing pagination here, is that most often you get the pagination happening *before* sorting, but you really want to *sort* the results first and then perform the pagination. For that you use the `sortBy` parameter:
The problem with introducing pagination here, is that you'll get the pagination happening *before* sorting, but you really want to *sort* the results first and then perform the pagination. For that you use the `sortBy` parameter:

```xslt
<xsl:call-template name="PaginateSelection">
Expand All @@ -76,7 +76,28 @@ The problem with introducing pagination here, is that most often you get the pag

*Note that it's a string combining the name of the element or attribute to sort by and the direction (`ASC` or `DESC`), separated by a space. `ASC` is the default so you don't even need to specify the direction, unless it's `DESC`.*

It won't cover every scenario, e.g. it doesn't do numerical sorting yet, and you can only sort by a single element/attribute, where the element has to be a direct child of the node being sorted. Still, this should cover **a lot** of use cases.
It won't cover every scenario, e.g. it doesn't do numerical sorting, and you can only sort by a single element/attribute, where the element has to be a direct child of the node being sorted. Still, this should cover **a lot** of use cases.

### Advanced sorting

Because XSLT allows for some very special sorting (e.g., sorting by a substring of a value or the combined value of two or more values), there need to be a way to support this, so by sending the string **'$CUSTOM'** into the `sortBy` parameter, the helper will execute a named template (**"customSort"**) to perform the sorting, so in that one you can just paste your existing sort statements, e.g.:

```xslt
<xsl:call-template name="PaginateSelection">
<xsl:with-param name="selection" select="$currentPage/Textpage" />
<xsl:with-param name="sortBy" select="'$CUSTOM'" />
</xsl:call-template>
...
<xsl:template name="customSort">
<xsl:param name="selection" />
<xsl:apply-templates select="$selection" mode="preSort">
<xsl:sort select="substring-before(@nodeName, '-')" data-type="text" order="ascending" />
<xsl:sort select="substring-after(@nodeName, '-')" data-type="number" order="ascending" />
</xsl:apply-templates>
</xsl:template>
```

## QueryString options

Expand Down
73 changes: 46 additions & 27 deletions paginationhelper/_PaginationHelper.xslt
Original file line number Diff line number Diff line change
Expand Up @@ -289,36 +289,55 @@
<xsl:param name="sortBy" />

<nodes>
<xsl:if test="normalize-space($sortBy)">
<xsl:variable name="sortNode">
<xsl:value-of select="substring-before($sortBy, ' ')" />
<xsl:if test="not(contains($sortBy, ' '))">
<xsl:value-of select="$sortBy" />
</xsl:if>
</xsl:variable>
<xsl:variable name="sortDirection">
<xsl:value-of select="substring-after($sortBy, ' ')" />
<xsl:if test="not(contains($sortBy, ' '))">
<xsl:value-of select="'ASC'" />
</xsl:if>
</xsl:variable>
<xsl:variable name="direction" select="translate(concat($sortDirection, 'ending'), 'ACDES', 'acdes')" />
<xsl:choose>
<xsl:when test="starts-with($sortNode, '@')">
<xsl:apply-templates select="$selection" mode="presort">
<xsl:sort select="@*[name() = substring-after($sortNode, '@')]" data-type="text" order="{$direction}" />
</xsl:apply-templates>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="$selection" mode="presort">
<xsl:sort select="*[name() = $sortNode]" data-type="text" order="{$direction}" />
</xsl:apply-templates>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
<xsl:choose>
<xsl:when test="$sortBy = '&CustomSortTrigger;'">
<xsl:call-template name="customSort">
<xsl:with-param name="selection" select="$selection" />
</xsl:call-template>
</xsl:when>
<xsl:when test="normalize-space($sortBy)">
<xsl:variable name="sortNode">
<xsl:value-of select="substring-before($sortBy, ' ')" />
<xsl:if test="not(contains($sortBy, ' '))">
<xsl:value-of select="$sortBy" />
</xsl:if>
</xsl:variable>
<xsl:variable name="sortDirection">
<xsl:value-of select="substring-after($sortBy, ' ')" />
<xsl:if test="not(contains($sortBy, ' '))">
<xsl:value-of select="'ASC'" />
</xsl:if>
</xsl:variable>
<xsl:variable name="direction" select="translate(concat($sortDirection, 'ending'), 'ACDES', 'acdes')" />
<xsl:choose>
<xsl:when test="starts-with($sortNode, '@')">
<xsl:apply-templates select="$selection" mode="presort">
<xsl:sort select="@*[name() = substring-after($sortNode, '@')]" data-type="text" order="{$direction}" />
</xsl:apply-templates>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="$selection" mode="presort">
<xsl:sort select="*[name() = $sortNode]" data-type="text" order="{$direction}" />
</xsl:apply-templates>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
</xsl:choose>
</nodes>
</xsl:template>

<!--
This is the template that gets called when you ask for custom sorting.
It should just apply templates to the $selection parameter in "presort" mode,
and of course add a special sort element or more to accomplish the task.
-->
<xsl:template name="customSort">
<xsl:param name="selection" />
<xsl:apply-templates select="$selection" mode="presort">
<xsl:sort select="." data-type="text" order="ascending" />
</xsl:apply-templates>
</xsl:template>

<xsl:template match="*" mode="presort">
<nodeId><xsl:value-of select="generate-id()" /></nodeId>
</xsl:template>
Expand Down
2 changes: 2 additions & 0 deletions paginationhelper/entities.ent
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<!ENTITY % use.in.umbraco "IGNORE">
<!ENTITY % use.in.textmate "INCLUDE">

<!ENTITY CustomSortTrigger "$CUSTOM">

<![ %use.in.umbraco; [
<!ENTITY GetMediaFile "umb:GetMedia(., false())">
<!ENTITY GetMediaFolder "umb:GetMedia(., true())">
Expand Down
13 changes: 13 additions & 0 deletions paginationhelper/test/PaginationHelperSortedTest.xspec
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,19 @@
</x:scenario>

</x:scenario>

<x:scenario label="with sortBy '$CUSTOM'">
<x:call>
<x:param name="sortBy" select="'$CUSTOM'" />
</x:call>
<x:expect label="it should call the customSort template">
<p>Hugo Reyes</p>
<p>Jack Shepard</p>
<p>James Sawyer</p>
<p>Kate Austen</p>
<p>Penelope Widmore</p>
</x:expect>
</x:scenario>

</x:scenario>

Expand Down
4 changes: 2 additions & 2 deletions version.ent
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<!-- Current Versions -->
<!ENTITY packageVersion "0.8.5">
<!ENTITY packageVersion "0.8.6">
<!ENTITY XSLTHelpersVersionHeader "XSLT Helpers v&packageVersion;">
<!ENTITY MediaHelperVersion "1.3">
<!ENTITY PaginationHelperVersion "1.3">
<!ENTITY PaginationHelperVersion "1.4">
<!ENTITY GroupingHelperVersion "1.0">
<!ENTITY CalendarHelperVersion "1.1">
<!ENTITY NavigationHelperVersion "1.1">

0 comments on commit d3ad718

Please sign in to comment.