Hi AdobeTeam,
I have created
- a custom resource type which is inherited from the core resource type "core/wcm/components/navigation/v2/navigation",
- the respective Sling model exporter which contains the following annotation:
@Self@Via(type = ResourceSuperType.class)
private Navigation navigation;
I would like to get the json Sling model for my custom resource generated by calling it from a SlingAllMethodsServlet which gets the navigation attributes in query parameters. To do that I created a SyntheticResource (i.e. ValueMapResource) where I pass some Navigation parameters for the model.
Doing it like this:
...
Views
Replies
Total Likes
Hi @pnagy ,
To resolve the currentPage and currentStyle variables in your custom model when using a SyntheticResource, you need to ensure that these variables are set correctly in the Sling bindings. These variables are typically set by the Sling scripting context when rendering a page in AEM, but when you create a synthetic resource programmatically, you need to set them manually.
Here's how you can achieve this:
Set the Script Variables in the Request: Add the currentPage and currentStyle variables to the request attributes or the Sling bindings before creating the model.
Use SlingBindings to set variables: You can use the SlingBindings class to set the necessary variables.
Create and set up the SyntheticResource:
ValueMap properties = new ValueMapDecorator(new HashMap<>());
properties.put(PN_NAVIGATION_ROOT, navigationRoot);
properties.put(PN_STRUCTURE_START, structureStart);
Resource syntheticResource = new ValueMapResource(resourceResolver, "/syntheticResourcePath", RESOURCE_TYPE, properties);
Set up the currentPage and currentStyle variables:
Page currentPage = resourceResolver.adaptTo(PageManager.class).getPage("/path/to/current/page");
Style currentStyle = currentPage.getContentResource().adaptTo(Style.class);
Set these variables in the SlingBindings and the request:
SlingBindings bindings = (SlingBindings) request.getAttribute(SlingBindings.class.getName());
if (bindings == null) {
bindings = new SlingBindings();
request.setAttribute(SlingBindings.class.getName(), bindings);
}
bindings.put("currentPage", currentPage);
bindings.put("currentStyle", currentStyle);
Retrieve the model using the ModelFactory:
UeNavigationModel model = modelFactory.getModelFromWrappedRequest(request, syntheticResource, UeNavigationModel.class);
Here's how all these pieces fit together:
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.api.resource.ValueMapDecorator;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.models.factory.ModelFactory;
import com.adobe.cq.sightly.WCMUsePojo;
import com.day.cq.wcm.api.Page;
import com.day.cq.wcm.api.PageManager;
import com.day.cq.wcm.api.designer.Style;
import org.apache.sling.models.annotations.via.ResourceSuperType;
import org.apache.sling.api.scripting.SlingBindings;
import java.util.HashMap;
// In your SlingAllMethodsServlet
public void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws IOException {
ResourceResolver resourceResolver = request.getResourceResolver();
ValueMap properties = new ValueMapDecorator(new HashMap<>());
properties.put(PN_NAVIGATION_ROOT, navigationRoot);
properties.put(PN_STRUCTURE_START, structureStart);
Resource syntheticResource = new ValueMapResource(resourceResolver, "/syntheticResourcePath", RESOURCE_TYPE, properties);
Page currentPage = resourceResolver.adaptTo(PageManager.class).getPage("/path/to/current/page");
Style currentStyle = currentPage.getContentResource().adaptTo(Style.class);
SlingBindings bindings = (SlingBindings) request.getAttribute(SlingBindings.class.getName());
if (bindings == null) {
bindings = new SlingBindings();
request.setAttribute(SlingBindings.class.getName(), bindings);
}
bindings.put("currentPage", currentPage);
bindings.put("currentStyle", currentStyle);
UeNavigationModel model = modelFactory.getModelFromWrappedRequest(request, syntheticResource, UeNavigationModel.class);
// Use the model as needed
}
SlingBindings: By creating or retrieving the SlingBindings object from the request and setting the currentPage and currentStyle attributes, you ensure that these variables are available to your Sling model.
ResourceSuperType: The @Via(type = ResourceSuperType.class) annotation correctly resolves the parent model (Navigation in this case) and sets up its dependencies if they are available in the Sling bindings or request attributes.
This setup ensures that when the model is instantiated, it can access the currentPage and currentStyle variables, avoiding the null issue in the parent Navigation model.
Views
Replies
Total Likes
Thanks a lot @HrishikeshKa for the detailed suggestion, this is the same approach I tried TBH.
The issue is that the request will be wrapped into a ResourceOverridingRequestWrapper before resolving to a model. That wrapped request has this logic:
Views
Replies
Total Likes
I think I have the good question which I don't know the answer yet for:
what s the prerequisite for com.day.cq.wcm.scripting.impl.WCMBindingsValuesProvider so that it can calculate "currentStyle" for in the SlingBindings?
Views
Replies
Total Likes
Can someone help with finding the source / jar for com.day.cq.wcm.scripting.impl.WCMBindingsValuesProvider ?
The "currentPage" property will be set in SlingBindings when I set a page resource path for the ValueMapResource but the currentStyle is yet empty. I would like to understand what is missing to get it calculated.
Views
Replies
Total Likes
Views
Likes
Replies
Views
Likes
Replies