Queries and searches are two very different concepts, but both will follow the same flow: provide parameters and iterate on results. This tutorial will provide practical usage examples of both concepts as well as references to relevant documentation entries.
Jahia modules rely on Java and Maven. The key requirements are as follows:
Queries
<jcr:sql
library:
<jcr:sql var="pages" sql="select * from [jnt:page] as page where isdescendantnode(page,['${renderContext.site.path}'])"/>
The query will select all the objects of type jnt:page
under the current site, and store an iterator (a list) of results in the variable pages
.
Results stored by jcr:sql
are stored in an iterator who will return a list with the accessor .nodes
<c:forEach items="${pages.nodes}" var="node">
<template:module node="${node}" view="link" />
</c:forEach>
In the previous piece of code, we are storing each page in a variable node
, and displaying its view link
, which is a simple HTML link to the page.
Queries can be resource intensive when not optimized. Some easy optimizations can make a big difference:
isdescendantnode
Searching is an experience composed of two steps: gathering inputs, and displaying the results. Since searching is targeted at humans, the search experience is a key aspect to be taken into consideration.
The following code displays a vanilla HTML form to perform searches with the following parameters:
<c:url value="${currentNode.properties.result.node.url}" var="searchUrl"/>
<s:form method="post" action="${searchUrl}" role="search">
<div class="search_form">
<s:term match="all_words" id="searchTerm" searchIn="siteContent,tags" class="form-control" placeholder="Search term"/>
<s:site value="${renderContext.site.name}" includeReferencesFrom="systemsite" display="false"/>
<s:language value="${renderContext.mainResource.locale}" display="false"/>
<span class="input-group-btn">
<button type="button" onclick="document.searchForm.submit()" value="Search">
</button>
</span>
</div>
</s:form>
The variable ${currentNode.properties.result}
is expected to contain a reference to the search result's page. The search form content type should contain a property defined as follows:
[jnt:customSearchForm] > jnt:content, jmix:structuredContent
- result (weakreference, type=['picker=page'])
When putting this content on a page via composer, the following field should be displayed:
The search results page is automatically created under the home page and can be picked as follows:
For more information about the taglib options, please refer to the Search and Queries documentation.
Search results are extracted by the function s:results
and put on a Map object.
<s:results var="resultsHits" approxCountVar="listApproxSize">
<c:set target="${moduleMap}" property="listTotalSize" value="${count}" />
<c:set target="${moduleMap}" property="resultsHits" value="${resultsHits}" />
<c:set target="${moduleMap}" property="listApproxSize" value="${listApproxSize}" />
</s:results>
<s:resultIterator begin="${moduleMap.begin}" end="${moduleMap.end}" varStatus="status" hits="${moduleMap['resultsHits']}">
<li>
<%--<span>${status.index+1}.</span>--%>
<%@ include file="searchHit.jspf" %>
</li>
</s:resultIterator>
The code above will store the search results as well as some metadata on the moduleMap, and iterate through each result. The moduleMap is a Hashmap used by various Jahia modules to store and fetch data between views. In this instance, the s:result taglib stores the search results in the moduleMap and the current view passes it to s:resultIterator to display each result individually.
The searchHit.jspf's source code can be found here, and forked according to your needs. This file needs to be stored in the same folder as your search result view file.