AEM 61 - JcrPayloadPathBuilder Implementation to change Inbox Item Url from Touch to Classic


When a user clicks on Inbox item of Classic UI, by default the asset opens in Touch UI editor - /assetdetails.html

This post is on changing the url from Touch (/assetdetails.html) to Classic (/damadmin) for workflow started on assets in sample folder /content/dam/experience-aem

Demo | SourcePackage Install


1) Create a OSGI service apps.experienceaem.inbox.ClassicUIAssetUrlPathBuilder implementing with much lower ranking say -1306, installed in /apps/classicui-inbox-asset-url/install

package apps.experienceaem.inbox;

import org.apache.commons.lang3.StringUtils;
import org.apache.felix.scr.annotations.*;
import org.osgi.framework.Constants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

@Component(metatype = false)
    @Property(name = Constants.SERVICE_DESCRIPTION, value = "Experience AEM Classic UI Inbox Asset Url"),
    @Property(name = "service.ranking", intValue = -1306, propertyPrivate = false)
public class ClassicUIAssetUrlPathBuilder implements JcrPayloadPathBuilder {
    private static final Logger log = LoggerFactory.getLogger(ClassicUIAssetUrlPathBuilder.class);

    private static String EAEM_FOLDER = "/content/dam/experience-aem";

    private ResourceResolverFactory resolverFactory;

    public String buildPath(WorkItem item) {
        ResourceResolver srvResolver = null;

        try {
            if (!item.getWorkflowData().getPayloadType().equals("JCR_PATH")) {
                return null;

            String path = item.getWorkflowData().getPayload().toString();

            Map<String, Object> authMap = new HashMap<String, Object>();
            authMap.put(ResourceResolverFactory.SUBSERVICE, "pathbuilder");

            srvResolver = resolverFactory.getServiceResourceResolver(authMap);

            Resource res = srvResolver.getResource(path);

            if (res == null || !StringUtils.startsWith(res.getPath(), EAEM_FOLDER)) {
                return null;

            if (res.adaptTo(Asset.class) != null) {
                return "/damadmin#" + res.getPath();
        } catch (Exception e) {
            log.warn("Error creating inbox asset url", e);
        } finally {
            if (srvResolver != null) {

        return null;

2) Create a service user mapping for bundle apps.experienceaem.inbox.classicui-inbox-asset-url-bundle and sub service pathbuilder in folder /apps/classicui-inbox-asset-url/config, node of type sling:OsgiConfig

<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="" xmlns:jcr=""

3) Check the component registered in http://localhost:4502/system/console/components

1 comment:

  1. Forgive me as I haven't tried implementing this yet, but simply because this service exists, the system knows to use it over the default implementation? What actually ties this to the clicking of an inbox item?