jade(テンプレートエンジン)をクライアントサイドで動かすの巻
2014/02/24 追記:
jade.compile(jadeText, {client: true})は使えなくなったようです。かわりにjade.compileClient(jadeText)を使えとのこと。
あと、下の文中のanonymousはtemplateに変わってました。
Node.jsのフレームワークExpressの標準テンプレートエンジンである、jade
https://github.com/visionmedia/jade
を、クライアントサイドで動かしたくなったので、色々調べながらなんとかゴリ押しでできるようにした。
公式読んだ限り普通に出来そうな事を書いてあるんだけど、
僕が英語弱すぎてかつ色々初心者すぎて分からなかったので、色々試してやってみました。
まずjadeは、jade->js->htmlという流れでコンパイルされる。
jadeをjsに変換することを、公式に倣い、プリコンパイルということにする。
プリコンパイル時にclient: trueオプションをつけると、次のような感じのjsの関数に変換される。
コンパイル元(jade)
p= hello
コンパイル後(js)
function anonymous (locals) { var buf = []; var locals_ = (locals || {}),hello = locals_.hello;jade.indent = []; buf.push("\n<p>" + (jade.escape(null == (jade.interp = hello) ? "" : jade.interp)) + "</p>");;return buf.join(""); }
例えばNodeで動かすなら、
var jade = require('jade'); var fn = jade.compile('p= hello', {client: true, pretty: true, compileDebug: false}); console.log(fn.toString());
とかすると上のような関数を文字列として書き出せる。
で、htmlを生成するには、この関数の第一引数localsに、テンプレートで埋めたいモノを含んでるオブジェクトを渡せばよいので、
var html = fn({hello: 'Hi'}); console.log(html);
とかすると、
<p>Hi</p>
というhtmlが生成されるという理屈。
プリコンパイルされた状態はただのjsなので、クライアントサイドでも普通に評価できる。
ということで、私が至った結論としては、
- 1箇所(例えばclient/views/)にjadeファイルを置く
- シェルで全jadeファイルを回し、
- jadeファイルを開き、その文字列をjade.compile()の引数に渡す(Nodeならfsモジュールを使う)
- できた関数を1ファイルに書き出していく。
- public/以下に置き、公開する。
- クライアント側で、その関数を呼び出す。
あとは、些細な点ですが、
上のようにプリコンパイルした関数をtoString()するとanonymousという名前の関数になってしまうので、この名前を変えてやる必要があります。
anonymousをjadeのファイル名に変えようと思ったのですが、それだとファイル名にjsで使えない文字が入っていた時困りますので、
書き出す1ファイルを
var pre = { 'jadeのファイル名': function (locals) {...}, 'jadeのファイル名2': function (locals) {...}, };
というように連想配列にしました。これで、呼ぶときはpre.ファイル名(obj)でOK。