AEM 61 - Touch UI Filtering Pages by Template in Asset Finder

Goal


Asset Finder in Touch UI is Content Finder of Classic UI. In AEM 61 ( not 60 ) we can search for pages in Asset Finder. In this extension we provide additional filtering of pages by providing Search by Template (Granite/TouchUI/Coral UI sample Select)

Demo | Source Code | Package Install

A similar extension for Classic UI is here



Solution


1) We need a servlet to return templates as json. So code one and install as OSGI bundle

package apps.experienceaem.pagefilters;

import org.apache.felix.scr.annotations.sling.SlingServlet;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.servlets.SlingAllMethodsServlet;
import org.apache.sling.commons.json.io.JSONWriter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.Session;
import javax.jcr.query.Query;
import javax.jcr.query.QueryManager;
import javax.servlet.ServletException;
import java.io.IOException;

@SlingServlet(
        paths="/bin/experience-aem/touch-ui/page-filters/templates",
        methods = "GET",
        metatype = false,
        label = "Get Templates Servlet"
)
public class GetTemplates extends SlingAllMethodsServlet {
    private static final Logger log = LoggerFactory.getLogger(GetTemplates.class);

    @Override
    protected void doGet(final SlingHttpServletRequest request, final SlingHttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("application/json");
        response.setCharacterEncoding("utf-8");

        JSONWriter jw = new JSONWriter(response.getWriter());

        try{
            ResourceResolver resolver = request.getResourceResolver();
            Session session = resolver.adaptTo(Session.class);
            QueryManager qm = session.getWorkspace().getQueryManager();

            String stmt = "//element(*,cq:Template)[jcr:like(@jcr:path, '/apps/%')] order by @jcr:title";

            Query q = qm.createQuery(stmt, Query.XPATH);

            NodeIterator results = q.execute().getNodes();
            Node node = null, tNode = null; String path = null;

            jw.array();

            while(results.hasNext()){
                node = results.nextNode();
                path = node.getProperty("jcr:content/sling:resourceType").getString();

                if(path.startsWith("/apps/")){
                    path = path.substring(6);//remove /apps/
                }

                jw.object();
                jw.key("id").value(path);
                jw.key("name").value(node.getProperty("jcr:title").getString());
                jw.endObject();
            }

            jw.endArray();
        }catch(Exception e){
            log.error("Error getting templates",e);
            throw new ServletException(e);
        }
    }
}

2) JS logic for showing templates is added using Clientlibs. Login to CRXDE Lite (http://localhost:4502/crx/de) and create folder /apps/touch-ui-page-filters

2) Create node /apps/touch-ui-page-filters/clientlib of type cq:ClientLibraryFolder and add a String property categories with value cq.authoring.editor.hook.assetfinder and String property dependencies with value cq.jquery.ui

3) Create file (nt:file) /apps/touch-ui-page-filters/clientlib/js.txt and add

                       page-filters.js

4) Create file (nt:file) /apps/touch-ui-page-filters/clientlib/page-filters.js and add the following code

(function (document, $, assetFinder) {
    var TEMPLATE_SELECT_ID = "experience-aem-filter-template";
    var c$templateSelect = null;

    //id assetfinder-filter and class .assetfilter.type are defined in
    ///libs/wcm/core/content/editor/jcr:content/sidepanels/edit/items/assetsTab/items/filterPanel/items/views/items/search/items/searchpanel
    var $assetFinderFilter = $('#assetfinder-filter');
    var $assetFinderType = $assetFinderFilter.find(".assetfilter.type");

    var addTemplateSelect = function () {
        var templateMarkup = '<span class="coral-Select" data-init="select" id="' + TEMPLATE_SELECT_ID + '">' +
            '<button type="button" class="coral-Select-button coral-MinimalButton">' +
            '<span class="coral-Select-button-text">Select</span>' +
            '</button>' +
            '<select class="coral-Select-select">' +
            '<option value="ALL">Of All Templates</option>' +
            '</select>' +
            '</span>';

        var $optionTemplate = $('<script type="text/x-jquery-tmpl">' +
                                    '<option value="${id}">${name}</option>' +
                                '</script>').appendTo($assetFinderType);

        var promise = $.ajax({
            type: 'GET',
            url: "/bin/experience-aem/touch-ui/page-filters/templates"
        });

        promise.done(function (data) {
            $("<div/>").appendTo($assetFinderType).append($(templateMarkup));

            $optionTemplate.tmpl(data).appendTo("#" + TEMPLATE_SELECT_ID + " .coral-Select-select");

            c$templateSelect = new CUI.Select({
                element: "#" + TEMPLATE_SELECT_ID,
                visible: true
            });

            c$templateSelect.hide();
        });

        promise.fail(function(){
            alert("error");
        });

        $assetFinderType.find("select").on('change', function (event) {
            var type = $(event.target).find("option:selected").val();

            if (type == "Pages") {
                c$templateSelect.show();
            }else{
                c$templateSelect.hide();
            }
        });
    };

    var pagesController = assetFinder.registry["Pages"];
    var loadAssets = pagesController.loadAssets;

    $.extend(pagesController, {
        loadAssets: function(query, lowerLimit, upperLimit){
            var template = c$templateSelect.getValue();

            if(template && ( template != "ALL")){
                query = '"jcr:content/sling:resourceType":"' + template + '" ' + query;
            }

            return loadAssets.call(this, query, lowerLimit, upperLimit);
        }
    });

    addTemplateSelect();
}(document, jQuery, Granite.author.ui.assetFinder));

5) In the above logic #32 we use JQuery templates to fill options in Select

$optionTemplate.tmpl(data).appendTo("#" + TEMPLATE_SELECT_ID + " .coral-Select-select");


6) The following logic #34 creates Touch UI Select Widget

c$templateSelect = new CUI.Select({
                element: "#" + TEMPLATE_SELECT_ID,
                visible: true
            });


1 comment:

  1. Looking for reliable Marketing Homework Help? Get expert guidance on consumer behavior, market research, branding, digital marketing, and campaign strategy. We help you understand key concepts, analyze case studies effectively, and present well-structured homework that meets academic standards. With personalized support and clear explanations, completing your marketing homework becomes easier and stress-free.

    ReplyDelete