내 커뮤니티 업적 표시줄을 확대합니다.

Submissions are now open for the 2026 Adobe Experience Maker Awards.

Mark Solution

활동이 없어 이 대화는 잠겼습니다. 새 게시물을 작성해 주세요.

해결됨

How to get child pages of a component using sling model?

Avatar

Level 1

A developer is creating a custom component on the page and needs to list all the child pages of the root page. How to do that and what is the correct way to do that?

1 채택된 해결책 개

Avatar

정확한 답변 작성자:
Level 4

A good sample! except that it's better always to use try-with-resources as the resource resolver is of Closeable interface, and the ArrayList should be used instead of the default LinkedList only in limited cases when you need to update the list after filling it.

In addition from me, if you use those pages to build a list of links, you should check for other properties, for example, if the page is a redirect one, you should display the target page instead of found one, and also if you need to traverse no only first children, but a whole tree, I use this approach:

// public final class StreamUtils {

  public static Stream<Page> descendants(@Nullable final Page rootPage) {
    return Optional.ofNullable(rootPage).map(rootPage -> 
        Stream.concat(Stream.of(rootPage),
          StreamSupport.stream(Spliterators.spliteratorUnknownSize(rootPage.listChildren(),
              Spliterator.ORDERED), false)
            .flatMap(StreamUtils::descendants)))
      .orElse(Stream.empty());
  }

I have inlined some utility functions that I use to get it shorter, I hope I didn't brake it as I did it right here not in IDE  And then I use this function as:

final List<Page> allDescendantPages = StreamUtils.descendants(rootPage).collect(Collectors.toList());

 

원본 게시물의 솔루션 보기

2 답변 개

Avatar

Employee

Hi @nats ,

 

You can create a simple Sling Model class for your component to get the root page and access all the child pages of that root page. 
Sample code for java model class : 

package com.example.models;

import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceResolverFactory;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.sling.api.resource.Resource;
import com.day.cq.wcm.api.Page;
import com.day.cq.wcm.api.PageManager;

@Component(service = ChildPagesModel.class)
public class ChildPagesModel {

    @Reference
    private ResourceResolverFactory resourceResolverFactory;

    private List<Page> childPages;

    @PostConstruct
    protected void init() {
        childPages = new ArrayList<>();
        String rootPagePath = "/content/your-site-root"; // Replace this with the actual path to your root page

        ResourceResolver resourceResolver = null;
        try {
            // Get the ResourceResolver using ResourceResolverFactory
            resourceResolver = resourceResolverFactory.getServiceResourceResolver(null);
            PageManager pageManager = resourceResolver.adaptTo(PageManager.class);

            if (pageManager != null) {
                Page rootPage = pageManager.getPage(rootPagePath);
                if (rootPage != null) {
                    Iterator<Page> childIterator = rootPage.listChildren();
                    while (childIterator.hasNext()) {
                        Page childPage = childIterator.next();
                        childPages.add(childPage);
                    }
                }
            }
        } catch (Exception e) {
            // Handle exceptions
            e.printStackTrace();
        } finally {
            // Always close the ResourceResolver when done
            if (resourceResolver != null) {
                resourceResolver.close();
            }
        }
    }

    public List<Page> getChildPages() {
        return childPages;
    }
}

You can then use this model in your HTL code by doing 

<div data-sly-use.childPages="com.example.models.ChildPagesModel"> <ul> <li data-sly-repeat.child="${childPages}"> <a href="${child.path}.html">${child.title}</a> </li> </ul> </div>

 

Hope it helps!

Thanks,
Ayush

Avatar

정확한 답변 작성자:
Level 4

A good sample! except that it's better always to use try-with-resources as the resource resolver is of Closeable interface, and the ArrayList should be used instead of the default LinkedList only in limited cases when you need to update the list after filling it.

In addition from me, if you use those pages to build a list of links, you should check for other properties, for example, if the page is a redirect one, you should display the target page instead of found one, and also if you need to traverse no only first children, but a whole tree, I use this approach:

// public final class StreamUtils {

  public static Stream<Page> descendants(@Nullable final Page rootPage) {
    return Optional.ofNullable(rootPage).map(rootPage -> 
        Stream.concat(Stream.of(rootPage),
          StreamSupport.stream(Spliterators.spliteratorUnknownSize(rootPage.listChildren(),
              Spliterator.ORDERED), false)
            .flatMap(StreamUtils::descendants)))
      .orElse(Stream.empty());
  }

I have inlined some utility functions that I use to get it shorter, I hope I didn't brake it as I did it right here not in IDE  And then I use this function as:

final List<Page> allDescendantPages = StreamUtils.descendants(rootPage).collect(Collectors.toList());