Add search

master
Will Faught 3 years ago
parent 038f020aee
commit 11561c1853

@ -48,6 +48,7 @@ Term page:
- Minimal design - Minimal design
- Responsive - Responsive
- Safari and Firefox Reader View support - Safari and Firefox Reader View support
- Search
- Sections - Sections
- Single column - Single column
- Social links - Social links
@ -91,6 +92,9 @@ Single pages use the `link` page parameter, if any, as the reference for
an anchor around the page title, if any. If the page or site parameter an anchor around the page title, if any. If the page or site parameter
`math` is set to true, math typesetting is enabled with KaTeX. `math` is set to true, math typesetting is enabled with KaTeX.
The `paige_search` layout provides full site search. It requires setting
`outputs.home` to `["html", "json", "rss"]` in `config.yaml`.
If `partials/paige_head_last.html` exists in the site, it is included at If `partials/paige_head_last.html` exists in the site, it is included at
the end of the head tag. If `partials/paige_body_last.html` exists in the end of the head tag. If `partials/paige_body_last.html` exists in
the site, it is included at the end of the body tag. the site, it is included at the end of the body tag.

@ -33,6 +33,15 @@ menu:
name: Tags name: Tags
weight: 70 weight: 70
url: /tags/ url: /tags/
- identifier: search
name: Search
weight: 80
url: /search/
outputs:
home:
- html
- json
- rss
paginate: 50 paginate: 50
params: params:
paigehidethemecomment: true paigehidethemecomment: true

@ -0,0 +1,4 @@
---
layout: paige_search
title: Search
---

@ -0,0 +1,5 @@
{{- $.Scratch.Add "index" slice -}}
{{- range .Site.RegularPages -}}
{{- $.Scratch.Add "index" (dict "title" (.Title | markdownify | plainify | htmlUnescape) "description" (.Description | markdownify | plainify | htmlUnescape) "date" .PublishDate "categories" .Params.categories "tags" .Params.tags "keywords" .Params.keywords "text" (strings.TrimRight " " (replace (.Plain | htmlUnescape) "\n" " ")) "link" .RelPermalink) -}}
{{- end -}}
{{- $.Scratch.Get "index" | jsonify -}}

@ -0,0 +1,4 @@
{{ define "main" }}
{{ partial "paige_main.html" . }}
{{ partial "paige_search.html" . }}
{{ end }}

@ -0,0 +1,108 @@
<div class="container-fluid">
<form action="{{ .Page.RelPermalink }}" method="get">
<div class="justify-content-center row mb-3">
<div class="col col-sm-8 col-md-7 col-lg-6 col-xl-5 col-xxl-4">
<input aria-label="Query" class="form-control" id="query" name="q" type="search" placeholder="Query">
</div>
</div>
<div class="justify-content-center row">
<div class="col-auto">
<button class="btn btn-primary" type="submit">Search</button>
</div>
</div>
</form>
</div>
<div id="paige-error" style="display: none">
<p class="lead text-center text-danger">Error</p>
</div>
<div id="paige-searching" style="display: none">
<p class="lead text-center">Searching...</p>
</div>
<div id="paige-nothing" style="display: none">
<p class="lead text-center">Found nothing</p>
</div>
<div id="paige-something" style="display: none">
<p class="lead text-center">Found something</p>
</div>
<script crossorigin="anonymous" defer integrity="sha384-1LalyFI+BycKouEClZE5CoFnlLr+Kx8Wslc45o5NATVo+c2mEh02i8HNaaT7XOdQ" referrerpolicy="no-referrer" src="https://cdn.jsdelivr.net/gh/nextapps-de/flexsearch@0.7.31/dist/flexsearch.bundle.js"></script>
<script>
var errorElement = document.getElementById("paige-error");
var nothingElement = document.getElementById("paige-nothing");
var queryElement = document.getElementById("query");
var searchingElement = document.getElementById("paige-searching")
var somethingElement = document.getElementById("paige-something");
if (queryElement !== null) {
var queryText = decodeURIComponent((location.search.split("q=")[1] || "").split("&")[0]).replace(/\+/g, " ");
if (queryText) {
queryElement.value = queryText;
search(queryText);
}
}
function search(queryText) {
show(searchingElement);
fetch("/index.json").then(function (response) {
if (response.status !== 200) {
console.log("Cannot load /index.json", response);
hide(searchingElement);
show(errorElement);
return;
}
response.json().then(function (pages) {
var index = new FlexSearch.Document({
document: {
id: "link",
index: ["categories", "description", "keywords", "tags", "text", "title"]
}
});
var pathPage = {};
pages.forEach(function (page) {
index.add(page);
pathPage[page.link] = page;
});
var results = index.search(queryText, {limit: 50});
hide(searchingElement);
var shown = false;
var done = {};
results.forEach(function (result) {
result.result.forEach(function (path) {
if (path === "{{ .RelPermalink }}" || done[path]) {
return;
}
if (!shown) {
shown = true;
show(somethingElement);
}
done[path] = true;
var page = pathPage[path];
var link = document.createElement("a");
link.href = page.link;
link.innerText = page.title;
var result = document.createElement("p");
result.classList = "text-center";
result.appendChild(link);
if (page.description) {
result.appendChild(document.createElement("br"));
result.innerHTML += page.description;
}
somethingElement.appendChild(result);
});
});
if (!shown) {
show(nothingElement);
}
}).catch(function (error) {
console.log("Cannot search /index.json", error);
});
});
}
function hide(element) {
element.style.display = "none";
}
function show(element) {
element.style.display = "block";
}
</script>
Loading…
Cancel
Save