Middleman+GitHub で構築したサイトの検索画面を作る
このブログは Middleman と GitHub Pages で構築しています。
GitHub Pages は静的な資材をホスティングする機能しかないため、Movable Type でいうところの、mt-search.cgi
みたいな、動的な検索画面は作れない制約があります。
そこで、GitHub API v3 を使って JavaScript で実装することにしました。
実際の動作は、サイドバー (モバイル画面では下部) にある、検索窓から、適当な文字列で検索してみて下さい。(例: Hubot)
実装コード
たった 34 行です。 search.slim on ngs/sources.ngs.io
個人ブログで、規模が小さいので、多少富豪的な実装になっています。
Search Code API
検索には GitHub の Search Code API を使っています。検索に使える修飾子は Advanced Search と共通しています。
Search term q
に URI エンコードされた検索文字列と、ブログリポジトリ、記事資材を保存しているパスを指定します。
per_page
には 100
を指定します。
"https://api.github.com/search/code?q=#{ encodeURIComponent q }+repo:ngs/sources.ngs.io+path:/source/#{lang}/&per_page=100"
サイトマップ・リソース
当たり前ですが、Search Code API は、記事のタイトル・日付など、Middleman 固有のデータ返せないので、サイトマップ・リソースのデータをパスをキーにするハッシュにぶら下げておきます。
ruby:
sitemap = {}
blog.articles.each{|a|
sitemap[a.url] = a.data.merge url: a.url
}
javascript:
sitemap = #{sitemap.to_json}
API のコールバックの中で、上記のデータと付け合わせて、テンプレート内でイテレートするコレクションを集めます。
items = _.map res?.items, ({name}) ->
m = name.match /^(\d{4})\-(\d{2})\-(\d{2})\-(.+)\.md(?:\.erb)?/
permalink = "/#{m[1]}/#{m[2]}/#{m[3]}/#{m[4]}/"
sitemap[permalink]
SEO 問題
今回はウェブ検索に引っかかる必要がないので、対策していませんが、GitHub API v3 は robots.txt の制約により、クローラーのアクセスを許可していません。
(上は、Google ウェブマスターツールの Fetch as Google で確認した画面です。)
https://api.github.com/robots.txt
もし、Single Page Application などで活用し、SEO も行いたいのであれば、Heroku に迂回用のアプリを作るなどして対応する必要があります。