 | Sorts a list of XWiki objects by a given object property name |
| Type | Snippet |
| Developed by | Eduard Moraru |
| License | GNU Lesser General Public License 2.1 |
The problem with directly using $sorttool.sort(...) on a list of XWiki objects is that $sorttool expects the objects to have getters for the properties you want to sort on. However, XWiki objects don`t work that way and, instead, you have to do $object.getProperty(propertyname).value to get the actual property value.
To work around this problem, you can use the velocity macro below which supports sorting by a property name and allows multiple values for the sorted property.
{{velocity output='false'}}
#*
* Sort a list of XWiki objects using an property as comparator.
*
* @param inputObjects the list of XWiki objects to sort.
* @param propertyName the name of the XWiki object property to sort the inputObjects by. Multiple values for the same property are allowed.
* @param outputObjects the list where to append the sorted objects. This list must not be null and should be empty before calling the macro.
*#
#macro (sortXWikiObjectsList $inputObjects $propertyName $outputObjects)
#set ($objectsMap = {})
#foreach ($object in $inputObjects)
#set ($key = $object.getProperty($propertyName).value)
#set ($sameKeyObjects = $objectsMap.get($key))
#if (!$sameKeyObjects)
#set ($sameKeyObjects = [])
#set ($discard = $objectsMap.put($key, $sameKeyObjects))
#end
#set ($discard = $sameKeyObjects.add($object))
#end
#foreach ($key in $sorttool.sort($objectsMap.keySet()))
#set ($sameKeyObjects = $objectsMap.get($key))
#foreach ($sameKeyObject in $sameKeyObjects)
#set ($discard = $outputObjects.add($sameKeyObject))
#end
#end
#end
{{/velocity}}
Use case: Sort comment object in the page using the 'comment' property
{{velocity}}
#set ($objects = $doc.getObjects('XWiki.XWikiComments'))
#set ($sortedObjects = [])
##
#sortXWikiObjectsList($objects, 'comment', $sortedObjects)
## Print the result
#foreach ($object in $sortedObjects)
$object.getProperty('comment').value
#end
{{/velocity}}
Output: (assuming the comments contain each a single number in an scrambled order)
1
2
3
4
4
5
6