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の柔軟さを利用して変なことするよりもこうやった方が良さそう。