Hello everyone,
I have recently run into an issue where I want to filter the pages that appear inside of a pathfield's selection dialog, to pages that have a specific resourceType (e.g. "products"). I have tried using a custom predicate to achieve this, but it does not seem to work (predicate gets registered as an OSGi service, but never fires).
Could anybody shine some light on this? Is a predicate even the correct way of approaching this? I will attach the code bellow nonetheless. We are using AEM as a Cloud Service.
Thanks in advance!
Predicate:
// Imports omitted
@Component(
service = Predicate.class,
property = { "predicate.name=allowed-article-predicate" }
)
public class AllowedArticlePredicate extends AbstractNodePredicate {
private static final Logger log = LoggerFactory.getLogger(AllowedArticlePredicate.class);
private static final String[] ALLOWED_RESOURCE_TYPES = {
CommonConstants.NEWS_RESOURCE_TYPE,
CommonConstants.EVENT_RESOURCE_TYPE,
CommonConstants.PRODUCT_RESOURCE_TYPE
};
@Override
public final boolean evaluate(final Node node) {
if (Objects.nonNull(node)) {
try {
if (node.isNodeType("cq:Page")) {
Node contentNode = node.getNode("jcr:content");
if (contentNode != null && contentNode.hasProperty("sling:resourceType")) {
String resourceType = contentNode.getProperty("sling:resourceType").getString();
for (String allowedType : ALLOWED_RESOURCE_TYPES) {
if (allowedType.equals(resourceType)) {
return true;
}
}
}
}
} catch (RepositoryException re) {
log.error("Unable to read node or property: {}", re.getMessage());
}
}
return false;
}
}
CQ Dialog:
<article
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/pathfield"
fieldLabel="Article Selection"
name="./article"
required="true"
showTitleInTree="true"
predicate="allowed-article-predicate"
multiple="false"
forceSelection="{Boolean}true"
/>
Solved! Go to Solution.
Topics help categorize Community content and increase your ability to discover relevant content.
Views
Replies
Total Likes
Hi @FotisMa1
Custom Java predicates don't work in AEM as a Cloud Service with Touch UI `pathfield`. They were supported in Classic UI or older AEM versions but are ignored now. Touch UI only supports predefined client-side filters—no custom OSGi predicate injection.
To filter pathfield options by sling:resourceType in AEM as a Cloud Service, custom Java predicates will not work.
1.Use autocomplete in the dialog:
<article
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/autocomplete"
fieldLabel="Select Product Page"
name="./article"
multiple="{Boolean}false"
required="{Boolean}true">
<datasource
jcr:primaryType="nt:unstructured"
sling:resourceType="myproject/components/datasource/productpages" />
</article>
2.Create a DataSource Servlet to return pages with specific sling:resourceType:
@Component(service = Servlet.class,
property = {
"sling.servlet.resourceTypes=myproject/components/datasource/productpages",
"sling.servlet.methods=GET"
})
public class ProductPagesDataSourceServlet extends SlingSafeMethodsServlet {
@Override
protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response)
throws ServletException, IOException {
ResourceResolver resolver = request.getResourceResolver();
List<Resource> options = new ArrayList<>();
String query = "SELECT * FROM [cq:PageContent] AS pageContent "
+ "WHERE pageContent.[sling:resourceType] = 'myapp/components/page/product'";
Iterator<Resource> results = resolver.findResources(query, Query.JCR_SQL2);
results.forEachRemaining(res -> {
String title = res.getValueMap().get("jcr:title", res.getName());
String path = res.getParent().getPath(); // Get the page path
ValueMap vm = new ValueMapDecorator(new HashMap<>());
vm.put("text", title);
vm.put("value", path);
options.add(new ValueMapResource(resolver, new ResourceMetadata(), "nt:unstructured", vm));
});
DataSource ds = new SimpleDataSource(options.iterator());
request.setAttribute(DataSource.class.getName(), ds);
}
}
Replace:
myapp/components/page/product with your actual resourceType.
Hope this helpful.:)
Regards,
Karishma.
Hi @FotisMa1
Custom Java predicates don't work in AEM as a Cloud Service with Touch UI `pathfield`. They were supported in Classic UI or older AEM versions but are ignored now. Touch UI only supports predefined client-side filters—no custom OSGi predicate injection.
To filter pathfield options by sling:resourceType in AEM as a Cloud Service, custom Java predicates will not work.
1.Use autocomplete in the dialog:
<article
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/autocomplete"
fieldLabel="Select Product Page"
name="./article"
multiple="{Boolean}false"
required="{Boolean}true">
<datasource
jcr:primaryType="nt:unstructured"
sling:resourceType="myproject/components/datasource/productpages" />
</article>
2.Create a DataSource Servlet to return pages with specific sling:resourceType:
@Component(service = Servlet.class,
property = {
"sling.servlet.resourceTypes=myproject/components/datasource/productpages",
"sling.servlet.methods=GET"
})
public class ProductPagesDataSourceServlet extends SlingSafeMethodsServlet {
@Override
protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response)
throws ServletException, IOException {
ResourceResolver resolver = request.getResourceResolver();
List<Resource> options = new ArrayList<>();
String query = "SELECT * FROM [cq:PageContent] AS pageContent "
+ "WHERE pageContent.[sling:resourceType] = 'myapp/components/page/product'";
Iterator<Resource> results = resolver.findResources(query, Query.JCR_SQL2);
results.forEachRemaining(res -> {
String title = res.getValueMap().get("jcr:title", res.getName());
String path = res.getParent().getPath(); // Get the page path
ValueMap vm = new ValueMapDecorator(new HashMap<>());
vm.put("text", title);
vm.put("value", path);
options.add(new ValueMapResource(resolver, new ResourceMetadata(), "nt:unstructured", vm));
});
DataSource ds = new SimpleDataSource(options.iterator());
request.setAttribute(DataSource.class.getName(), ds);
}
}
Replace:
myapp/components/page/product with your actual resourceType.
Hope this helpful.:)
Regards,
Karishma.
@FotisMa1 Just checking in, were you able to resolve your issue? We’d love to hear how things worked out. If the suggestions above helped, marking a response as correct can guide others with similar questions. And if you found another solution, feel free to share it. Your insights could really benefit the community. Thanks again for being part of the conversation!
Views
Replies
Total Likes
Views
Likes
Replies
Views
Likes
Replies