【HowTo】Hexoの新しいInjectorについて調べた【5.0】

予てより、Hexoに新しいInjector機構を導入する動きがありました。
それが、実際のコードとして試せる、かもしれない段階まで進展しているようです。
先月の16日に、マスターブランチにマージされたからです。
リリースは、次のメジャーバージョンアップとなる(筈の)、5.0になるようです。

PR: feat(extend/injector): bring up new extend Injector #4049

これはなに?

まずHexoですが、いわゆる「静的サイトジェネレーター」とよばれる方式の、ブログ作成ツールです。
本ブログでも使っているものです。

そして本件で言うInjectorとは、プログラムが生成するHTMLファイルに対して、cssやjavascriptなどの、code snippet(断片)を、後付で挿入する仕組みのことを指します。

主なユースケースは、プラグインによって、テーマ(HTMLのテンプレート)を直に編集することなく、cssやjavascriptを挿入することになるでしょう。

テーマ等が固定であれば、直接テンプレートに追加することで、本件要件は満たせます。
しかしHexo本体とは別に、各種テーマ、各種プラグインを好みによって導入できる仕組みであるために、このような機構が必要になってきます。

これまでの流れ

以前より同じ目的のために、hexo-injectプラグインが存在しました。
これはだいたい2016年3月頃までは開発が続けられていた模様で、その後にメンテナンスがされなくなり、またHexo本体のバージョンが上がると共に、動作しない状態になっていました。

それが昨年の8月に、再び修正する機運が持ち上がっていたようなのですが、結局のところそれも中途で実用化されないままになっていたようです。

私にもその理由は、なんとなく想像ができます。
Injector機構をプラグインによって実装することは、アドホック感ありありで、それならばHexo本体でサポートする方が、ずっとシンプルかつスマートに実現できると考えられるからです。
(修正しようとしていた開発者様が同じ考えだったかは、わかりません。)

Issues: Deprecation #90

私とInjector

私がHexoを使い始めると同時に作り始めたプラグインがあります。
hexo-tag-google-photos-album 公開しました (npm)

このプラグインの中でも、cssやjavascriptを挿入する機能が必要になって、開発の過程でhexo-injectプラグインのことを知り、そして挫折しました。

それで他作者様のプラグイン等を参考にして、独自にInjector機能を実装したもの、実は満足する動作を実現できていません。
ひとまず動く、かな、位の状況になっていて、後で必ず、作り直そうと決めていたのです。

が、いかんせん、上記のように、プラグインからそれを実装するには原理的な困難があり、同時に他の開発者によって改善に動いている様子があることも知ったために、その進捗を待つこととして、私の作成するプラグインは、不完全なままで、時期が来るのを待つことにしていたのでした。

ドキュメント 私家版和訳

新しいAPIは、本番リリース前なので、現時点で公式サイトを探してもドキュメントがありません。

そして公式サイトの更新も、プルリクが既に準備されており、開発ブランチを通してその中身を読むことが可能です。

docs | API/Injector | Hexo

今回、これを和訳してみようかと思います。

↓↓↓和訳ここから


Injector


「Injector」は、静的なコードの断片(スニペット)を、生成されたHTMLファイル内の、head要素やbody要素に付け加えます。
Hexoは、after_render:htmlフィルターが処理される前に、Injectorを実行します。

Synopsis 使い方

hexo.extend.injector.register(entry, value, to)

entry <string>

HTML内部において、目的のコードを挿入する場所を指定します。<文字列>

以下の値を指定できます。

  • head_begin: <head>要素開始タグの直後に、コードを挿入します。(デフォルト)
  • head_end: </head>要素閉じタグの直前 〃
  • body_begin: <body>要素開始タグの直後 〃
  • body_end: </body>要素閉じタグの直前 〃

value <string> | <Function>

挿入したい、コードの断片(スニペット)。<文字列、もしくは関数>

文字列を返却する関数を指定することも可能です。

to <string>

どのページに対して、コードの断片を挿入するか。<文字列>

  • default: 全てのページ(デフォルト)
  • home: インデックスのみ (ヘルパーis_home()true のとき)
  • post: ブログ記事のみ (ヘルパーis_post()true のとき)
  • page:(postではない)静的ページのみ (ヘルパーis_page()true のとき)
  • archive: アーカイブのみ (ヘルパーis_archive()true のとき)
  • category: カテゴリーのみ (ヘルパーis_category()true のとき)
  • tag: タグのみ (ヘルパーis_tag()true のとき)
  • カスタムレイアウト(Layout)の名前を指定することが可能です。参照:Writing - Layout

他にも内部的な機能がありますが、詳細は hexojs/hexo#4049 を参照してください。

Example サンプル

const css = hexo.extend.helper.get('css');
const js = hexo.extend.helper.get('js');

hexo.extend.injector.register('head_end', () => {
return css('https://cdn.jsdelivr.net/npm/aplayer@1.10.1/dist/APlayer.min.css');
}, 'music');

hexo.extend.injector.register('body_end', '<script src="https://cdn.jsdelivr.net/npm/aplayer@1.10.1/dist/APlayer.min.js">', 'music');

hexo.extend.injector.register('body_end', () => {
return js('/js/jquery.js');
});

上記の例では、musicレイアウトを指定した全てのページに対して、APlayer.min.css (<link> 要素)を、</head>要素閉じタグの前に挿入します。
同時に、APlayer.min.js (<script> 要素)を、それらのページの</body>要素閉じタグの前に挿入します。

そして最後の段落では、全ての生成されたページで、jquery.js (<script> 要素)を、</body>要素閉じタグの前に挿入します。


↑↑↑和訳ここまで

この和訳は、 API/Injector を、私(isnot)が独自に翻訳したものです。原文はMIT Licenseです。

私の和訳について、MIT Licenseもしくは、クリエイティブ・コモンズ 表示 4.0 国際 ライセンスの下に提供されています。
クリエイティブ・コモンズ・ライセンス