Hexo で検索結果を表示するページを生成するプラグインを作った。

TOC

  1. 追記:2018/02/08
  2. 概要
  3. リポジトリ
  4. インストール
  5. 仕組み
    1. Hexo 側
    2. ブラウザ側
  6. まとめ

こんにちは。shundroid です。お久しぶりです。

今回は新しく作った Hexo のプラグインについて、
仕組みや工夫したところなどを書きたいと思います。

追記:2018/02/08

client 側の工夫したところが消えましたw
多分 vscode-vim で insert モードを解除せずに消しちゃったからかな
とりあえず大まかには書いておきました。

概要

hexo-generator-search で生成された search.xml を使って、
検索結果を表示するページを作成します。

このブログでも使用しています。
サイドバーの検索ボックスで検索すると、このプラグインで生成されたページが表示されます。

リポジトリ

インストール

1
$ npm install hexo-generator-search

続きは上のリポジトリのREADME.mdに書いてあります。

仕組み

空のページを作成し、そこに {% search_result %} と書くことで、
ページが表示されるようにしています。
このタグが読み込まれると、そこに <div> <script> <style>
挿入されるようになっています。

Hexo 側

index.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const fs = require('hexo-fs')
const path = require('path')
function insertSearchResult (args) {
return Promise.all([fs.readFile(path.join(__dirname, './client.js')),
fs.readFile(path.join(__dirname, './style.css'))]).then(contents => {
return '<div id="plugin-search-result"></div>' +
'<script>' + contents[0] + '</script>' +
'<style>' + contents[1] + '</style>'
})
}

hexo.extend.tag.register('search_result', insertSearchResult, {
async: true
})

script、style の読み込みは、webpack などをつかってもよかったのですが、 
今回は小規模に作りたかったので、単純にファイル読み込み+inline 出力で実装しました。

この時、タグの中身に非同期プロセスを含みますので、
tag.register には引数で { async: true } を渡しています。
また、fs は代わりに hexo-fs を利用して、それが Promise を返してくれています。
2ファイル読んでいるので、Promise.all を使用して並立にしています。

ブラウザ側

ここで読み込んでいる script は、ブラウザ側で動作しますね。
そちらも見てみましょう。

流れは、

  1. hexo-generator-search で生成された search.xml を xhr で読み込む
  2. そこから検索
  3. 検索結果を dom として生成

という感じです。

まとめ

このような感じでプラグインを作りました。
よろしければ使ってみてください。
バグ・機能要望などは Github Issues へ。