2013年12月08日, 編集履歴
Jekyll製ウェブサイトに簡易検索機能を実装する
はじめに
Jekyllは静的ウェブサイト生成システムであり、検索機能は付いていない。
プラグインで検索機能を付けられるのかもしれないが、GitHub Pages上でビルド・ホストをする場合は使えないので、ちゃんと探していない。かんたんにサイト内検索を実現するならGoogleのカスタム検索を使用する方法もあるが、Googleには頼りたくないので今回は自分で実装した。
こんなの。
キィワードを入力してエンターで検索実行。キィワードを[]
(角括弧)でくくるとそれをブログ記事に付けられたタグとして認識する。たとえば[jekyll] 検索
とすると、「jekyll」タグを付けられたもの、かつ本文に「検索」を含むブログ記事がヒットする。
コンセプト
基本コンセプトは「simple jekyll searching - alex pearce」を参考にした。
かいつまんで言えば、ブログ記事の情報(タイトル、URL、タグ、日付、本文)をJSONファイルに配列として詰め込み、JavaScriptで条件に合致する記事を取得するという方法をとった。
JSONファイルの作成
ブログ記事の情報を溜め込むsearch.json
を作成する。ウェブサイトのビルド時に全ブログ記事の情報を自動で埋め込むために、Jekyllの処理対象として作成する。
---
---
[
{% for post in site.posts %}
{
"title": "{{ post.title | escape }}",
"tags": [{% for tag in post.tags%}"{{ tag }}"{% unless forloop.last %}, {% endunless %}{% endfor %}],
"url": "{{ post.url }}",
"date": {"year": "{{ post.date | date: "%Y" }}", "month": "{{ post.date | date: "%m" }}", "day": "{{ post.date | date: "%d" }}"},
"content": "{{ post.content | strip_html | strip_newlines | escape }}"
}{% unless forloop.last %},{% endunless %}
{% endfor %}
]
全体を配列として、その中にブログ記事の情報を詰め込む。Jekyllの処理対象とするためにファイル先頭にYAML Front-matterが必要。
ポイントはcontent
の値に適用するフィルタ。
post.content
にはブログ記事の本文がHTMLタグ付きで入っているので、strip_html
フィルタを適用してHTMLタグを取り除く。strip_newlines
で改行を除去して単一行にし、最後にescape
でクォーテイション文字等をエスケープする。
JSONファイルが作成できたら、一度ローカルでビルド、生成されたJSONファイルを検査し(JSONLint - The JSON Validator)、Validなファイルができているかを確認した方が良い。
検索フォーム、検索結果ページの作成
検索ページへGET
リクエストを送信するフォームを作成し、すべてのページで読み込まれるテンプレート内に配置する。
<form action="/search.html" method="get">
<input type="search" name="q" placeholder="Search"/>
</form>
検索結果ページsearch.html
を作成し、空のdiv
要素をひとつ置いておく。
<div id="matchedList">
</div>
JavaScriptによる検索
search.js
を作成し、前節のsearch.html
に読み込ませる。
search.js
の要点を書くと、
search.html
はGET
リクエストが送信されているので、URL文字列から検索キィワードを取り出し、整形するsearch.json
を読み込むsearch.json
から読み込んだブログ記事情報の配列から検索条件に合致するものを抜き出し、search.html
に配置しているdiv
に情報を整形して埋め込む
本文にキィワードが含まれているかどうかはString.match()
の正規表現を用いた。たとえばキィワードがjekyll 検索
であれば(?=.*jekyll)(?=.*検索)
という正規表現を本文文字列に対して用いた。この場合は、本文文字列内に「jekyll」「検索」の両方(順不同)が含まれている場合にマッチする。
まとめ
実際のファイル構成はGitHubリポジトリィを参照。
この方式の問題点はブログ記事数が増えるごとに生成されるJSONファイルが肥大化し、検索速度が低下することだが、それはそのときになって考えれば良いとして、今回はこれまで。