diff options
| -rw-r--r-- | haunt.scm | 2 | ||||
| -rw-r--r-- | jakob/builder/blog.scm | 5 | ||||
| -rw-r--r-- | jakob/builder/search.scm | 39 | ||||
| -rw-r--r-- | jakob/theme.scm | 2 | ||||
| -rw-r--r-- | static/js/search.js | 58 |
5 files changed, 103 insertions, 3 deletions
@@ -27,6 +27,7 @@ (jakob builder index) (jakob builder outbox) (jakob builder projects) + (jakob builder search) (jakob reader html-prime) (jakob reader org-mode-prime) (jakob theme) @@ -53,6 +54,7 @@ #:builders (list (atom-feed #:max-entries 1024) (index) + (search) (blog) (blogroll) (outbox) diff --git a/jakob/builder/blog.scm b/jakob/builder/blog.scm index 94b77d5..bb5567c 100644 --- a/jakob/builder/blog.scm +++ b/jakob/builder/blog.scm @@ -55,9 +55,10 @@ (define (render-article post) "Return the SHTML for POST's contents." - #<(article (@ (class "update-entry")) + #<(article (@ (class "update-entry") + (data-pagefind-body "1")) (h1 (@ (class "section-header")) - ,(format #f "Blog :: ~a" (post-ref post 'title))) + ,(format #f "Blog :: ~a" (post-ref post 'title))) (div (@ (class "date-stamp")) (time (@ (datetime ,(date->string (post-date post) "~Y-~m-~d"))) ,(date->string (post-date post) "~B ~d, ~Y")) diff --git a/jakob/builder/search.scm b/jakob/builder/search.scm new file mode 100644 index 0000000..df8e94f --- /dev/null +++ b/jakob/builder/search.scm @@ -0,0 +1,39 @@ +;;; Copyright © 2019 - 2026 Jakob L. Kreuze <zerodaysfordays@sdf.org> +;;; +;;; This program is free software; you can redistribute it and/or +;;; modify it under the terms of the GNU General Public License as +;;; published by the Free Software Foundation; either version 3 of the +;;; License, or (at your option) any later version. +;;; +;;; This program is distributed in the hope that it will be useful, +;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;; General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with this program. If not, see +;;; <http://www.gnu.org/licenses/>. + +(define-module (jakob builder search) + #:use-module (haunt artifact) + #:use-module (haunt html) + #:use-module (jakob theme) + #:use-module (jakob utils sxml) + #:export (search)) + +(define (search) + "Return a Haunt build procedure to create an index page." + (lambda (site posts) + `(,(serialized-artifact "search.html" + (theme #:title "Search Results" + ;; #:description (description-from-post post) + ;; #:keywords (post-ref post 'tags) + ;; #:meta (if (not (eof-object? meta-tags)) meta-tags '()) + ;; #:scripts (if (not (eof-object? scripts)) scripts '()) + #:content `((main (@ (class "main-content")) + (section (@ (id "search-results")) + (h2 (@ (class "section-header")) "Search Results") + (div (@ (id "search-output")) + (noscript "Javascript must be enabled for search.")))) + ,(script "search.js"))) + sxml->html)))) diff --git a/jakob/theme.scm b/jakob/theme.scm index 0cfebd6..65aaf51 100644 --- a/jakob/theme.scm +++ b/jakob/theme.scm @@ -73,7 +73,7 @@ (class "module-title module-title-has-icon") (style ,(fugue-icon-path "magnifier"))) "Search") - (form (@ (action "/search") + (form (@ (action "/search.html") (method "GET") (role "search") (style "display: flex; gap: 5px;")) diff --git a/static/js/search.js b/static/js/search.js new file mode 100644 index 0000000..7037386 --- /dev/null +++ b/static/js/search.js @@ -0,0 +1,58 @@ +/* + * search.js -- Alternative search results processor for pagefind. + * Copyright © 2022 - 2026 Jakob L. Kreuze <zerodaysfordays@sdf.org> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + */ + +window.addEventListener("load", async () => { + const pagefind = await import("/_pagefind/pagefind.js"); + pagefind.init(); + + const params = new URLSearchParams(window.location.search); + const query = params.get('q'); + const outputContainer = document.getElementById('search-output'); + + if (query) { + const search = await pagefind.search(query); + + if (search.results.length === 0) { + outputContainer.innerHTML = `<p>No results found for "<strong>${query}</strong>".</p>`; + return; + } + + outputContainer.innerHTML = `<p style="font-size: 9px; color: #999; margin-bottom: 20px;"> + Found ${search.results.length} result(s) for "<strong>${query}</strong>": + </p>`; + + for (let result of search.results) { + const data = await result.data(); + + const resultElement = document.createElement('article'); + resultElement.className = 'update-entry'; + console.log(data); + resultElement.innerHTML = ` + <header> + <h3 class="title"><a href="${data.url}">${data.meta.title}</a></h3> + </header> + <p>${data.excerpt} ...</p> + <p><a href="${data.url}">view page →</a></p> + `; + outputContainer.appendChild(resultElement); + } + } else { + outputContainer.innerHTML = `<p>Searching for '${query}'...</p>`; + } +}); |