mirror of
https://github.com/Wonderfall/hugo-WonderMod.git
synced 2024-12-22 09:05:07 +01:00
search: init Search feature (#105)
* based on https://gist.github.com/cmod/5410eae147e4318164258742dd053993 * modified working for PaperMod * fetches current lang index.json for search * add fuse.js v6.4.3 LICENSE: Apache License 2.0 * bundled fastsearch and fusejs as search.js Co-authored-by: Craig Mod <stuff@craigmod.com>
This commit is contained in:
parent
c76233b350
commit
4a4408573e
40
assets/css/search.css
Normal file
40
assets/css/search.css
Normal file
@ -0,0 +1,40 @@
|
||||
.searchbox input {
|
||||
padding: 4px 10px;
|
||||
width: 100%;
|
||||
color: var(--primary);
|
||||
font-weight: bold;
|
||||
border: 2px solid var(--tertiary);
|
||||
border-radius: var(--radius);
|
||||
}
|
||||
|
||||
.searchbox input:focus {
|
||||
border-color: var(--secondary);
|
||||
}
|
||||
|
||||
#searchResults li {
|
||||
list-style: none;
|
||||
border-radius: var(--radius);
|
||||
padding: 10px;
|
||||
margin: 10px 0;
|
||||
position: relative;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
#searchResults {
|
||||
margin: 10px 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#searchResults li:active {
|
||||
transition: transform .1s;
|
||||
transform: scale(.98);
|
||||
}
|
||||
|
||||
#searchResults a {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
outline: none;
|
||||
}
|
57
assets/js/fastsearch.js
Normal file
57
assets/js/fastsearch.js
Normal file
@ -0,0 +1,57 @@
|
||||
var fuse; // holds our search engine
|
||||
|
||||
// load our search index, only executed onload
|
||||
function loadSearch() {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.onreadystatechange = function () {
|
||||
if (xhr.readyState === 4) {
|
||||
if (xhr.status === 200) {
|
||||
var data = JSON.parse(xhr.responseText);
|
||||
if (data) {
|
||||
// fuse.js options; check fuse.js website for details
|
||||
var options = {
|
||||
isCaseSensitive: false,
|
||||
shouldSort: true,
|
||||
location: 0,
|
||||
distance: 100,
|
||||
threshold: 0.4,
|
||||
minMatchCharLength: 0,
|
||||
keys: [
|
||||
'title',
|
||||
'permalink',
|
||||
'summary',
|
||||
'content'
|
||||
]
|
||||
};
|
||||
fuse = new Fuse(data, options); // build the index from the json file
|
||||
}
|
||||
} else {
|
||||
console.log(xhr.responseText);
|
||||
}
|
||||
}
|
||||
};
|
||||
xhr.open('GET', "../index.json");
|
||||
xhr.send();
|
||||
}
|
||||
|
||||
// execute search as each character is typed
|
||||
document.getElementById("searchInput").onkeyup = function (e) {
|
||||
// run a search query (for "term") every time a letter is typed
|
||||
// in the search box
|
||||
const results = fuse.search(this.value); // the actual query being run using fuse.js
|
||||
|
||||
if (results.length !== 0) {
|
||||
// build our html if result exists
|
||||
let resultSet = ''; // our results bucket
|
||||
|
||||
for (let item in results) {
|
||||
resultSet = resultSet + itemGen(results[item].item.title, results[item].item.permalink)
|
||||
}
|
||||
|
||||
document.getElementById("searchResults").innerHTML = resultSet;
|
||||
}
|
||||
}
|
||||
|
||||
function itemGen(name, link) {
|
||||
return `<li class="post-entry"><header class="entry-header">${name} »</header><a href="${link}" aria-label="${name}"></a></li>`
|
||||
}
|
2252
assets/js/fuse.js
Normal file
2252
assets/js/fuse.js
Normal file
File diff suppressed because it is too large
Load Diff
@ -6,7 +6,7 @@
|
||||
</head>
|
||||
|
||||
<body class="
|
||||
{{- if (or (ne .Kind `page` ) (eq .Layout `archives`)) -}}
|
||||
{{- if (or (ne .Kind `page` ) (eq .Layout `archives`) (eq .Layout `search`)) -}}
|
||||
{{- print "list" -}}
|
||||
{{- end -}}
|
||||
{{- if eq $.Site.Params.defaultTheme `dark` -}}
|
||||
|
6
layouts/_default/index.json
Normal file
6
layouts/_default/index.json
Normal file
@ -0,0 +1,6 @@
|
||||
{{- $.Scratch.Add "index" slice -}}
|
||||
{{- range .Site.RegularPages -}}
|
||||
{{- $.Scratch.Add "index" (dict "title" .Title "content" .Plain "permalink" .Permalink "summary" .Summary) -}}
|
||||
{{- end -}}
|
||||
{{- $.Scratch.Get "index" | jsonify -}}
|
||||
|
38
layouts/_default/search.html
Normal file
38
layouts/_default/search.html
Normal file
@ -0,0 +1,38 @@
|
||||
{{- define "main" }}
|
||||
|
||||
<header class="page-header">
|
||||
<h1>{{ .Title }}
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" viewBox="0 0 24 24" fill="none"
|
||||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<circle cx="11" cy="11" r="8"></circle>
|
||||
<line x1="21" y1="21" x2="16.65" y2="16.65"></line>
|
||||
</svg>
|
||||
</h1>
|
||||
{{- if .Params.hideMeta }}{{ else }}
|
||||
<div class="post-meta">
|
||||
{{- if .IsTranslated -}}
|
||||
<ul class="i18n_list">
|
||||
{{- i18n "translations" | default "Translations"}}:
|
||||
{{- range .Translations }}
|
||||
<li>
|
||||
<a href="{{ .Permalink }}">
|
||||
{{- if (and $.Site.Params.displayFullLangName (.Language.LanguageName)) }}
|
||||
{{- .Language.LanguageName | emojify | humanize -}}
|
||||
{{- else }}
|
||||
{{- .Lang | humanize -}}
|
||||
{{- end -}}
|
||||
</a>
|
||||
</li>
|
||||
{{- end }}
|
||||
</ul>
|
||||
{{- end }}
|
||||
</div>
|
||||
{{- end}}
|
||||
</header>
|
||||
|
||||
<div class="searchbox">
|
||||
<input id="searchInput" autofocus placeholder="{{.Title}} ↵" aria-label="search">
|
||||
<ul id="searchResults" aria-label="search results"></ul>
|
||||
</div>
|
||||
|
||||
{{- end }}{{/* end main */}}
|
@ -29,6 +29,22 @@
|
||||
{{- $stylesheet := (resources.Match "css/*.css") | resources.Concat "assets/css/stylesheet.css" | minify -}}
|
||||
<link href="{{ $stylesheet.Permalink }}" rel="preload stylesheet" as="style">
|
||||
{{- end}}
|
||||
<!-- Search -->
|
||||
{{- if (eq .Layout `search`) -}}
|
||||
<link rel="preload" as="fetch" href="../index.json" crossOrigin="anonymous">
|
||||
{{- $fastsearch := resources.Get "js/fastsearch.js" }}
|
||||
{{- $fusejs := resources.Get "js/fuse.js" }}
|
||||
{{- if not .Site.Params.assets.disableFingerprinting }}
|
||||
{{- $search := (slice $fusejs $fastsearch ) | resources.Concat "assets/js/search.js" | minify | fingerprint }}
|
||||
<script defer src="{{ $search.Permalink }}" rel="preload" as="script" onload="loadSearch();"
|
||||
integrity="{{ $search.Data.Integrity }}">
|
||||
</script>
|
||||
{{- else}}
|
||||
{{ $search := (slice $fusejs $fastsearch ) | resources.Concat "assets/js/search.js" | minify }}
|
||||
<script defer src="{{ $search.Permalink }}" rel="preload" as="script" onload="loadSearch();"></script>
|
||||
{{- end}}
|
||||
{{- end -}}
|
||||
|
||||
<!-- Favicons -->
|
||||
<link rel="icon" href="{{- .Site.Params.assets.favicon | default "favicon.ico" | absURL -}}">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="
|
||||
|
Loading…
Reference in New Issue
Block a user