List page children based on the reference hierarchy
Last modified by slauriere on 2026/06/02 17:54
| List the children of a given page using the reference hierarchy (as opposed to the one based on the parent field) |
| Type | Snippet |
| Category | Other |
| Developed by | |
| Rating | |
| License | GNU Lesser General Public License 2.1 |
Table of contents
Description
Using Solr
#set ($wikiId = $services.wiki.getCurrentWikiDescriptor().getId())
#set ($query = $services.query.createQuery('*', 'solr'))
#set ($fq = ['type:DOCUMENT', "wiki:$wikiId"])
#set ($rootSpaceName = 'Sandbox')
#set ($rootSpaceReference = $services.model.resolveSpace($rootSpaceName))
#set ($referenceChain = $rootSpaceReference.getReversedReferenceChain())
#set ($depth = $referenceChain.size())
#set ($depth = $mathtool.sub($depth, 2))
#set ($defaultPageName = $services.model.getEntityReference('DOCUMENT', 'default').name)
#if ($depth >= 0)
#set ($discard = $fq.add("space_facet:$depth/${rootSpaceName}."))
#set ($discard = $query.bindValue('fq', $fq))
#set ($discard = $query.bindValue('sort', 'title_sort asc'))
#set ($discard = $query.setLimit(1000))
#set ($searchResponse = $query.execute()[0])
#foreach ($result in $searchResponse.results)
#set ($reference = $services.model.resolveDocument($result.fullname))
#set ($name = $reference.name)
#if ($name == $defaultPageName)
## Page is not terminal
#set ($isDirectChild = $reference.getParent().getParent().equals($rootSpaceReference))
#else
## Page is terminal
#set ($isDirectChild = $reference.getParent().equals($rootSpaceReference))
#end
#if ($isDirectChild)
* [[$result.title_>>$result.fullname]]
#end
#end
#endRemarks:
- TODO: the rootSpaceName should be escaped
- The limit parameter should be adjusted if needed.
- Use
$fq = ['hidden:false', 'type:DOCUMENT']to retrieve only visible pages. - The list of fields that can be retrieved from a Solr Document is listed on the Solr Schema page.
Using the REST API
There are 2 REST resources that you can use to fetch the child pages:
- for top level pages: /wikis/{wikiName}/children
- for nested pages: /wikis/{wikiName}/spaces/{spaceName}[/spaces/{nestedSpaceName}]*/pages/{pageName}/children?hierarchy=nestedpages
See the REST API documentation for more information.
Using the PageHierarchy component
@Inject
@Named("nestedpages")
private PageHierarchy nestedPageHierarchy;
...
List<DocumentReference> topLevelPages = this.nestedPageHierarchy
.getChildren(wikiReference)
.withOffset(offset)
.withLimit(limit)
.matching(search)
.getDocumentReferences();
...
List<DocumentReference> childPages = this.nestedPageHierarchy
.getChildren(parentReference)
.withOffset(offset)
.withLimit(limit)
.matching(search)
.getDocumentReferences();Using the tree.nestedPages Component
In Velocity
#set ($id = $services.model.serialize($doc.documentReference))
#set ($count = $services.tree.nestedPages.getChildCount("document:${id}"))
#set ($children = $services.tree.nestedPages.getChildren("document:${id}", 0, $count))In Java
The sample code below can be used from a Component:
@Inject
@Named("nestedPages")
private org.xwiki.tree.Tree tree;
@Inject
@Named("entityTreeNodeId")
private org.xwiki.properties.converter.Converter<EntityReference> entityTreeNodeIdConverter;
public List<DocumentReference> getChildren(EntityReference reference) {
String name = entityTreeNodeIdConverter.convert(String.class, reference);
int childrenCount = tree.getChildCount(name);
List<String> children = tree.getChildren(name, 0, childrenCount);
List<DocumentReference> childReferences = new ArrayList<>();
for (String childNodeId : children) {
// FIXME: see how to convert a TreeNode id to a DocumentReference including for nested pages
// EntityReference childReference = entityTreeNodeIdConverter.convert(EntityReference.class, childName);
String childName = childNodeId.replace("document:", "");
DocumentReference childReference = documentReferenceResolver.resolve(childName);
childReferences.add(childReference);
}
return childReferences;
}