Undefined の定義

id:mopemopeTwitter 上で色々教わりながら解決したネタ。jinja2 には Undefined というのがありまして、簡単に言えばテンプレート上で定義されていない場合、どう定義するのかというものだと思っているのですが(勘違いしてたらつっこみお願いします)。

これがまた、ややこしくて。Django の場合、テンプレートにおける未定義変数はスルー(エラーを無視)するのですが jinja2 は冷静に UndefinedError が帰ってきます。例えば...

{{ spam.eggs }} という書き方で spam が未定義の場合は Django では無視、jinja2 では見事に UndefinedError が返ってきます。これだと色々困るので、なんとかならないかなぁと思って調べいたら解決策がありました。

jinja2 は Environment を生成してそこでテンプレートローダを突っ込んだり、autoescape を True にしたりするのですが、Undefined の定義を書き換えることが出来るようだということを理解しました。

標準で Environment は Undefined を使用していますが、ここで Undefined を継承した NullUndefined を定義してやります。

class NullUndefined(Undefined):
  def __int__(self):
    return 0
  def __getattr__(self):
    return u''

jinja2_environment = jinja2.Environment(
  loader=...,
  autoescape=True,
  undefined=NullUndefined,
)

これで、jinja2 のテンプレートで未定義の変数の属性を触っても特に怒られなくなりました。これ気付くのに1時間くらいかかりました。

jinja2 は良くできています、とにかくプログラマブルにかくことも出来ますし、デザイナ向けにもかくことが出来ます。Werkzeug との相性も作者が同じなのでステキですよ。ちょっと癖が強いですけどね:-P