Wednesday, July 25, 2018
AEM 61 Touch UI Multiple Root Paths in Tags Picker
AEM 61 Touch UI Multiple Root Paths in Tags Picker
Goal
Support multiple root paths in Tags Picker of Touch UI. For Classic UI check this post
This is a picker extension only, searching inline still returns every tag available
For a similar Path Browser Picker extension check this post
Demo | Package Install
Tags Picker (Product)

Tags Picker with Multiple Root Paths Configuration (Extension)


Solution
1) Login to CRXDE Lite http://localhost:4502/crx/de, create folder /apps/touchui-tags-picker-custom-root-paths
2) Create folder /apps/touchui-tags-picker-custom-root-paths/tags-picker and file /apps/touchui-tags-picker-custom-root-paths/tags-picker/tags-picker.jsp, add the following code. This picker jsp extends ootb tags picker jsp /libs/cq/gui/components/common/tagspicker to set the data source url /apps/touchui-tags-picker-custom-root-paths/content/tag-column-wrapper.html (ootb its /libs/wcm/core/content/common/tagbrowser/tagbrowsercolumn.html set in /libs/cq/gui/components/common/tagspicker/render.jsp). Had the pickerSrc attribute been available as configuration param like rootPath, this step would have not been required...
<%@ page import="com.adobe.granite.ui.components.Config" %>
<%@ page import="org.apache.commons.lang3.StringUtils" %>
<%@ page import="org.apache.commons.lang3.ArrayUtils" %>
<%@include file="/libs/granite/ui/global.jsp" %>
<sling:include resourceType="/libs/cq/gui/components/common/tagspicker" />
<%
Config cfg = cmp.getConfig();
String[] eaemTagsPaths = cfg.get("eaemTagsRootPaths", String[].class);
//tags paths not set, continue with ootb functionality
if(ArrayUtils.isEmpty(eaemTagsPaths)){
return;
}
%>
<script type="text/javascript">
(function(){
var EAEM_TAGS_PATHS = "eaemtagsrootpaths",
BROWSER_COLUMN_PATH = "/apps/touchui-tags-picker-custom-root-paths/content/tag-column-wrapper.html";
function changeTagsPickerSrc(){
var $eaemTagsPicker = $("[data-" + EAEM_TAGS_PATHS + "]");
if($eaemTagsPicker.length == 0){
return;
}
var browserCP = BROWSER_COLUMN_PATH + <%=StringUtils.join(eaemTagsPaths, ",")%>;
$eaemTagsPicker.attr("data-picker-src", browserCP);
}
changeTagsPickerSrc();
}());
</script>
3) Create sling:Ordered folder /apps/touchui-tags-picker-custom-root-paths/content and nt:unstructured node /apps/touchui-tags-picker-custom-root-paths/content/tag-column-wrapper with sling:resourceType /apps/touchui-tags-picker-custom-root-paths/tag-browser-column
4) To add the picker browser column renderer extension, create folder /apps/touchui-tags-picker-custom-root-paths/tag-browser-column and file /apps/touchui-tags-picker-custom-root-paths/tag-browser-column/tag-browser-column.jsp with the following code. It includes /libs/wcm/core/content/common/tagbrowser/tagbrowsercolumn.html for getting the columns html and later removes unwanted root nodes
<%@ page import="org.apache.sling.api.request.RequestPathInfo" %>
<%@ page import="org.apache.sling.commons.json.JSONArray" %>
<%@include file="/libs/granite/ui/global.jsp" %>
<%!
String TAG_BROWSER_COLUMN_PATH = "/libs/wcm/core/content/common/tagbrowser/tagbrowsercolumn.html";
String TAG_NAV_MARKER = "eaemTagNavMarker";
private String getParentTagPath(String tagPath) {
return tagPath.substring(0, tagPath.lastIndexOf("/"));
}
private JSONArray getTagPathsJson(String[] tagPaths){
JSONArray array = new JSONArray();
for(String tagPath: tagPaths){
array.put(tagPath);
}
return array;
}
%>
<%
RequestPathInfo pathInfo = slingRequest.getRequestPathInfo();
String tagPaths[] = pathInfo.getSuffix().split(",");
for(String tagPath: tagPaths){
String includePath = TAG_BROWSER_COLUMN_PATH + getParentTagPath(tagPath);
%>
<sling:include path="<%=includePath%>" />
<%
}
%>
<div id="<%=TAG_NAV_MARKER%>">
</div>
<script type="text/javascript">
(function(){
function removeAddnNavsGetColumn($navs){
$navs.not(":first").remove(); //remove all additional navs
return $navs.first().children(".coral-ColumnView-column-content").html("");//get the column of first nav
}
function addRootTags(){
var $tagMarker = $("#<%=TAG_NAV_MARKER%>"),
$navs = $tagMarker.prevAll("nav"),
tagPaths = <%=getTagPathsJson(tagPaths)%>,
rootTags = [];
//find the root tags
$.each(tagPaths, function(index, tagPath){
rootTags.push($navs.find("[data-value=" + tagPath + "]"));
});
removeAddnNavsGetColumn($navs).append(rootTags);
//remove the tag marker div
$tagMarker.remove();
}
addRootTags();
}());
</script>
5) In the component dialog add necessary configuration eaemTagsRootPaths and sling:resourceType /apps/touchui-tags-picker-custom-root-paths/tags-picker. For example, here is a sample configuration added on ootb page properties /libs/foundation/components/page/cq:dialog/content/items/tabs/items/basic/items/column/items/title/items/tags. This is for demonstration only, never touch /libs
