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 });
No comments:
Post a Comment