Symfony2 twigでnl2brフィルタが使えない

前回の記事でnl2brフィルタの便利さを伝えたけど今回はtwigフィルタの微妙な話。

twigで使えるフィルタ同士の順番や相性?の問題で何故かnl2brが反映されない状態になったので一応メモ。

Symfonyについてはさっぱりわからないので原因や理由を把握しないまま野蛮的知識人的に強引に解決法だけ書いて終わり。

今回(といっても随分前だけど)引っかかったのは、

我らがnl2brフィルタとlengthフィルタの同時使用におけるフィルタ効いてないよー問題。

DBから取り出した改行コード入りのテキストデータをまずはnl2brを使って出力させる。

{{ str|nl2br }}

上記のようにすれば問題なく改行されて出力される。

ここに最初の100文字だけを取り出すフィルタを追加するとおかしいことになった。

単純に知識がないのでそのままゴリゴリ書く。

失敗1:

{ str|length > 100 ? str|nl2br|slice(0, 100) ~ ' ...' : str|nl2br|slice(0, str|nl2br|length -1) }}

すると array などと意図しない表示が出力される・・・

あー、strに付けるのが間違ってるんだなきっと。と浅はかな知恵を働かせる。

(後ろで再度sliceをしてるのは特殊データ形式のためスルーで)

失敗2:

{ str|length > 100 ? str|slice(0, 100)|nl2br ~ ' ...' : str|slice(0, str|length -1)|nl2br }}

あれ?今度は
がそのまま表示されてしまう。

なぜかsliceすると
がそのまま出力されるという謎。

この謎が解決出来ないどころか理由を知ろうともしない私はそのまま強引な解決策をピコーンと閃く。



失敗3:

{ str|length > 100 ? str|slice(0, 100)|nl2br|raw ~ ' ...' : str|slice(0, str|length -1)|nl2br|raw }}

rawが効いてない・・・だと?

もうフィルタはいいやと思い始めたけど、念のためエスケープ外してみるか。



成功:

{% autoescape false %}{{ str|length > 100 ? str|slice(0, 100)|nl2br ~ ' ...' : str|slice(0, str|length -1)|nl2br }}{% endautoescape %}

これでバッチリ改行されつつ表示されましたとさ。

切った後にnl2brをしないとそりゃ改行タグが途中で切れておかしくなるんだから失敗1はそもそも有り得ないミスです。

でもボリュームのある単純作業をやってると何も考えずに指だけ動いてることって結構あるんですよね。。。

しかしなぜ{% autoescape false %}をしないといけないのかよくわかりません。

英語が致命的に出来ないので調べようともしてないんですがなんでなんでしょう。


{% debug %}を使って出力しろって言われそうですが長くつき合うつもりがないので華麗にスルー。

どう考えてもviewでやる処理じゃないけど一つ上の行でnl2br使ってるのにそこだけ違うもおかしいので今回はtwig側に処理を書き入れての対応になりました。

出来る天才プログラマの方がtwigマニュアルを作ってくれることを切に願っています。