Goal
AEM Assets Omnisearch does a full text search and is not nodename (or filename) based. XPath query generated by Omnisearch is something like below...
(/jcr:root/content/dam//element(*, nt:folder)[(jcr:contains(., 'show'))] | /jcr:root/content/dam//element(*, dam:Asset)[(jcr:contains(., 'show'))])
Solution discussed below performs a search based on filename (and not file content) running the following query in AEM...
(/jcr:root/content/dam//element(*, nt:folder)[(jcr:like(fn:lower-case(fn:name()), '%show%') and jcr:contains(., 'png'))] | /jcr:root/content/dam//element(*, dam:Asset)[(jcr:like(fn:lower-case(fn:name()), '%show%') and jcr:contains(., 'png'))])
For Assets search form Metadata Exists predicate check this post
Search Filter in Rail
Solution
1) Login to CRXDe Lite and add the File name predicate configuration eaemignorecasenodename in /apps/settings/dam/search/facets/formbuilderconfig/predicatetypes/items
2) Create the configuration page for predicate (fieldPropResourceType in step 1) /apps/eaem-search-form-nodename-predicate/nodename-field/nodename-field.jsp with the following code
3) Create the predicate widget render html (fieldResourceType in step 1) /apps/eaem-search-form-nodename-predicate/nodename-predicate/nodename-predicate.jsp with following code
4) Add the predicate evaluator apps.experienceaem.assets.IgnoreCaseNodeNamePredicateEvaluator for searching using partial file name, case ignored...
<?xml version="1.0" encoding="UTF-8"?> <jcr:root xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0" jcr:primaryType="cq:Page"> <adminui/> <search jcr:primaryType="nt:unstructured"> <facets jcr:primaryType="nt:unstructured"> <formbuilderconfig jcr:primaryType="nt:unstructured"> <predicatetypes jcr:primaryType="nt:unstructured"> <items jcr:primaryType="nt:unstructured"> <eaemignorecasenodename jcr:primaryType="nt:unstructured" fieldLabel="Filename" fieldPropResourceType="/apps/eaem-search-form-nodename-predicate/nodename-field" fieldResourceType="/apps/eaem-search-form-nodename-predicate/nodename-predicate" fieldTitle="Experience AEM Filename Predicate" fieldViewResourceType="granite/ui/components/foundation/form/textfield" renderType="text"/> </items> </predicatetypes> </formbuilderconfig> </facets> </search> </jcr:root>
2) Create the configuration page for predicate (fieldPropResourceType in step 1) /apps/eaem-search-form-nodename-predicate/nodename-field/nodename-field.jsp with the following code
<%@include file="/libs/granite/ui/global.jsp" %> <%@ page session="false" contentType="text/html" pageEncoding="utf-8" import="com.adobe.granite.ui.components.Config" %> <% String key = resource.getName(); String metaType = "eaemignorecasenodename"; String fieldLabel = i18n.get("Filename"); %> <input type="hidden" name="<%= xssAPI.encodeForHTMLAttr("./items/" + key) %>"> <input type="hidden" name="<%= xssAPI.encodeForHTMLAttr("./items/" + key + "/jcr:primaryType") %>" value="nt:unstructured"> <input type="hidden" name="<%= xssAPI.encodeForHTMLAttr("./items/" + key + "/sling:resourceType") %>" value="/apps/eaem-search-form-nodename-predicate/nodename-predicate"> <input type="hidden" name="<%= xssAPI.encodeForHTMLAttr("./items/" + key + "/fieldLabel") %>" value="<%= fieldLabel %>"> <input type="hidden" name="<%= xssAPI.encodeForHTMLAttr("./items/" + key + "/metaType") %>" value="<%= metaType %>"> <div><h3><%= i18n.get("Filename predicate")%></h3></div> <% request.setAttribute ("com.adobe.cq.datasource.fieldtextplaceholder", i18n.get("Filename"));%> <sling:include resource="<%= resource %>" resourceType="dam/gui/coral/components/admin/customsearch/formbuilder/predicatefieldproperties/fieldlabelpropertyfield"/> <sling:include resource="<%= resource %>" resourceType="granite/ui/components/foundation/form/formbuilder/formfieldproperties/titlefields"/> <sling:include resource="<%= resource %>" resourceType="granite/ui/components/foundation/form/formbuilder/formfieldproperties/deletefields"/>
3) Create the predicate widget render html (fieldResourceType in step 1) /apps/eaem-search-form-nodename-predicate/nodename-predicate/nodename-predicate.jsp with following code
<%@include file="/libs/granite/ui/global.jsp" %> <%@ page session="false" contentType="text/html" pageEncoding="utf-8" import="com.adobe.granite.ui.components.Config"%> <%@ page import="com.adobe.granite.ui.components.AttrBuilder" %> <% Config cfg = new Config(resource); String name = cfg.get("text", i18n.get("Property")); String metaType = cfg.get("metaType", "eaemignorecasenodename"); boolean foldableOpen = cfg.get("open", true); String selected = foldableOpen ? "selected":""; AttrBuilder inputAttrs = new AttrBuilder(request, xssAPI); inputAttrs.add("type", "text"); inputAttrs.add("name", metaType); inputAttrs.addClass("coral-Form-field coral-Textfield coral-DecoratedTextfield-input"); inputAttrs.add("placeholder", "Partial or full name, any case..."); %> <coral-accordion variant="large"> <coral-accordion-item "<%=selected%>" data-metaType="checkboxgroup" data-type="eaemignorecasenodename"> <coral-accordion-item-label><%= xssAPI.encodeForHTML(name) %></coral-accordion-item-label> <coral-accordion-item-content class="coral-Form coral-Form--vertical"> <input <%=inputAttrs.build()%>> </coral-accordion-item-content> </coral-accordion-item> </coral-accordion>
4) Add the predicate evaluator apps.experienceaem.assets.IgnoreCaseNodeNamePredicateEvaluator for searching using partial file name, case ignored...
package apps.experienceaem.assets; import com.day.cq.search.Predicate; import com.day.cq.search.eval.AbstractPredicateEvaluator; import com.day.cq.search.eval.EvaluationContext; import com.day.cq.search.eval.JcrPropertyPredicateEvaluator; import org.apache.commons.lang3.StringUtils; import org.osgi.service.component.annotations.Component; @Component( factory = "com.day.cq.search.eval.PredicateEvaluator/eaemignorecasenodename" ) public class IgnoreCaseNodeNamePredicateEvaluator extends AbstractPredicateEvaluator { public String getXPathExpression(Predicate predicate, EvaluationContext context) { String value = predicate.get(predicate.getName()); if(StringUtils.isEmpty(value)){ return null; } return "jcr:like(fn:lower-case(fn:name()), '%" + value.toLowerCase() + "%')"; } }
No comments:
Post a Comment