This is an automated email from the ASF dual-hosted git repository.
paulk pushed a commit to branch asf-site
in repository https://gitbox.apache.org/repos/asf/groovy-website.git
The following commit(s) were added to refs/heads/asf-site by this push:
new 0b140e1 provide partial fix for search (fixes #65)
0b140e1 is described below
commit 0b140e1bd3e4988ea2b3b3978b126069f4d56a59
Author: Paul King <[email protected]>
AuthorDate: Thu Jan 29 17:56:54 2026 +1000
provide partial fix for search (fixes #65)
currently generates an index just for the dev site not groovy-lang
---
site-dev/build.gradle | 52 +++++++++++++++++++++++++++++-
site/src/site/assets/js/search.js | 40 +++++++++++++++++++++++
site/src/site/assets/js/vendor/lunr.min.js | 6 ++++
site/src/site/pages/devsearch.groovy | 52 ++++++++++++++++++++++++++++++
site/src/site/sitemap-dev.groovy | 2 +-
5 files changed, 150 insertions(+), 2 deletions(-)
diff --git a/site-dev/build.gradle b/site-dev/build.gradle
index e8b6138..8fc5693 100644
--- a/site-dev/build.gradle
+++ b/site-dev/build.gradle
@@ -58,7 +58,7 @@ tasks.register('copyAssets', Copy) {
}
}
filesMatching('**/*.js') { f->
- if (!f.name.contains('.min.')) {
+ if (!f.name.contains('.min.') && !f.name.contains('search')) {
filter(JsFilter)
}
}
@@ -92,6 +92,56 @@ tasks.register('generateSite', JavaExec) {
systemProperties.docs_baseurl = System.getProperty('docs_baseurl')
}
+import groovy.json.JsonOutput
+
+tasks.register('generateSearchIndex') {
+ group = 'documentation'
+ description = 'Generate search index for site-dev documentation'
+ ext.outputDir = project.layout.buildDirectory.dir('site')
+
+ dependsOn 'generateSite'
+
+ doLast {
+ def htmlRoot = file(outputDir)
+ def outDir = new File(htmlRoot, "search")
+ outDir.mkdirs()
+
+ def index = []
+
+ fileTree(htmlRoot).matching {
+ include '**/*.html'
+ exclude 'search/**'
+ }.each { File html ->
+
+ def text = html.text
+ .replaceAll(/<script.*?<\/script>/, '')
+ .replaceAll(/<style.*?<\/style>/, '')
+ .replaceAll(/<\/?[^>]+>/, ' ')
+ .replaceAll(/\s+/, ' ')
+ .trim()
+
+ def title = (html.text =~ /<title>(.*?)<\/title>/)?.with {
+ it ? it[0][1] : html.name
+ }
+
+ def url = html.path
+ .substring(html.path.indexOf('/site/') + 6)
+ .replace('\\', '/')
+
+ index << [
+ id : url,
+ title : title,
+ content : text,
+ url : url,
+ site : 'dev'
+ ]
+ }
+
+ new File(outDir, 'search-index.json').text =
+ JsonOutput.prettyPrint(JsonOutput.toJson(index))
+ }
+}
+
tasks.register('checkDeadLinks') {
dependsOn generateSite
description = 'Checks for dead links in the generated Groovy website'
diff --git a/site/src/site/assets/js/search.js
b/site/src/site/assets/js/search.js
new file mode 100644
index 0000000..514a81d
--- /dev/null
+++ b/site/src/site/assets/js/search.js
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+let idx = null;
+let documents = [];
+
+fetch('search/search-index.json')
+ .then(r => r.json())
+ .then(data => {
+ documents = data;
+ idx = lunr(function () {
+ this.ref('id');
+ this.field('title');
+ this.field('content');
+
+ data.forEach(d => this.add(d));
+ });
+ });
+
+function doSearch(query) {
+ if (!idx || !query) return [];
+ return idx.search(query).map(r =>
+ documents.find(d => d.id === r.ref)
+ );
+}
diff --git a/site/src/site/assets/js/vendor/lunr.min.js
b/site/src/site/assets/js/vendor/lunr.min.js
new file mode 100644
index 0000000..ae2661c
--- /dev/null
+++ b/site/src/site/assets/js/vendor/lunr.min.js
@@ -0,0 +1,6 @@
+/**
+ * lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as
bright - 2.3.9
+ * Copyright (C) 2020 Oliver Nightingale
+ * @license MIT
+ */
+!function(){var e=function(t){var r=new e.Builder;return
r.pipeline.add(e.trimmer,e.stopWordFilter,e.stemmer),r.searchPipeline.add(e.stemmer),t.call(r,r),r.build()};e.version="2.3.9",e.utils={},e.utils.warn=function(e){return
function(t){e.console&&console.warn&&console.warn(t)}}(this),e.utils.asString=function(e){return
void
0===e||null===e?"":e.toString()},e.utils.clone=function(e){if(null===e||void
0===e)return e;for(var
t=Object.create(null),r=Object.keys(e),i=0;i<r.length;i++){var n [...]
\ No newline at end of file
diff --git a/site/src/site/pages/devsearch.groovy
b/site/src/site/pages/devsearch.groovy
new file mode 100644
index 0000000..8e510a4
--- /dev/null
+++ b/site/src/site/pages/devsearch.groovy
@@ -0,0 +1,52 @@
+layout 'layouts/main.groovy', true,
+ pageTitle: 'The Apache Groovy programming language - Search',
+ mainContent: contents {
+ div(id: 'content', class: 'page-1') {
+ div(class: 'row') {
+ div(class: 'row-fluid') {
+
+ div(class: 'col-lg-3') {}
+
+ div(class: 'col-lg-8 col-lg-pull-0') {
+
+ include template:
'includes/contribute-button.groovy'
+
+ h1 {
+ i(class: 'fa-classic fa-solid
fa-magnifying-glass') {}
+ yield ' Search'
+ }
+
+ p '''
+ You can search the Groovy developer documentation
and site-dev pages.
+ Type your query below and see results instantly:
+ '''
+
+ div(id: 'search-container') {
+ input(type: 'search', id: 'q', placeholder:
'Search developer docs…', style: 'width: 100%; padding: 0.5em; font-size: 1em;')
+ div(id: 'results', style: 'margin-top: 1em;')
+ }
+
+ // Load Lunr.js and search logic
+ script(src: 'js/vendor/lunr.min.js', '')
+ script(src: 'js/search.js', '')
+
+ // Optional: init JS for live search
+ script '''
+
document.getElementById('q').addEventListener('input', function (e) {
+ const results = doSearch(e.target.value);
+ const out = document.getElementById('results');
+ out.innerHTML = '';
+ results.forEach(r => {
+ const div = document.createElement('div');
+ div.innerHTML = '<p><a href="' + r.url +
'">' + r.title + '</a></p>';
+ out.appendChild(div);
+ });
+ });
+ '''
+
+ hr(class: 'divider')
+ }
+ }
+ }
+ }
+ }
diff --git a/site/src/site/sitemap-dev.groovy b/site/src/site/sitemap-dev.groovy
index a2b5598..5936c28 100644
--- a/site/src/site/sitemap-dev.groovy
+++ b/site/src/site/sitemap-dev.groovy
@@ -60,7 +60,7 @@ menu {
pages {
// page 'index', 'index', [:]
- page 'search', 'search', [category: 'Search']
+ page 'devsearch', 'search', [category: 'Search']
page 'download', 'download', [category: 'Download', distributions:
distributions]
page 'versioning', 'versioning', [category: 'Download']
page 'snapshots', 'snapshots', [category: 'Develop']