テンプレートエンジンmustacheを使ってみる

programing

例えば、規則性のあるモデルとなるようなクラスのためのコードを沢山記述するのは大変。

ある程度自動で生成したい。そこで、テンプレートエンジンの mustache を触ってみることにした。

mustache

mustache(直訳:口ひげ) はテンプレートエンジンの一つ。テンプレートとなるファイルと、 そこに差し込むデータを記述したファイル地を用意して、テンプレートエンジンにくぐらせることで、 目的のファイルを出力してくれるプログラム。

http://mustache.github.io/

基本的な使い方を見たほうが早いので、下記に示す。例えば、typescriptのクラスをテンプレートとしたいとき、

1.テンプレートを用意する

test.mustache

class {{className}} {
	constructor(
		public {{field}}
	){}

	{{#hasFunction}}
	{{functionName}}(): void {
		console.log('this instance has function');
	}
	{{/hasFunction}}
}

2.テンプレートに差し込むデータを用意する

test.json

{
  "className": "SomeClass",
  "field": "someField",
  "hasFunction": true,
  "functionName": "print"
}

3.mustacheをインストールする

様々な実装が存在しているが、今回はjavascriptの実装を使う。 npmでmustacheをインストールする。

$ npm install mustache

4.mustacheにテンプレートとデータを渡す

下記のコマンドを実行。mustacheコマンドにテンプレートとデータを引数で指定し、 コマンドの出力をファイルにリダイレクトすることで、目的のファイルを生成する。

$ mustache ./test.json ./test.mustache > ./SomeClass.ts

コマンドを実行すると、カレントディレクトリにSomeClass.tsというファイルが生成される、 その中身は下記のようになる。

SomeClass.ts

class SomeClass {
	constructor(
		public someField,
	){}

	print(): void {
		console.log('this instance has function');
	}
}

{{}}で囲まれた部分がデータ部を参考に置き換わっていること、{{#key}}keyに対応する部分を データ部から参照して、そこがtrueであれば{{#key}} ~ {{/key}}で囲まれている部分が 出力されていることなどが確認できる。

基本的なmustacheの使い方、出来ることはこんな感じ。{{#key}} ~ {{/key}}以外にも、他の命令もあるので、 そこはリファレンスを見ながら書いていけば良い。

javascriptと組み合わせて使う

https://github.com/janl/mustache.js

基本的には、前述した使い方で どの言語のソースコードでも生成できる。 単に生成したい言語でテンプレートを書き、そこにデータを差し込めば良いだけなので。

ここで書く typescriptと組み合わせて使う とは、前述の操作そのものをtypescriptで書くということ。

勿論、以下に書くよりも単純な使い方をしたければ、

  1. 好きな言語でデータ部を指定するjsonファイルを生成するプログラムを書く
  2. 1で生成したjsonファイルと、テンプレートファイルをmustacheに渡す

これでも別に構わないと思う。

ただ、例えば対応する値を関数の戻り値にしたい場合などに、言語で制御できると便利。 どういうことかというと、下記のようなことが出来るということ。

mustache_test.js

const Mustache = require('mustache');

var data = {
  name: "alice",
  calcAge: function () {
    return Math.floor( Math.random() * (10 + 1));
  }
};

var template = "my name is {{name}}, I'm {{calcAge}} years old."

var output = Mustache.render(template, data);

console.log(output);

上記のコードをNode.jsで実行すると、下記のようになる。

$ node ./mustache_test.js
> my name is alice, I'm 6 years old.

上記の場合、nameには静的に指定されたaliceが、calcAgeは引数を持たない関数が実行され、 その戻り値が(ここではランダムな10までの数字)割り当てられているのが分かる。

他にも、{{}}のタグを別のタグにしたりも出来るようだが、あまり使わない機能だろう。 他のテンプレートエンジンのソースを出力したいときなどに使えるのかもしれない。