EVOLVE'16 | Enhance | Oscar Bolaños & Justin Edelson | Search All the Things: Omnisearch in AEM 6.2
-
Upload
evolve-the-aem-community-conference -
Category
Technology
-
view
116 -
download
1
Transcript of EVOLVE'16 | Enhance | Oscar Bolaños & Justin Edelson | Search All the Things: Omnisearch in AEM 6.2
#evolverocks
SEARCH ALL THE THINGS:OMNISEARCH IN AEM 6.2JUSTIN EDELSON & OSCAR BOLAÑOS
August 31st, 2016
#evolverocks
#evolverocks 3
ABOUT US
Twittertwitter.com/justinedelson
Linkledinlinkedin.com/in/justinedelson
Justin EdelsonTeam Lead
Linkledinlinkedin.com/in/orbolanos
Oscar BolañosProject Lead
#evolverocks4
What is Omnisearch and How do I use it?ExtensibilityWriting a new OmniSearchHandlerUI Implementation
AGENDA
#evolverocks5
Unified Author-Side Content SearchingConsistent User ExperienceConsistent AccessConsole/Tool Access
WHAT IS OMNISEARCH?
#evolverocks6
1.OpenSlash KeySearch Icon2.Start Typing
HOW TO USE OMNISEARCH?
#evolverocks7
CROSS-CONTENT TYPE SEARCHES
#evolverocks8
LOCATIONS
#evolverocks9
#evolverocks10
PREDICATES
#evolverocks11
GO TO…
12#evolverocks
CONSOLE FILTERS
#evolverocks
DEMO
13
14#evolverocks
LET’S SEE SOME CODE
#evolverocks15
Locations Map 1:1 to implementations of OmniSearchHandler
ADDING A LOCATION
#evolverocks16
getID()Return unique identifier for the search handler
getModuleConfig()Return a Resource with the configuration of the handler
CONFIGURATION METHODS
#evolverocks17
@Component@Servicepublic final class ContentFragmentOmniSearchHandler
implements OmniSearchHandler {
@Overridepublic Resource getModuleConfig(ResourceResolver resourceResolver) { return resourceResolver.getResource("/apps/aem-omnisearch-content-fragments/content/metadata");}
@Overridepublic String getID() { return "custom-cfm";
}}
START OF IMPLEMENTATION
#evolverocks18
getResults()Return the actual search results
getSuggestions()Return a Query to get the list of suggestions
getSpellCheck()Return a Query to get the list of spell check suggestions
getPredicateSuggestions()Get a list of predicate suggestions based on a search term
SEARCH METHODS
19#evolverocks
Requires configuration of Lucene indexese.g. /oak:index/damAssetLucene
Properties can have these two flags:useInSuggestuseInSpellcheck
Suggestion list is updated every 10 minutes by default, but configurable.
Path restriction support is limitedProperty restriction support is non-existing
OAK SUGGESTIONS & SPELL CHECKA BRIEF DIGRESSION
#evolverocks20
@Overridepublic SearchResult getResults(ResourceResolver resourceResolver,
Map<String, Object> predicateParameters, long limit, long offset) { Map<String, String> predicates = new HashMap<String, String>(); predicates.put("path", DamConstants.MOUNTPOINT_ASSETS); predicates.put("type", DamConstants.NT_DAM_ASSET); predicates.put("property", "jcr:content/contentFragment"); predicates.put("property.value", "true");
if (predicateParameters.containsKey("fulltext")) { String[] ft = (String[]) predicateParameters.get("fulltext"); predicates.put("fulltext", ft[0]); }
PredicateGroup predicatesGroup = PredicateGroup.create(predicates); com.day.cq.search.Query query = queryBuilder.createQuery(predicatesGroup,
resourceResolver.adaptTo(Session.class)); if (limit != 0) { query.setHitsPerPage(limit); } if(offset != 0) { query.setStart(offset); } SearchResult queryResult = query.getResult(); return queryResult;}
SEARCH METHODTHE NAÏVE VERSION
21#evolverocks
boolean addedPath = false;boolean addedType = false;for (Map.Entry<String, Object> param : predicateParameters.entrySet()) { if (param.getValue() instanceof String[]) { String[] values = (String[]) param.getValue(); if (values.length == 1) { if ((param.getKey().equals("path") || param.getKey().endsWith("_path")) && values[0].length() > 0) { addedPath = true; } if (param.getKey().equals("type") || param.getKey().endsWith("_type")) { addedType = true; } predicates.put(param.getKey(), values[0]); } }}if (!addedPath) { predicates.put("path", DamConstants.MOUNTPOINT_ASSETS);}if (!addedType) { predicates.put("type", DamConstants.NT_DAM_ASSET);}predicates.put("999_property", "jcr:content/contentFragment");predicates.put("999_property.value", "true");
SEARCH METHODTHE REAL VERSION
22#evolverocks
public Query getSuggestionQuery(ResourceResolver resourceResolver, String term) { String queryStr = "SELECT [rep:suggest()] FROM [dam:Asset] as s " + " WHERE SUGGEST($term) AND ISDESCENDANTNODE([/content/dam])"; try { Query query = createQuery(resourceResolver, term, queryStr); return query; } catch (RepositoryException e) { log.error("Unable to create suggestions query", e); return null; }}
SUGGESTIONS METHOD
23#evolverocks
@Overridepublic List<PredicateSuggestion> getPredicateSuggestions( ResourceResolver resourceResolver, I18n i18n, String term) { List<PredicateSuggestion> matchedPredicates = new ArrayList<PredicateSuggestion>(); List<PredicateSuggestion> allPredicateSuggestions = getAllPredicateSuggestions(resourceResolver); for (PredicateSuggestion suggestion : allPredicateSuggestions) { if (suggestion.getOptionTitle().toLowerCase(). contains(term.toLowerCase())) { matchedPredicates.add(suggestion); } } return matchedPredicates;}
PREDICATE SUGGESTIONS
#evolverocks24
• Control the UI of the search module• Each handler needs to have one• Default ones are at /libs/granite/omnisearch/content/metadata
MODULE CONFIGURATION NODES
#evolverocks25
jcr:titleThe display title of the search location
listOrderThe order of the location
cardPathThe resource type used to render results in the card view
listItemPathThe resource type used to render results in the list view
clientlibsAny custom clientlib that needs to be loaded when the location is shown. This is typically used to handle custom actions when an item is selected.
MODULE CONFIG NODE PROPERTIES
#evolverocks26
actions/selectionActions that are loaded once an item from that location is selected. Different actions could be enabled during the Omnisearch here, as opposed to the console.
views/listView configuration that is used while in list view. This is specially important for the List View because allows to configure the columns that are shown.
MODULE CONFIG NODE CHILD NODES
#evolverocks27
<coral-card data-sly-use.data="data.js" class="foundation-collection-navigator" data-foundation-collection-navigator-href="${data.navigationHref}" itemscope="itemscope" itemtype="http://schema.org/WebPage" colorhint="#ffffff"> <coral-card-asset> <img src="${data.thumbnailUrl}"> </coral-card-asset> <coral-card-content> <coral-card-context>FRAGMENT</coral-card-context> <coral-card-title class="foundation-collection-item-title" value="${data.title}">${data.title}</coral-card-title> </coral-card-content> <coral-card-propertylist></coral-card-propertylist> <!-- see next slides --> <link rel="properties" href="${data.navigationHref}"> <meta class="foundation-collection-quickactions" data-foundation-collection-quickactions-rel=""> <coral-quickactions></coral-quickactions> <!-- see next slides --></coral-card>
CARD COMPONENT
#evolverocks28
<coral-card-propertylist data-sly-test=${data.lastModified}> <coral-card-property icon="edit"> <time datetime="${data.lastModified}"> ${data.formattedRelativeTime} </time> </coral-card-property></coral-card-propertylist>
CARD COMPONENT CONTINUED
#evolverocks29
<coral-quickactions target="_prev" alignmy="left top" alignat="left top"> <coral-quickactions-item icon="check” class="foundation-collection-item-activator"> Select </coral-quickactions-item> <coral-quickactions-item icon="edit” class="foundation-anchor” data-foundation-anchor-href="${data.navigationHref}"> Edit </coral-quickactions-item> <coral-quickactions-item icon="infoCircle" class="foundation-anchor” data-foundation-anchor-href="${data.propertiesHref}” data-contextpath = "/assetdetails.html"> View Properties </coral-quickactions-item></coral-quickactions>
CARD COMPONENT CONTINUED
30#evolverocks
<tr data-sly-use.data="data.js" data-item-title="${data.title}" data-foundation-collection-navigator-href="${data.navigationHref}” data-foundation-collection-item-id="${data.path}" class="foundation-collection-item foundation-collection-navigator" is="coral-tr"> <td is="coral-td" coral-tr-select> <img class="foundation-collection-item-thumbnail" src="${data.thumbnailUrl}" alt="${data.title}"> </td> <td class="foundation-collection-item-title" is="coral-td">${data.title}</td> <td is="coral-td"> <time datetime="${data.lastModified}"> <coral-icon icon="edit" size="xs"></coral-icon> ${data.formattedRelativeTime}</time> </td> <td is="coral-td">${data.description} <meta class="foundation-collection-quickactions" data-foundation-collection-quickactions-rel=""> </td></tr>
ROW ITEM COMPONENT
#evolverocks
DEMO
31
32#evolverocks
https://github.com/justinedelson/aem-omnisearch-cfm
CODE
#evolverocks33
• Wizard support• i.e. “Create” -> “Create Page” (suggestion) -> Create Page Wizard
• Tags as Global Predicate• Recent Search Support• Improved Save Search Support
FUTURE CONCEPTS
#evolverocks
THANK YOU!