Expand my Community achievements bar.

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

Show pages of specific resourceType in pathfield selection dialog

Avatar

Level 1

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"
/>

 

Topics

Topics help categorize Community content and increase your ability to discover relevant content.

1 Accepted Solution

Avatar

Correct answer by
Level 4

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.

View solution in original post

3 Replies

Avatar

Correct answer by
Level 4

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.

Avatar

Community Advisor

Avatar

Administrator

@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!



Kautuk Sahni