mustacheのパーシャルをファイルから読み込む

何かしらテンプレート使う時は、実行にはHandlebars.jsを使いつつ、mustacheの仕様に沿った形のみで書くみたいな感じで大体やってる。前に書いたHandlebars.jsのincludeヘルパーだけ便利だったのでちょっと使ったりしてたけど、パーシャルを使って書き直すことにした。パーシャルそのままなのでネストでき、他の実行環境でもだいたいそのままで動く反面、相対パスで見に行くみたいなことは出来なくなった。

特定のパスにまとめたパーシャル(*.partial.mustache)を読み込み、オブジェクトに拡張子を抜いたファイル名をキーにして、その内容を値に格納していくだけ。

function _loadSharedPartials(dir) {
	var partials = {};

	var files = fs.readDirSync(dir);

	for (var i = 0, l = files.length; i < l; i++) {
		var file = files[i];

		if (file.match(/\.partial\.mustache$/)) {
			var name = path.basename(file, '.partial.mustache');
			partials[name] = fs.readFileSync(path.join(dir, file), {
				encoding: 'utf8'
			});
		}
	}

	return partials;
}

Handlebars.jsで使う場合は以下のようにテンプレートの実行関数の第2引数のオブジェクトの子で指定する。

var hbs = require('handlebars');

var render = hbs.compile(template);
var rendered = render(data, {
	partials: _loadSharedPartials('./')
});

mustache.jsではrender()の第3引数に直接指定する。

var mustache = require('mustache');

var rendered = mustache.render(template, data, _loadSharedPartials('./'));

SSIのインクルードとはちょっと違う挙動になるけど、mustache的には素直な実装なので、Handlebars.jsの柔軟さを利用して変なことするよりもこうやった方が良さそう。