Sort JCR Nodes
Available since version 4.12.0
This feature is not AEM as a Cloud Service compatible, and can only be used on AEM 6.5.
Purpose
Sort Nodes is a tool to sort child nodes by node name or jcr:title, for example, to alphabetize pages or tags in Sites Admin .
How to Use
AEM GUI
In AEM, navigate to the Tools > ACS AEM Commons > Sort JCR Nodes
In the path field, enter the the target path to sort. You can choose whether to sort by node name (default) or by jcr:title and whether sort should be case-sensitive.
HTTP POST
The code in ACS Commons extends the Sling POST Servlet with the acs-commons:sortNodes
operation which makes the sorting operation script-friendly.
sort children of /content/someFolder by node name, case-insensitive (defaults)
curl -F":operation=acs-commons:sortNodes" http://localhost:4502/content/someFolder
sort children of /content/someFolder by jcr:title, case-sensitive
curl -F":operation=acs-commons:sortNodes" \
-F":sorterName=byTitle" \
-F":caseSensitive=true" \
http://localhost:4502/content/someFolder
Request Parameters
:sorterName
To select the actual sorter to execute, the :sorterName
request parameter is used. Out of the box, the SortNodesOperation supports the following sorters:
Sorter | Description |
---|---|
byName |
Sort nodes by node name |
byTitle |
Sort nodes by jcr:title. The code will use the value of the jcr:title property of the underlying node or of it’s jcr:content child node if it exists or default to node name of jcr:title was not found |
:caseSensitive
Optional boolean parameter to control whether sort should be case sensitive (default: false
), e.g.
+ /content/someFolder
- a
- A
- b
- B
You can turn it off by setting the -F":caseSensitive=true"
request parameter and the order will change to
+ /content/someFolder
- A
- B
- a
- b
:nonHierarchyFirst
Optional boolean parameter to control whether sort should move non-hierarchy nodes to the top (default: true
)
The default value is true
which means jcr:content, rep:policy and such will be sorted first followed by other, hierarchy nodes like cq:Page, e.g.
+ /content/someFolder
- jcr:content // non-hierarchy
- rep:policy // non-hierarchy
- a // cq:Page
- b // cq:Page
- c // cq:Page
- p // cq:Page
You can turn it off by setting the -F":nonHierarchyFirst=false"
parameter
which will switch the mode to sort nodes regardless if they are nt:hierarchyNode
or not
+ /content/someFolder
- a // cq:Page
- b // cq:Page
- c // cq:Page
- jcr:content // non-hierarchy
- p // cq:Page
- rep:policy // non-hierarchy
:respectNumbers
Optional boolean parameter to control whether numbers should be sorted first followed by alphabetical values (default: false
)
The default value is false
which means all values will be sorted alphabetically, e.g.
+ /content/someFolder
- 1
- 1-A
- 101
- 11
- 2-B
- 20
- 200
- 22
- aaa
- bbb
With :respectNumbers=true
numbers will be sorted first followed by alphabetical values:
+ /content/someFolder
- 1
- 11
- 20
- 22
- 101
- 200
- 1-A
- 2-B
- aaa
- bbb
Extending SortNodesOperation
OSGi services of the com.adobe.acs.commons.sorter.NodeSorter type can be used to implement new node sorters. For example, to register a sorter by sling:resourceType deploy the service below:
import com.adobe.acs.commons.sorter.NodeSorter;
import org.apache.jackrabbit.commons.JcrUtils;
import org.osgi.service.component.annotations.Component;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.servlet.http.HttpServletRequest;
import java.util.Comparator;
@Component
public class ResourceTypeSorter implements NodeSorter {
/**
* A unique name which will be used to find the actual sorter by the
* <code>:sorterName</code> request parameter
*/
public String getName() {
return "resourceType";
}
/**
* The label that will appear in the 'Select Sorter' drop-down in UI
*/
public String getLabel() {
return "By resource type";
}
/**
* Create a comparator to sort nodes.
* Implementations can read additional parameters from request, e.g.
* whether search should be case-sensitive, ascending/descending, etc.
*/
@Override
public Comparator<Node> createComparator(HttpServletRequest request) {
return (n1, n2) -> {
try {
String val1 = JcrUtils.getStringProperty(n1, "jcr:content/sling:resourceType", "");
String val2 = JcrUtils.getStringProperty(n2, "jcr:content/sling:resourceType", "");
return val1.compareTo(val2);
} catch (RepositoryException e) {
return 0;
}
};
}
}
Once the ResourceTypeSorter service is deployed you should be able to select the new sorter in the UI:
or pass it as -F":sorterName=resourceType"
request parameter in curl:
curl -F":operation=acs-commons:sortNodes" -F":sorterName=resourceType" \
http://localhost:4502/content/we-retail