From 4a826ff2748eafdbf63dd0547706ed7dc7ed3d76 Mon Sep 17 00:00:00 2001 From: Oscar Najera Date: Thu, 9 Nov 2023 17:49:27 +0100 Subject: Search page --- assets/js/search.js | 65 ++++++++++++++++++++++++++++++++++++++++++++ layouts/404.html | 12 +++++--- layouts/_default/search.html | 45 ++++++++++++++++++++++++++++++ layouts/_default/search.json | 13 +++++++++ 4 files changed, 131 insertions(+), 4 deletions(-) create mode 100644 assets/js/search.js create mode 100644 layouts/_default/search.html create mode 100644 layouts/_default/search.json diff --git a/assets/js/search.js b/assets/js/search.js new file mode 100644 index 0000000..2dd397a --- /dev/null +++ b/assets/js/search.js @@ -0,0 +1,65 @@ +// Options for fuse.js +let fuseOptions = { + includeMatches: true, + includeScore: true, + ignoreLocation: true, + minMatchCharLength: 3, + keys: [ + { name: "title", weight: 0.8 }, + { name: "contents", weight: 0.4 }, + { name: "tags", weight: 0.5 }, + { name: "categories", weight: 0.5 }, + ], +} + +function getUrlParameter(name) { + const urlParams = new URLSearchParams(location.search) + return urlParams.get(name) +} + +let searchQuery = getUrlParameter("q") +if (searchQuery) { + document.getElementById("search-query").value = searchQuery + executeSearch(searchQuery) +} else { + document.getElementById("search-results").innerHTML = "" +} + +function executeSearch(searchQuery) { + // Look for "index.json" in the same directory where this script is called. + fetch("index.json") + .then((response) => response.json()) + .then(function (data) { + let fuse = new Fuse(data, fuseOptions) + let result = fuse.search(searchQuery) + // console.log("Results: ", result) + if (result.length > 0) { + populateResults(result) + } else { + document.getElementById("search-results").innerHTML = + "

No matches found

" + } + }) +} + +function populateResults(result) { + result.forEach(function (value, key) { + // Lifted from https://stackoverflow.com/posts/3700369/revisions + var elem = document.createElement("textarea") + elem.innerHTML = value.item.contents + var decoded = elem.value + + // Pull template from hugo template definition + let frag = document + .getElementById("search-result-template") + .content.cloneNode(true) + // Replace values + frag.querySelector(".search_summary").setAttribute("id", "summary-" + key) + frag.querySelector(".search_link") + .setAttribute("href", value.item.permalink) + frag.querySelector(".search_title").textContent = value.item.title + frag.querySelector(".search_snippet").textContent = decoded + frag.querySelector(".search_time").textContent = value.item.date + document.getElementById("search-results").appendChild(frag) + }) +} diff --git a/layouts/404.html b/layouts/404.html index c375edb..af1122f 100644 --- a/layouts/404.html +++ b/layouts/404.html @@ -5,14 +5,12 @@

{{ .Title }}

-

- Perhaps you were looking for one of these? -

+

Perhaps you were looking for one of these?

{{ $query := where (where (where (where site.RegularPages.ByDate.Reverse "Title" "!=" "") "Kind" "in" (slice "page" "section")) "Params.private" "!=" true) "Permalink" "!=" "" }} {{ $count := len $query }} {{ if gt $count 0 }} -

Pages recently edited

+

Pages recently edited

{{ end }} + +

+ + Not there? Try using the search page. +

+
{{ end }} diff --git a/layouts/_default/search.html b/layouts/_default/search.html new file mode 100644 index 0000000..bcbaad4 --- /dev/null +++ b/layouts/_default/search.html @@ -0,0 +1,45 @@ +{{ define "main" }} +
+
+

+ {{ .Title }} +

+
+ +
+ +
+ +
+
+ + + + + {{ with resources.Get "js/search.js" | resources.Minify | fingerprint }} + + {{ end }} +{{ end }} diff --git a/layouts/_default/search.json b/layouts/_default/search.json new file mode 100644 index 0000000..16912cb --- /dev/null +++ b/layouts/_default/search.json @@ -0,0 +1,13 @@ + +{{ $dateFormat := .Site.Params.dateFormat | default "Jan 2, 2006" }} +{{- $.Scratch.Add "index" slice -}} +{{- range (where .Site.RegularPages "Type" "in" .Site.Params.mainSections) -}} + + {{- $.Scratch.Add "index" (dict "title" .Title + "tags" .Params.tags + "categories" .Params.categories + "contents" (.Summary | plainify) + "date" (.Date.Format $dateFormat) + "permalink" .Permalink) -}} +{{- end -}} +{{- $.Scratch.Get "index" | jsonify -}} -- cgit v1.2.3