社内のコーディングの生産性向上のために、hygenでファイルを追加するスクリプトを作っていたのですが、hygenのTemplateドキュメントを見てもどういう風にテンプレートファイルがレンダリングされているのかよくわからなかったので調べてみました。
前提
- yarnでhygenを実行して、複数のテンプレートファイルから数種類のファイルを生成したかった。
- オプションの値によってテンプレートファイルの処理方法を変えたかった。
- 条件分岐の書き方などでわからないところがあった。
- hygenのバージョンはv6.2.11
hygenのコードを読む
ドキュメントは使い方がざっくり書いてあるだけなので、コードを読みました。
render.tsのrender関数
front-matterでパース
実際にファイルを読み込んだあと、front-matterでヘッダ部分とボディ部分を読み込んでいます
該当コード
hygenのテンプレートファイルは↓のようになっています。
---
// frontmatterの定義部分(ヘッダ部分)
---
// テンプレート部分(ボディ部分)
これをヘッダ部分とボディ部分に分けて次の処理に渡しています。
ejsでテンプレートをレンダリング
その後、ヘッダ部分とボディ部分を用いてファイルをレンダリングしています。
該当コード
ヘッダ部分の属性をパース
front-matterでパースされたヘッダ部分の属性の値をrenderTemplate
に渡してパースしています。
該当コード
renderTemplate
関数では受け取った値をejsでパースします。
該当コード
パースされた値がこの後テンプレートのレンダリングに使用されます。
ボディ部分を属性値を使ってレンダリング
パースされた属性値と、render関数が受け取ったargs、ボディ部分のテンプレートをrenderTemplate
に渡してパースします。
該当コード
renderTemplate
はejsを使用しているので、テンプレートのパースもejsが行っていることになります。
まとめ
以上をまとめると、テンプレートファイルは下記のようにレンダリングされるようです。
- front-matterによって、frontmatterの定義部分(ヘッダ部分)とテンプレート部分(ボディ部分)に分離される。
- ヘッダ部分に定義されている属性値がrender関数に渡されたargsを使ってejsでパースされる。
- ボディ部分が、render関数に渡されたargsと上記でパースされた属性値を条件にレンダリングされる。
front-matterとejsが使用されるのと、この順序を念頭においてテンプレートファイルを作成すればいいことになります。
基本的にはejsの記法が肝になると思うので、困ったらejsのドキュメントを参考にすればいいと思います。
ヘッダ部分の挙動(レンダリング・injectするか否かなど)についてはhygenのドキュメントを漁るしか無いですが、そこに渡す値はejsの記法範囲で自由にできるので自由度は高いと思いました。