Link to search page + cleanup client-side code
diff --git a/org.apache.sling.graphql.samples.website/src/main/java/org/apache/sling/graphql/samples/website/datafetchers/ArticlesBySectionFetcher.java b/org.apache.sling.graphql.samples.website/src/main/java/org/apache/sling/graphql/samples/website/datafetchers/ArticlesBySectionFetcher.java
index a466d53..0458736 100644
--- a/org.apache.sling.graphql.samples.website/src/main/java/org/apache/sling/graphql/samples/website/datafetchers/ArticlesBySectionFetcher.java
+++ b/org.apache.sling.graphql.samples.website/src/main/java/org/apache/sling/graphql/samples/website/datafetchers/ArticlesBySectionFetcher.java
@@ -46,8 +46,6 @@
// TODO should paginate instead
final int maxArticles = 42;
- final Resource currentResource = FetcherUtil.getSourceResource(env, section);
-
final List<Map<String, Object>> result = new ArrayList<>();
final Iterable<Resource> it = () -> section.getResourceResolver().getChildren(section).iterator();
StreamSupport.stream(it.spliterator(), false)
diff --git a/org.apache.sling.graphql.samples.website/src/main/java/org/apache/sling/graphql/samples/website/datafetchers/ArticlesWithTextFetcher.java b/org.apache.sling.graphql.samples.website/src/main/java/org/apache/sling/graphql/samples/website/datafetchers/ArticlesWithTextFetcher.java
index 065e111..dea5fcb 100644
--- a/org.apache.sling.graphql.samples.website/src/main/java/org/apache/sling/graphql/samples/website/datafetchers/ArticlesWithTextFetcher.java
+++ b/org.apache.sling.graphql.samples.website/src/main/java/org/apache/sling/graphql/samples/website/datafetchers/ArticlesWithTextFetcher.java
@@ -46,8 +46,8 @@
public Object get(DataFetchingEnvironment environment) throws Exception {
final String expectedText = environment.getArgument(P_WITH_TEXT);
final String jcrQuery = String.format(
- "/jcr:root/content/articles//*[jcr:contains(@text, '%s') or jcr:contains(@title, '%s')]",
- expectedText, expectedText);
+ "/jcr:root%s//*[jcr:contains(@text, '%s') or jcr:contains(@title, '%s')]",
+ Constants.ARTICLES_ROOT, expectedText, expectedText);
final List<Map<String, Object>> result = new ArrayList<>();
final Iterator<Resource> it = resource.getResourceResolver().findResources(jcrQuery, "xpath");
diff --git a/org.apache.sling.graphql.samples.website/src/main/java/org/apache/sling/graphql/samples/website/datafetchers/Constants.java b/org.apache.sling.graphql.samples.website/src/main/java/org/apache/sling/graphql/samples/website/datafetchers/Constants.java
new file mode 100644
index 0000000..2dafd58
--- /dev/null
+++ b/org.apache.sling.graphql.samples.website/src/main/java/org/apache/sling/graphql/samples/website/datafetchers/Constants.java
@@ -0,0 +1,29 @@
+/*
+ * 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.graphql.samples.website.datafetchers;
+
+class Constants {
+ private Constants() {
+ }
+
+ public static final String ARTICLES_ROOT = "/content/articles";
+ public static final String ARTICLE_RESOURCE_SUPERTYPE = "samples/article";
+ public static final String SEARCH_PAGE_PATH = "/content/search";
+}
\ No newline at end of file
diff --git a/org.apache.sling.graphql.samples.website/src/main/java/org/apache/sling/graphql/samples/website/datafetchers/NavigationDataFetcher.java b/org.apache.sling.graphql.samples.website/src/main/java/org/apache/sling/graphql/samples/website/datafetchers/NavigationDataFetcher.java
index 9fe2dd1..a8613f1 100644
--- a/org.apache.sling.graphql.samples.website/src/main/java/org/apache/sling/graphql/samples/website/datafetchers/NavigationDataFetcher.java
+++ b/org.apache.sling.graphql.samples.website/src/main/java/org/apache/sling/graphql/samples/website/datafetchers/NavigationDataFetcher.java
@@ -39,8 +39,6 @@
class NavigationDataFetcher implements DataFetcher<Object> {
public static final String NAME = "navigation";
- public static final String CONTENT_ROOT = "/content/articles";
- public static final String ARTICLE_RESOURCE_SUPERTYPE = "samples/article";
private final Resource resource;
@@ -50,7 +48,7 @@
private Object[] getSections() {
final List<Map<String, Object>> result = new ArrayList<>();
- final Resource root = resource.getResourceResolver().getResource(CONTENT_ROOT);
+ final Resource root = resource.getResourceResolver().getResource(Constants.ARTICLES_ROOT);
final Iterable<Resource> it = () -> root.getResourceResolver().getChildren(root).iterator();
StreamSupport.stream(it.spliterator(), false)
.forEach(child -> result.add(SlingWrappers.resourceWrapper(child)));
@@ -61,7 +59,8 @@
String getNextOrPreviousPath(Resource r, String propertyName, String currentValue, boolean isNext) {
String result = null;
final String jcrQuery = String.format(
- "/jcr:root/content/articles//*[%s %s '%s'] order by %s %s",
+ "/jcr:root%s//*[%s %s '%s'] order by %s %s",
+ Constants.ARTICLES_ROOT,
propertyName,
isNext ? ">" : "<",
currentValue,
@@ -78,7 +77,7 @@
/** If r is an article, add previous/next navigation based on article filenames */
private void maybeAddPrevNext(Map<String, Object> result, Resource r) {
final String propName = "filename";
- if(ARTICLE_RESOURCE_SUPERTYPE.equals(r.getResourceSuperType())) {
+ if(Constants.ARTICLE_RESOURCE_SUPERTYPE.equals(r.getResourceSuperType())) {
final String filename = r.adaptTo(ValueMap.class).get(propName, String.class);
if(filename != null) {
result.put("previous", getNextOrPreviousPath(r, propName, filename, false));
@@ -90,8 +89,9 @@
@Override
public Object get(DataFetchingEnvironment env) throws Exception {
final Map<String, Object> result = new HashMap<>();
- result.put("root", CONTENT_ROOT);
+ result.put("root", Constants.ARTICLES_ROOT);
result.put("sections", getSections());
+ result.put("search", Constants.SEARCH_PAGE_PATH);
maybeAddPrevNext(result, FetcherUtil.getSourceResource(env, resource));
return result;
}
diff --git a/org.apache.sling.graphql.samples.website/src/main/java/org/apache/sling/graphql/samples/website/datafetchers/SeeAlsoDataFetcher.java b/org.apache.sling.graphql.samples.website/src/main/java/org/apache/sling/graphql/samples/website/datafetchers/SeeAlsoDataFetcher.java
index d9ea5c7..b07c051 100644
--- a/org.apache.sling.graphql.samples.website/src/main/java/org/apache/sling/graphql/samples/website/datafetchers/SeeAlsoDataFetcher.java
+++ b/org.apache.sling.graphql.samples.website/src/main/java/org/apache/sling/graphql/samples/website/datafetchers/SeeAlsoDataFetcher.java
@@ -47,7 +47,7 @@
* we can use the full path + title to render links.
*/
private static Map<String, Object> toArticleRef(ResourceResolver resolver, String nodeName) {
- final String jcrQuery = String.format("/jcr:root/content/articles//*[@filename='%s']", nodeName);
+ final String jcrQuery = String.format("/jcr:root%s//*[@filename='%s']", Constants.ARTICLES_ROOT, nodeName);
final Iterator<Resource> it = resolver.findResources(jcrQuery, "xpath");
// We want exactly one result
diff --git a/org.apache.sling.graphql.samples.website/src/main/java/org/apache/sling/graphql/samples/website/datafetchers/TagQueryDataFetcher.java b/org.apache.sling.graphql.samples.website/src/main/java/org/apache/sling/graphql/samples/website/datafetchers/TagQueryDataFetcher.java
index 8c7d54d..34cc0fc 100644
--- a/org.apache.sling.graphql.samples.website/src/main/java/org/apache/sling/graphql/samples/website/datafetchers/TagQueryDataFetcher.java
+++ b/org.apache.sling.graphql.samples.website/src/main/java/org/apache/sling/graphql/samples/website/datafetchers/TagQueryDataFetcher.java
@@ -46,7 +46,7 @@
static String jcrQuery(String ... tags) {
// Build a query like
// /jcr:root/content/articles//*[@tags = "panel" and @tags = "card"]
- final StringBuilder sb = new StringBuilder("/jcr:root/content/articles//*[");
+ final StringBuilder sb = new StringBuilder("/jcr:root" + Constants.ARTICLES_ROOT + "//*[");
for(int i=0 ; i < tags.length; i++) {
if(i > 0) {
sb.append(" and ");
diff --git a/org.apache.sling.graphql.samples.website/src/main/resources/SLING-INF/initial-content/apps/samples/article/article.hbs b/org.apache.sling.graphql.samples.website/src/main/resources/SLING-INF/initial-content/apps/samples/article/article.hbs
index e33b48e..cdbffe6 100644
--- a/org.apache.sling.graphql.samples.website/src/main/resources/SLING-INF/initial-content/apps/samples/article/article.hbs
+++ b/org.apache.sling.graphql.samples.website/src/main/resources/SLING-INF/initial-content/apps/samples/article/article.hbs
@@ -38,6 +38,7 @@
{{#if data.navigation.next}}
<a href="{{data.navigation.next}}.html">Next article</a>
{{/if}}
+ <a href="{{data.navigation.search}}.html">Search</a>
<hr/>
</div>
diff --git a/org.apache.sling.graphql.samples.website/src/main/resources/SLING-INF/initial-content/apps/samples/article/json.gql b/org.apache.sling.graphql.samples.website/src/main/resources/SLING-INF/initial-content/apps/samples/article/json.gql
index 8531cbd..58d0729 100644
--- a/org.apache.sling.graphql.samples.website/src/main/resources/SLING-INF/initial-content/apps/samples/article/json.gql
+++ b/org.apache.sling.graphql.samples.website/src/main/resources/SLING-INF/initial-content/apps/samples/article/json.gql
@@ -21,6 +21,7 @@
root
previous
next
+ search
sections {
path
name
diff --git a/org.apache.sling.graphql.samples.website/src/main/resources/SLING-INF/initial-content/apps/samples/common/GQLschema.jsp b/org.apache.sling.graphql.samples.website/src/main/resources/SLING-INF/initial-content/apps/samples/common/GQLschema.jsp
index abfeb49..512ef90 100644
--- a/org.apache.sling.graphql.samples.website/src/main/resources/SLING-INF/initial-content/apps/samples/common/GQLschema.jsp
+++ b/org.apache.sling.graphql.samples.website/src/main/resources/SLING-INF/initial-content/apps/samples/common/GQLschema.jsp
@@ -34,6 +34,8 @@
previous: String
# Next article, if application
next: String
+ # Search page
+ search: String
}
# A content section with its name and path
diff --git a/org.apache.sling.graphql.samples.website/src/main/resources/SLING-INF/initial-content/apps/samples/section/json.gql b/org.apache.sling.graphql.samples.website/src/main/resources/SLING-INF/initial-content/apps/samples/section/json.gql
index 81c5e13..7c4ff63 100644
--- a/org.apache.sling.graphql.samples.website/src/main/resources/SLING-INF/initial-content/apps/samples/section/json.gql
+++ b/org.apache.sling.graphql.samples.website/src/main/resources/SLING-INF/initial-content/apps/samples/section/json.gql
@@ -19,6 +19,7 @@
{
navigation {
root
+ search
sections {
path
name
diff --git a/org.apache.sling.graphql.samples.website/src/main/resources/SLING-INF/initial-content/apps/samples/section/section.hbs b/org.apache.sling.graphql.samples.website/src/main/resources/SLING-INF/initial-content/apps/samples/section/section.hbs
index 9c3199f..e28eeed 100644
--- a/org.apache.sling.graphql.samples.website/src/main/resources/SLING-INF/initial-content/apps/samples/section/section.hbs
+++ b/org.apache.sling.graphql.samples.website/src/main/resources/SLING-INF/initial-content/apps/samples/section/section.hbs
@@ -31,6 +31,8 @@
<a href="{{this.path}}.html">{{this.name}}</a>
</span>
{{/each}}
+ <br/>
+ <a href="{{data.navigation.search}}.html">Search</a>
<hr/>
</div>
<div class="title">
diff --git a/org.apache.sling.graphql.samples.website/src/main/resources/SLING-INF/initial-content/apps/samples/tag/json.gql b/org.apache.sling.graphql.samples.website/src/main/resources/SLING-INF/initial-content/apps/samples/tag/json.gql
index 383d8a0..8e88e34 100644
--- a/org.apache.sling.graphql.samples.website/src/main/resources/SLING-INF/initial-content/apps/samples/tag/json.gql
+++ b/org.apache.sling.graphql.samples.website/src/main/resources/SLING-INF/initial-content/apps/samples/tag/json.gql
@@ -19,6 +19,7 @@
{
navigation {
root
+ search
sections {
path
name
diff --git a/org.apache.sling.graphql.samples.website/src/main/resources/SLING-INF/initial-content/apps/samples/tag/tag.hbs b/org.apache.sling.graphql.samples.website/src/main/resources/SLING-INF/initial-content/apps/samples/tag/tag.hbs
index 7c04a0b..8d542ba 100644
--- a/org.apache.sling.graphql.samples.website/src/main/resources/SLING-INF/initial-content/apps/samples/tag/tag.hbs
+++ b/org.apache.sling.graphql.samples.website/src/main/resources/SLING-INF/initial-content/apps/samples/tag/tag.hbs
@@ -31,6 +31,8 @@
<a href="{{this.path}}.html">{{this.name}}</a>
</span>
{{/each}}
+ <br/>
+ <a href="{{data.navigation.search}}.html">Search</a>
<hr/>
</div>
diff --git a/org.apache.sling.graphql.samples.website/src/main/resources/SLING-INF/initial-content/content/js/graphql.js b/org.apache.sling.graphql.samples.website/src/main/resources/SLING-INF/initial-content/content/js/graphql.js
new file mode 100644
index 0000000..31c66da
--- /dev/null
+++ b/org.apache.sling.graphql.samples.website/src/main/resources/SLING-INF/initial-content/content/js/graphql.js
@@ -0,0 +1,39 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~ 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.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+/** Minimal GraphQL client for our sample website */
+var graphQL = null;
+
+(function() {
+ graphQL = {
+ query : function(query, info, callback) {
+ fetch('/graphql.json', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ 'Accept': 'application/json',
+ },
+ body: JSON.stringify({query: `${query} `})
+ })
+ .then(r => r.json())
+ .then(json => callback ({ result: json.data, query: query, info: info}))
+ ;
+ }
+ }
+})();
\ No newline at end of file
diff --git a/org.apache.sling.graphql.samples.website/src/main/resources/SLING-INF/initial-content/content/search.html b/org.apache.sling.graphql.samples.website/src/main/resources/SLING-INF/initial-content/content/search.html
index 215d025..b97d7d3 100644
--- a/org.apache.sling.graphql.samples.website/src/main/resources/SLING-INF/initial-content/content/search.html
+++ b/org.apache.sling.graphql.samples.website/src/main/resources/SLING-INF/initial-content/content/search.html
@@ -33,25 +33,59 @@
</script>
<script
- src="https://cdn.jsdelivr.net/npm/handlebars@latest/dist/handlebars.js">
+ src="https://cdn.jsdelivr.net/npm/handlebars@4.7.6/dist/handlebars.js"
+ integrity="sha256-ZafrO8ZXERYO794Tx1hPaAcdcXNZUNmXufXOSe0Hxj8="
+ crossorigin="anonymous">
</script>
- <script src="./search.js"></script>
+ <script src="./js/graphql.js"></script>
+
+ <script>
+ var template;
+
+ function queryAndRender(searchText) {
+ var query = `{
+ article(withText: "${searchText}") {
+ path
+ title
+ seeAlso {
+ path
+ title
+ tags
+ }
+ }
+ }`;
+ console.log(`Querying:\n${query}`);
+ graphQL.query(query, { searchText: searchText}, function(data) {
+ $("#results").html(template({data:data}));
+ });
+ }
+
+ $(document).ready(function() {
+ template = Handlebars.compile($("#template").html());
+ $("#search").submit(function() {
+ queryAndRender($("#searchText").val());
+ return false;
+ });
+ });
+ </script>
</head>
<body>
<h1>Search in articles</h1>
<hr/>
+
<form id="search">
<input id="searchText" type="text" width="40"/>
<input type="submit" value="Search"/>
</form>
+
<div id="results"/>
<div id="template" style="display:none">
- <h2>Articles containing "{{data.query}}"</h2>
+ <h2>Found {{data.result.article.length}} articles containing "{{data.info.searchText}}"</h2>
<ul>
{{#each data.result.article}}
- <li class="seeAlso">
+ <li class="articleLink">
<a href="{{this.path}}.html">{{this.title}}</a>
</li>
{{/each}}
diff --git a/org.apache.sling.graphql.samples.website/src/main/resources/SLING-INF/initial-content/content/search.js b/org.apache.sling.graphql.samples.website/src/main/resources/SLING-INF/initial-content/content/search.js
deleted file mode 100644
index b3dccaa..0000000
--- a/org.apache.sling.graphql.samples.website/src/main/resources/SLING-INF/initial-content/content/search.js
+++ /dev/null
@@ -1,63 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-~ 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.
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-var template;
-
-function render(resultElement, data) {
- console.log(`Rendering ${data.result.article.length} articles`);
- $(resultElement).html(template({ data : data }));
-}
-
-function queryAndRender(queryText) {
- var query = `{
- article(withText: "${queryText}") {
- path
- title
- seeAlso {
- path
- title
- tags
- }
- }
- }`;
-
- console.log(`Querying:\n${query}`);
-
- fetch('/graphql.json', {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- 'Accept': 'application/json',
- },
- body: JSON.stringify({query: `${query} `})
- })
- .then(r => r.json())
- .then(json => render($("#results"), { result: json.data, query: queryText}))
- ;
-}
-
-$(document).ready(function() {
- template = Handlebars.compile($("#template").html());
- $("#search").submit(function(e) {
- var searchText = $("#searchText").val();
- queryAndRender(searchText);
- return false;
- });
-});
-