Search code examples
aemaem-touch-ui

How to find the page URL complete path in AEM Touch UI Dialog


We have site structure as below:

Site:
  --Brand
     --Market
         --Language
             --Page1

Let us say my custom component dragged and dropped in Page1. Now in dialog listener I want to find the Market and Language parameters from the page path.

How to achieve this in TouchUI dialog of AEM?


Solution

  • There are two options that I know of. One is easy but not "robust" and the other is more complex but also more robust.

    Option #1: The Easy Solution

    In TouchUI you have access to so called "page information" in JavaScript. Your dialog listener could access this "page information" to get the absolute content path and then parse the string.

    This could look like this:

    (function ($, $document, author) {
        "use strict";
     
        $document.on("dialog-ready", function() {
            var path = author.page.path;
        });
     
        
    })($, $(document), Granite.author);
    

    Obviously, you have to parse the path string variable to get the parts of the path that you are interested in.

    I want to note, that the JavaScript "variable" Granite.author.page contains a lot of interesting information about the current page, components etc.

    Now to the important part: This is a easy way to solve your problem, but parsing strings is always going to be a fragile solution. Personally, I would say that parsing strings should be considered bad practice and should be avoided at all cost. This is way I want to propose a better solution with Option #2.

    Option #2: The (More) Complex Solution

    In Option #1 I proposed using the "page information" provided by the TouchUI to get the full page path and then parse the path. Option #2 builds on this but improves the approach by extending the information provided by the "page information".

    To extend the "page information" you have to create a OSGi service that implements the following interface:

    com.day.cq.wcm.api.PageInfoProvider
    

    Your PageInfoProvider will be called on every request and then is able to add information to the provided JSONObject.

    This means that you could write some business logic that:

    1. gets a proper AEM Page instance either from the provided request or resource.
    2. gets the market and language page from the page.

    Code for this could look like this:

    import com.day.cq.wcm.api.PageInfoProvider;
    import org.apache.sling.api.SlingHttpServletRequest;
    import org.apache.sling.api.resource.Resource;
    import org.apache.sling.commons.json.JSONException;
    import org.apache.sling.commons.json.JSONObject;
    import org.osgi.service.component.annotations.Component;
    
    @Component
    public class MyPageInfoProvider implements PageInfoProvider {
    
        @Override
        public void updatePageInfo(final SlingHttpServletRequest request,
                                   final JSONObject pageInfo,
                                   final Resource resource) throws JSONException {
    
            // get market
            // get languagepage
    
            pageInfo.put("market", market);
            pageInfo.put("languagepage", languagepage);
        }
    }
    

    I would advice you to use dedicated resource types for your market and language pages. This way it would be easy to write another OSGi service that you can pass a Page to and it would then determine the pages market and languagepage by traversing the content tree up until a page is found that has the required resource type.

    The dialog listener could like this now:

    (function ($, $document, author) {
        "use strict";
     
        $document.on("dialog-ready", function() {
            var market = author.pageInfo.market;
            var languagepage = author.pageInfo.languagepage;
        });
     
        
    })($, $(document), Granite.author);
    

    This solution is far more robust because no string parsing is involved and all of the Java code can be covered by proper unit tests.