How to get properties of "jcr:content" of nested page | Community
Skip to main content
New Participant
June 17, 2023
Solved

How to get properties of "jcr:content" of nested page

  • June 17, 2023
  • 2 replies
  • 1326 views

I have one parent page News. This parent page have several nested pages. I am trying to get properties of all jcr:content node of nested pages. But I am getting null response from getChild().

 

Here down is the snapshot of CRDXE Page. I need all properties of jcr:content

 

 

Here down is my code

 

NewsServiceImpl

 

@Component(service = NewsService.class
public class NewsServiceImpl implements NewsService {
    @Reference
    private QueryBuilder queryBuilder;
    
    @Override
    public Optional<Iterator<Resource>> getNews(SlingHttpServletRequest request, String searchPath) {
        Iterator<Resource> resourceIterator = null;
        Session session = request.getResourceResolver().adaptTo(Session.class);
        final Map<String, String> map = new HashMap<>();
        map.put("path", searchPath);
        map.put("1_property", "sling:resourceType");
        map.put("1_property.value", "xxx/components/page");

        Query query = queryBuilder.createQuery(PredicateGroup.create(map), session);
        SearchResult result = query.getResult();
        resourceIterator = result.getResources();
        return Optional.ofNullable(resourceIterator);
    }
    
}

 

Servlet

 

@Component(service = Servlet.class, property = { Constants.SERVICE_DESCRIPTION + "= Get All News",
        SLING_SERVLET_METHODS + "=GET", SLING_SERVLET_PATHS + "=/bin/news" })
public class NewsServlet extends SlingSafeMethodsServlet {

    @Reference
    transient NewsService newsService;

    protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("application/json;charset=utf-8");
        JsonArray resultArray = new JsonArray();
        Optional<Iterator<Resource>> isNews = newsService.getNews(request, request.getParameter("searchPath"));
        if (isNews.isPresent()) {
            Iterator<Resource> news = isNews.get();
            while (news.hasNext()) {
                Resource parentPageResource = news.next();
                        
                // is jcr:content present, Store response in resultArray
                if (parentPageResource.getChild("jcr:content") != null)
                {
                    resultArray.add(parentPageResource.getChild("jcr:content").getValueMap().toString());
                }
            }
        }
        response.getWriter().print(resultArray);
    }
}

 

This post is no longer active and is closed to new replies. Need help? Start a new post to ask your question.
Best answer by aanchal-sikka

@faeemazaz92 

 

The code needs a small correction.

 

Following query returns you jcr:content already. Try printing the node name to confirm. Thats why getChild() fails. 

        final Map<String, String> map = new HashMap<>();
        map.put("path", searchPath);
        map.put("1_property", "sling:resourceType");
        map.put("1_property.value", "xxx/components/page");

 

You should improve the query.

- type should be cq:Page 

1_property should be jcr:content:resourceType

Example: This will improve the performance of the query and will only return jcr:content nodes.

final Map<String, String> map = new HashMap<>(); map.put("path", searchPath); map.put("type", "cq:Page"); map.put("1_property", "jcr:content/sling:resourceType"); map.put("1_property.value", "xxx/components/page");

 

2 replies

joerghoh
Employee
June 18, 2023

Your code will not only read the direct child pages, but rather all child pages. If you just want the child pages of a specific type the straight-forward low-level implementation looks like this:

 

 

public Optional<Iterator<Resource>> getNews(SlingHttpServletRequest request, String searchPath) { Resource parentResource = request.getResourceResolver().getResource(searchPath); if (parentResource == null) { return Optional.empty(); } Iterator<Resource> allChildren = parentResource.getChildren(); List<Resource> result = new ArrayList<>(); while (allChildren.hasNext()) { Resource child = allChildren.next(); Resource jcrContent = child.getChild("jcr:content"); if (jcrContent != null) { if (jcrContent.isResourceType("xxx/components/page")) { result.add(child); } } } return result; }


But that is not how I would write it, because you are encoding too much implementation details. I would rather code like this:

public Iterator<Page> getNewsPages(Resource parentResource) { Stream<Resource> children = StreamSupport.stream(Spliterators.spliteratorUnknownSize(parentResource.GetChildren), Spliterator.ORDERED), false); List<Page result = children.map( r -> r.adaptTo(Page.class) .filter(Objects::nonNull) .filter( p -> { return Optional.ofNullable(p.getProperties()) .map(vm -> vm.get("sling:resourceType") .map(p -> p.equals("xxx/components/page") .get(); }) .collect(Collectors.toList()); return result; }


This goes via the "Page" API and avoids some of the implementation knowledge (although it would be great if the page API would have a "getResourceType()" method as well).

aanchal-sikka
aanchal-sikkaAccepted solution
New Participant
June 17, 2023

@faeemazaz92 

 

The code needs a small correction.

 

Following query returns you jcr:content already. Try printing the node name to confirm. Thats why getChild() fails. 

        final Map<String, String> map = new HashMap<>();
        map.put("path", searchPath);
        map.put("1_property", "sling:resourceType");
        map.put("1_property.value", "xxx/components/page");

 

You should improve the query.

- type should be cq:Page 

1_property should be jcr:content:resourceType

Example: This will improve the performance of the query and will only return jcr:content nodes.

final Map<String, String> map = new HashMap<>(); map.put("path", searchPath); map.put("type", "cq:Page"); map.put("1_property", "jcr:content/sling:resourceType"); map.put("1_property.value", "xxx/components/page");

 

Aanchal Sikka