為 hugo 產生的網站增加搜尋功能
hugo fusejs search -Why
日記寫多了,就需要做索引卡片,才容易找。
How
在使用 fusejs
之前你必須為你要搜尋的網站建立一個 json 格式的索引檔。
例如,一個包含標題,作者和網址的物件陣列。
list.json
[
{
"title": "Crossorigin Anonymous",
"content": "......"
"link": "https://hokang.info/crossorigin-anonymous/"
},...
]
然後將該內容傳入建立一個 Fuse
物件後,便利用他來搜尋。
const options = {
// isCaseSensitive: false,
// includeScore: false,
// shouldSort: true,
// includeMatches: false,
// findAllMatches: false,
// minMatchCharLength: 1,
// location: 0,
// threshold: 0.6,
// distance: 100,
// useExtendedSearch: false,
// ignoreLocation: false,
// ignoreFieldNorm: false,
// fieldNormWeight: 1,
keys: [
"title",
"content"
]
};
const fuse = new Fuse(list, options);
const search = (pattern) => fuse.search(pattern)
如上,
現在只要將要搜尋的字串傳給 function search
便可得回一個依文字距離大小排列的搜尋結果。
例如,
[
{
"item": {
"title": "Crossorigin Anonymous",
"content": "......"
"link": "https://hokang.info/crossorigin-anonymous/"
},
"refIndex": 0
},...
]
所以,如何為網站產生一個索引檔是最關鍵的,而這正好可以利用 Hugo
的 jsonify 來產生。
編寫一個為每一頁產生一個物件的模板。
例如,
layouts/_default/index.json
{{- $.Scratch.Add "index" slice -}}
{{- range .Site.RegularPages -}}
{{- $.Scratch.Add "index" (dict dict "title" .Title "content" .Plain "link" .Permalink) -}}
{{- end -}}
{{- $.Scratch.Get "index" | jsonify -}}
在設定檔上增加 JSON
格式。
config.toml
[outputs] home = ["HTML", "RSS", "JSON"]
如此,在每次產生網頁時便會在 public 目錄下產生一個 index.json
檔。
接下來,可為需要查詢功能的網頁增加 javascript
。
<script src="https://cdn.jsdelivr.net/npm/fuse.js@6.6.2/dist/fuse.min.js">
const search = (pattern) => fetch('/index.json')
.then(response => response.ok ? response.json() : [])
.then(data => new Fuse(data, options))
.then(fuse => fuse.search(pattern))
// 將輸入的查詢字串傳入搜尋函式
search(document.getElementById('#searchInput').value)
上述為極簡的處理,可以改進的地方很多。 有興趣的可以進一步參考 hugo fastsearch。