2014年04月27日

jinja2でMarkupしたのにescapeされてしまう問題

今回は jinja2 のカスタムフィルターではまった話。

そもそも GAE + jinja2 で autoescape をしたくなければ、main.py などで
application = webapp2.WSGIApplication(
        [
# 省略
        ],
        config = {
                'webapp2_extras.jinja2': {
                        'environment_args': {
                                'autoescape': False,
                                'auto_reload': False,
                                'extensions': ['jinja2.ext.i18n','jinja2.ext.autoescape']
                        },
        }
)
と autoescape を False にしておけば OK ですが、ユーザに投稿させるようなサイトの場合、言うまでもなく autoescape させるべきです。
その場合、autoescape は True にしておいて、escape させたくない jinja2 の変数では、
{{hoge|safe}}
とやればその変数 hoge に関しては escape が行われません。
将来的に問題になる可能性があるので、safe フィルターは使わない方が良いとは思いますが。

カスタムフィルターを作る場合、例えば、入力された文章の改行を <br /> に変更したい場合、
def linebreaksbr(s):
    return Markup('<br />'.join(jinja2.escape(s).splitlines()))
という感じで、戻りを Markup クラスのインスタンスにしてやれば、autoescape が True でもここで追加した<br />はescape されません。
今回、入力された文章の一行一行を <li></li>で囲ったものを出力しようと思い、
def linebreaksli(s):
    result = ""
    logging.error(type(result));
    for line in jinja2.escape(s).splitlines():
        result += u'<li>' + line + u'</li>';
    return result;
というフィルターを作ってみたのですが、肝心の <li> が &lt;li&gt; と escape されるという問題が発生。 若干、ハマってしまいましたが、そもそも jinja2.escape(s) の戻りが Markup クラスのインスタンスになっていて、Markup クラスのインスタンスに + で unicode 文字列を連結しようとすると、unicode 文字列が escape されて連結されてしまうというだけでした。
def linebreaksli(s):
    result = u''
    logging.error(type(result));
    for line in jinja2.escape(s).splitlines():
        result += Markup(u'<li>') + line + Markup(u'</li>');
    return result;
という風にしてしまえば OK でした。
タグ:GAE jinja2
posted by おちエン at 21:01| Comment(0) | GAE | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

×

この広告は1年以上新しい記事の投稿がないブログに表示されております。