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 | このブログの読者になる | 更新情報をチェックする

広告


この広告は60日以上更新がないブログに表示がされております。

以下のいずれかの方法で非表示にすることが可能です。

・記事の投稿、編集をおこなう
・マイブログの【設定】 > 【広告設定】 より、「60日間更新が無い場合」 の 「広告を表示しない」にチェックを入れて保存する。


×

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