Hugoで構築したサイトにサイト検索機能を追加する。

大げさなので外部の検索サービスにクローリングさせたり、ElasticSearchを立てたりはせず、自前でインデックスファイルを作成しJavascriptで検索することとし、以下のページを参考にして実装した。

検索ページ用のコンテンツファイルを作成(content/search.md)

---
title: サイト検索
layout: search
---

レイアウトにsearchを使う指定をしてコンテンツファイルを作成する。 検索フォームはテンプレートで出力するため、中身は空でOK

テンプレートファイルを作成 (layouts/_default/search.html)

Hugo に全文検索(インクリメンタルサーチ)の機能を付ける - まくまく Hugo ノート」にある通り、新しいHugoでは出力ファイルに livereload用のscriptタグが出力されるため、検索に使用するインデックスは別ファイルに出力するのでは無く、テンプレートの中に展開する。

<script>
const data = [{{ range $index, $page := where .Site.Pages "Section" "post"}}
{{ if ne $index 0 }},{{ end }}{
url: "{{ $page.Permalink }}",
title: "{{ $page.Title }}",
pubdate: "{{ $page.PublishDate }}",
content: "{{ .PlainWords }}"
}{{ end }}]
</script>

テンプレートの先頭に上記のコードを記載する。これにより変数dataにインデックス情報が設定されるためdataを検索する処理を記述すれば良い。 こちらは「Hugo に全文検索を取り付けた the right stuff」のユーザインタフェースが使いやすそうなので、こちらを参考に実装した。

完成形はこちら。

[{{ range $index, $page := .Pages }}{{ if ne $index 0 }},{{ end }}
    {
        "ref": "{{ $page.Permalink }}",
        "title": {{ $page.Title | jsonify }},
        "section": "{{ $page.Section }}",
        "date" : {{ $page.Date.Format "2006.01.02" | jsonify }},
        "body": {{ $page.Plain | jsonify }}
    }
{{ end }}]