Expand my Community achievements bar.

SOLVED

Getting Sling Model for a page by JcrNodeResource

Avatar

Level 4

Hi,

I am building a REST endpoint which
1.) should execute some QueryBuilder queries based on the parameters passed to the endpoint,

2.) return the Sling models for the resources found by the QueryBuilder.

Point 1. is simple.
I have some concerns around point 2., where the hits returned by the QueryBuilder are JcrNodeResources and I would like to get Sling models for those resources (e.g. for a cq:Page with type "core/wcm/components/page/v3/page"). I have the idea to use the org.apache.sling.models.factory.ModelFactory -> getModelFromWrappedRequest method for this purpose like 
Page page = modelFactory.getModelFromWrappedRequest(request, createSyntheticResource(resource), Page.class);.
The method createSyntheticResource should create a ValueMapResource with the arguments for the Page to be created.

Does this make sense or is there an easier way to call Sling model exporter for a given JcrNodeResource?

Thanks,
Peter

1 Accepted Solution

Avatar

Correct answer by
Employee Advisor

It's possible to adapt a Resource directly to a com.day.cq.api.Page object.

View solution in original post

15 Replies

Avatar

Employee Advisor

Hi Peter,

 

do you know the exact model type, or has to this to be based on the resource type of the resource you are currently looking at?

Avatar

Level 4

Hi Jorg,

I know that the model type is core/wcm/components/page/v3/page based on the JCR content and its Sling model exporter is Adobe's internal PageImpl (but that internal class can't be referenced by the app code) so using Page.class, which is the model interface.

Avatar

Employee Advisor

 

resource.adaptTo(com.day.cq.api.Page.class);

 

should return a page object if that resource actually describes a page (and according to the screenshots, it does).

Avatar

Level 4

Even if the Page model is adaptable only for SlingHttpServletRequest like

@Model(adaptables = SlingHttpServletRequest.class

 ?

Avatar

Employee Advisor

 

You can adapt a resource to many things; and it's possible to adapt it both a Core Components SlingModel, but  also to a com.day.cq.api.Page object (you get a PageImpl object).

Avatar

Level 4

It returns null, unfortunately:
Screenshot 2025-01-18 at 14.01.15.png

Avatar

Community Advisor

Hi @pnagy 

You can't adapt resource to Page. You need to adpat to PageManager.

PageManager pageManager = resourceResolver.adaptTo(PageManager.class);
		String currentPage = Optional.ofNullable(pageManager).map(pm -> pm.getContainingPage(currentResource));

 

https://developer.adobe.com/experience-manager/reference-materials/6-4/javadoc/com/day/cq/wcm/api/Pa... 



Arun Patidar

Avatar

Correct answer by
Employee Advisor

It's possible to adapt a Resource directly to a com.day.cq.api.Page object.

Avatar

Community Advisor

Hi @Jörg_Hoh 
Yes you are right.

Resource can be adaptedTo Page but not ResourceReolver

ResourceResolver adapts to:PageManager
Resource adapts to: JCR-node-based resource and the node is a cq:Page (or cq:PseudoPage)



Arun Patidar

Avatar

Level 4

Thanks @arunpatidar , that really returns a Page.
Though the issue is, that I would like the page as Sling model exported component page, i.e. 

com.adobe.cq.wcm.core.components.models.page

but PageManager gives

com.day.cq.wcm.api.page.

I think I need to call like

modelFactory.getModelFromWrappedRequest(request, resource, Page.class)

but this will miss a "componentContext", as I debugged it in the ModelAdapterFactory. Just trying to figure out, why "componentContext" is null with my setup.

Avatar

Level 5

If you want to get the page object from the resource object, you should simply use adaptTo, provided the resource is a cq:Page.

Page page = resource.adaptTo(Page.class)

 

Refer - https://experienceleague.adobe.com/en/docs/experience-manager-65/content/implementing/developing/pla...

Avatar

Level 4

I tried that, but it does not work, it returns null:
Screenshot 2025-01-18 at 14.00.32.pngScreenshot 2025-01-18 at 14.00.45.pngScreenshot 2025-01-18 at 14.01.15.png

Avatar

Level 4

Not sure that's the root cause, but PageImpl has only the SlingHttpServletRequest as adaptable:

@Model(adaptables = SlingHttpServletRequest.class

Avatar

Community Advisor

@pnagy  If you have resource handy then just do resource.adaptTo(YourSlingModel.class)

Avatar

Level 4

That's still null. The only way I see is using modelFactory.getModelFromWrappedRequest.
That needs some tweaks though.
Screenshot 2025-01-22 at 9.57.59.png