You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by dk...@apache.org on 2018/02/15 17:41:31 UTC
[sling-whiteboard] branch master updated: Getting search to work
This is an automated email from the ASF dual-hosted git repository.
dklco pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-whiteboard.git
The following commit(s) were added to refs/heads/master by this push:
new 16371b0 Getting search to work
16371b0 is described below
commit 16371b0680c24902806c4dff01b81b4d5f07bb8e
Author: Dan Klco <da...@gmail.com>
AuthorDate: Thu Feb 15 12:40:10 2018 -0500
Getting search to work
---
cms/core/pom.xml | 3 +-
.../apache/sling/cms/reference/models/Search.java | 159 +++++++++++++++++++++
.../reference/components/general/search/edit.json | 7 +
.../components/general/search/pagination.jsp | 82 +++++------
.../reference/components/general/search/search.jsp | 35 ++---
.../components/general/stylewrapper/edit.json | 4 +-
6 files changed, 218 insertions(+), 72 deletions(-)
diff --git a/cms/core/pom.xml b/cms/core/pom.xml
index b3de0b7..b1f77d6 100644
--- a/cms/core/pom.xml
+++ b/cms/core/pom.xml
@@ -43,7 +43,8 @@
<configuration>
<instructions>
<Sling-Model-Packages>
- org.apache.sling.cms.core.models
+ org.apache.sling.cms.core.models,
+ org.apache.sling.cms.reference.models
</Sling-Model-Packages>
</instructions>
</configuration>
diff --git a/cms/core/src/main/java/org/apache/sling/cms/reference/models/Search.java b/cms/core/src/main/java/org/apache/sling/cms/reference/models/Search.java
new file mode 100644
index 0000000..6bb1a77
--- /dev/null
+++ b/cms/core/src/main/java/org/apache/sling/cms/reference/models/Search.java
@@ -0,0 +1,159 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.cms.reference.models;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.*;
+
+import javax.annotation.PostConstruct;
+import javax.jcr.query.Query;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.jackrabbit.util.Text;
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.models.annotations.Model;
+import org.apache.sling.models.annotations.injectorspecific.ValueMapValue;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Model for retrieving search results and pagination based on a search of the
+ * Sling CMS repository.
+ */
+@Model(adaptables = SlingHttpServletRequest.class)
+public class Search {
+
+ private static final Logger log = LoggerFactory.getLogger(Search.class);
+
+ public static final String TERM_PARAMETER = "q";
+
+ @ValueMapValue
+ private String basePath;
+
+ private int count;
+
+ private int end;
+
+ @ValueMapValue
+ private int limit;
+
+ private int page;
+
+ private Integer[] pages;
+
+ private SlingHttpServletRequest request;
+
+ private List<Resource> results = new ArrayList<Resource>();
+
+ private int start;
+
+ public Search(SlingHttpServletRequest request) {
+ this.request = request;
+ }
+
+ public int getCount() {
+ return count;
+ }
+
+ public int getCurrentPage() {
+ return page + 1;
+ }
+
+ public int getEnd() {
+ return end;
+ }
+
+ public Integer[] getPages() {
+ return pages;
+ }
+
+ public List<Resource> getResults() {
+ return results;
+ }
+
+ public int getStart() {
+ return start;
+ }
+
+ public String getTerm() {
+ return request.getParameter(TERM_PARAMETER);
+ }
+
+ @PostConstruct
+ public void init() {
+
+ Set<String> distinct = new HashSet<String>();
+
+ String term = Text.escapeIllegalXpathSearchChars(request.getParameter(TERM_PARAMETER)).replaceAll("'", "''");
+ log.debug("Searching for pages with {} under {}", term, basePath);
+
+ Iterator<Resource> res = request.getResourceResolver().findResources(
+ "SELECT parent.* FROM [sling:Page] AS parent INNER JOIN [nt:base] AS child ON ISDESCENDANTNODE(child,parent) WHERE ISDESCENDANTNODE(parent, '"
+ + basePath + "') AND CONTAINS(child.*, '" + term + "')",
+ Query.JCR_SQL2);
+ while (res.hasNext()) {
+ Resource result = res.next();
+ if (!distinct.contains(result.getPath())) {
+ results.add(result);
+ distinct.add(result.getPath());
+ }
+ }
+ count = results.size();
+ log.debug("Found {} results", count);
+
+ if (StringUtils.isNotBlank(request.getParameter("page")) && request.getParameter("page").matches("\\d+")) {
+ page = Integer.parseInt(request.getParameter("page"), 10) - 1;
+ log.debug("Using page {}", page);
+ } else {
+ page = 0;
+ log.debug("Page {} not specified or not valid", request.getParameter("page"));
+ }
+
+ if (page * limit >= count) {
+ start = count;
+ } else {
+ start = page * limit;
+ }
+ log.debug("Using start {}", start);
+
+ if ((page * limit) + limit >= count) {
+ end = count;
+ } else {
+ end = (page * limit) + limit;
+ }
+ log.debug("Using end {}", end);
+ results = results.subList(start, end);
+
+ List<Integer> pgs = new ArrayList<Integer>();
+ int max = ((int) Math.ceil((double) count / limit)) + 1;
+ for (int i = 1; i < max; i++) {
+ pgs.add(i);
+ }
+ pages = pgs.toArray(new Integer[pgs.size()]);
+ log.debug("Loaded pages {}", Arrays.toString(pages));
+ }
+
+ public boolean isFirst() {
+ return page == 0;
+ }
+
+ public boolean isLast() {
+ return page + 1 == pages[pages.length - 1];
+ }
+}
diff --git a/cms/ui/src/main/resources/jcr_root/apps/reference/components/general/search/edit.json b/cms/ui/src/main/resources/jcr_root/apps/reference/components/general/search/edit.json
index 4478859..c77aaaf 100644
--- a/cms/ui/src/main/resources/jcr_root/apps/reference/components/general/search/edit.json
+++ b/cms/ui/src/main/resources/jcr_root/apps/reference/components/general/search/edit.json
@@ -12,6 +12,13 @@
"name": "limit",
"required": true,
"type": "number"
+ },
+ "basePath": {
+ "jcr:primaryType": "nt:unstructured",
+ "sling:resourceType": "sling-cms/components/editor/fields/text",
+ "label": "Base Path",
+ "name": "basePath",
+ "required": true
}
}
}
\ No newline at end of file
diff --git a/cms/ui/src/main/resources/jcr_root/apps/reference/components/general/search/pagination.jsp b/cms/ui/src/main/resources/jcr_root/apps/reference/components/general/search/pagination.jsp
index ed0c1b4..b94da75 100644
--- a/cms/ui/src/main/resources/jcr_root/apps/reference/components/general/search/pagination.jsp
+++ b/cms/ui/src/main/resources/jcr_root/apps/reference/components/general/search/pagination.jsp
@@ -17,48 +17,42 @@
* under the License.
*/ --%>
<%@include file="/libs/sling-cms/global.jsp"%>
-<c:if test="${not empty param.q && not empty query}">
- <nav>
- <ul class="${searchConfig.valueMap.paginationClass}">
- <c:choose>
- <c:when test="${not empty param.page && param.page != '0'}">
- <li class="${searchConfig.valueMap.pageItemClass} disabled">
- <span class="${searchConfig.valueMap.pageLinkClass}">
- <
- </span>
- </li>
- </c:when>
- <c:otherwise>
- <li class="${searchConfig.valueMap.pageItemClass} disabled">
- <a class="${searchConfig.valueMap.pageLinkClass}" href="?q=${sling:encode(param.q,'HTML_ATTR')}"><</a>
- </li>
- </c:otherwise>
- </c:choose>
- <c:set var="hasMode" value="false" />
- <c:forEach var="item" items="${sling:findResources(resourceResolver,query,'JCR-SQL2')}" step="${properties.limit}" varStatus="status">
- <li class="${searchConfig.valueMap.pageItemClass} ">
- <a href="?q=${sling:encode(param.q,'HTML_ATTR')}&page=${status.index}" class="${searchConfig.valueMap.pageLinkClass}">
- ${status.index + 1}
- </a>
+<nav>
+ <ul class="${searchConfig.valueMap.paginationClass}">
+ <c:choose>
+ <c:when test="${search.first == true}">
+ <li class="${searchConfig.valueMap.pageItemClass} disabled">
+ <span class="${searchConfig.valueMap.pageLinkClass}">
+ <
+ </span>
</li>
- <c:if test="${status.last && param.page lt status.index}">
- <c:set var="hasMode" value="true" />
- </c:if>
- </c:forEach>
- <c:choose>
- <c:when test="${hasMode == 'false'}">
- <li class="${searchConfig.valueMap.pageItemClass} disabled">
- <span class="${searchConfig.valueMap.pageLinkClass}">
- >
- </span>
- </li>
- </c:when>
- <c:otherwise>
- <li class="${searchConfig.valueMap.pageItemClass} disabled">
- <a class="${searchConfig.valueMap.pageLinkClass}" href="?q=${sling:encode(param.q,'HTML_ATTR')}&page=${param.page + 1}">></a>
- </li>
- </c:otherwise>
- </c:choose>
- </ul>
- </nav>
-</c:if>
\ No newline at end of file
+ </c:when>
+ <c:otherwise>
+ <li class="${searchConfig.valueMap.pageItemClass}">
+ <a class="${searchConfig.valueMap.pageLinkClass}" href="?q=${sling:encode(search.term,'HTML_ATTR')}"><</a>
+ </li>
+ </c:otherwise>
+ </c:choose>
+ <c:forEach var="page" items="${search.pages}">
+ <li class="${searchConfig.valueMap.pageItemClass} ">
+ <a href="?q=${sling:encode(search.term,'HTML_ATTR')}&page=${page}" class="${searchConfig.valueMap.pageLinkClass}">
+ ${page}
+ </a>
+ </li>
+ </c:forEach>
+ <c:choose>
+ <c:when test="${search.last}">
+ <li class="${searchConfig.valueMap.pageItemClass} disabled">
+ <span class="${searchConfig.valueMap.pageLinkClass}">
+ >
+ </span>
+ </li>
+ </c:when>
+ <c:otherwise>
+ <li class="${searchConfig.valueMap.pageItemClass}">
+ <a class="${searchConfig.valueMap.pageLinkClass}" href="?q=${sling:encode(search.term,'HTML_ATTR')}&page=${search.currentPage + 1}">></a>
+ </li>
+ </c:otherwise>
+ </c:choose>
+ </ul>
+</nav>
\ No newline at end of file
diff --git a/cms/ui/src/main/resources/jcr_root/apps/reference/components/general/search/search.jsp b/cms/ui/src/main/resources/jcr_root/apps/reference/components/general/search/search.jsp
index e4ab38e..8cba767 100644
--- a/cms/ui/src/main/resources/jcr_root/apps/reference/components/general/search/search.jsp
+++ b/cms/ui/src/main/resources/jcr_root/apps/reference/components/general/search/search.jsp
@@ -19,37 +19,22 @@
<%@include file="/libs/sling-cms/global.jsp"%>
<sling:adaptTo var="pageMgr" adaptable="${resource}" adaptTo="org.apache.sling.cms.core.models.PageManager" />
<c:set var="searchConfig" value="${pageMgr.page.template.componentConfigs['reference/components/general/search']}" scope="request" />
-${searchConfig }
-<c:if test="${not empty properties.limit}">
+<c:if test="${not empty properties.limit && not empty param.q}">
+ <c:set var="search" value="${sling:adaptTo(slingRequest, 'org.apache.sling.cms.reference.models.Search')}" scope="request" />
<div class="search ${searchConfig.valueMap.searchClass}">
<div class="search__header">
<fmt:message key="slingcms.search.header">
- <fmt:param value="${sling:encode(param.q,'HTML')}" />
+ <fmt:param value="${sling:encode(search.term,'HTML')}" />
+ <fmt:param value="${search.start}" />
+ <fmt:param value="${search.end}" />
+ <fmt:param value="${search.count}" />
</fmt:message>
</div>
<div class="search__results">
- <c:if test="${not empty param.q}">
- <c:set var="quote" value="'"/>
- <c:set var="escape" value=""/>
- <c:catch>
- <c:set var="query" value="SELECT parent.* FROM [sling:Page] AS parent INNER JOIN [nt:base] AS child ON ISDESCENDANTNODE(child,parent) WHERE ISDESCENDANTNODE(parent, '/content/danklco-com') AND CONTAINS(child.*, '${fn:replace(param.q,quote,escape)}')" scope="request" />
- <sling:findResources var="results" query="${query}" language="JCR-SQL2" />
- <c:choose>
- <c:when test="${not empty param.page}">
- <c:set var="start" value="${param.page * properties.limit}" />
- <c:set var="end" value="${(param.page * properties.limit) + properties.limit}" />
- </c:when>
- <c:otherwise>
- <c:set var="start" value="0" />
- <c:set var="end" value="${properties.limit}" />
- </c:otherwise>
- </c:choose>
- <c:forEach var="result" items="${results}" begin="${start}" end="${end}">
- <c:set var="result" value="${result}" scope="request" />
- <sling:call script="result.jsp" />
- </c:forEach>
- </c:catch>
- </c:if>
+ <c:forEach var="result" items="${search.results}">
+ <c:set var="result" value="${result}" scope="request" />
+ <sling:call script="result.jsp" />
+ </c:forEach>
</div>
<sling:call script="pagination.jsp" />
</div>
diff --git a/cms/ui/src/main/resources/jcr_root/apps/reference/components/general/stylewrapper/edit.json b/cms/ui/src/main/resources/jcr_root/apps/reference/components/general/stylewrapper/edit.json
index 8dfa516..cfec221 100644
--- a/cms/ui/src/main/resources/jcr_root/apps/reference/components/general/stylewrapper/edit.json
+++ b/cms/ui/src/main/resources/jcr_root/apps/reference/components/general/stylewrapper/edit.json
@@ -5,11 +5,11 @@
"fields": {
"jcr:primaryType": "nt:unstructured",
"sling:resourceType": "sling-cms/components/general/container",
- "styles": {
+ "style": {
"jcr:primaryType": "nt:unstructured",
"sling:resourceType": "sling-cms/components/editor/fields/select",
"label": "Style Option",
- "name": "styles",
+ "name": "style",
"required": true,
"optionsScript": "/apps/reference/components/general/stylewrapper/options.jsp"
}
--
To stop receiving notification emails like this one, please contact
dklco@apache.org.