BETA

Twig の Tips

投稿日:2020-08-15
最終更新:2020-08-15

Twig で

  • 比較判定の落とし穴
  • 文字列結合
  • 文字列結合したもののエスケープ回避

といった、いくつかのニッチなものや調べてもなかなか情報が出てこなかったについてメモしておきます。

経緯

いずれも type="number"input タグで最小値・最大値をセットしようとしたときの話です。

$item = [  
    id          => 'old',  
    name        => '年齢',  
    condition   => [  
        min => 0,  
        max => 137  
    ],  
    placeholder => 17  
];  

という定義が予めPHP側であるという仮定で話を進めます。

比較判定の落とし穴

Twig の比較は PHP よりも緩いようです。例えば、

<input  
    type="number"  
    class="form-control"  
    id="{{ item.id }}"  
    name="{{ item.id }}"  
    placeholder="{{ item.placeholder }}"  
    {{ item.condition.min != null ? (' min="' ~ item.condition.min ~ '"')|raw : '' }}  
    {{ item.condition.max != null ? (' max="' ~ item.condition.max ~ '"')|raw : '' }}  
>  

という記述をすると、

<input  
    type="number"  
    class="form-control"  
    id="old"  
    name="old"  
    placeholder="17"  
    max="137"  
>  

と出力され、 min が出力されませんでした。 null == 0 と判定されてしまったようです。

対処

<input  
    type="number"  
    class="form-control"  
    id="{{ item.id }}"  
    name="{{ item.id }}"  
    placeholder="{{ item.placeholder }}"  
    {{ item.condition.min is same as(null) ? '' : (' min="' ~ item.condition.min ~ '"')|raw }}  
    {{ item.condition.max is same as(null) ? '' : (' max="' ~ item.condition.max ~ '"')|raw }}  
>  

厳密な比較は same as というのがあるとのことなので、それを利用します。否定の付け方がよく分からなかったので truefalse の出力を反転させました。

文字列結合

上述で既に出てしまっていますが、 Twig の中での文字列結合は ~ とのこと。 PHP の癖で . にしないように注意。

文字列結合したもののエスケープ回避

これも最初の例で出てしまっていますが、最初は以下のようにしていました。

<input  
    type="number"  
    class="form-control"  
    id="{{ item.id }}"  
    name="{{ item.id }}"  
    placeholder="{{ item.placeholder }}"  
    {{ item.condition.min is same as(null) ? '' : ' min="' ~ item.condition.min ~ '"'|raw }}  
    {{ item.condition.max is same as(null) ? '' : ' max="' ~ item.condition.max ~ '"'|raw }}  
>  

すると、以下のような出力に。

<input  
    type="number"  
    class="form-control"  
    id="old"  
    name="old"  
    placeholder="17"  
    min=&quote;&quote;0&quote;&quote;  
    max=&quote;&quote;137&quote;&quote;  
>  

|raw を付けたのにエスケープされてしまっています。

対処

検索したところ、いくつか空振りの後にようやく文字列結合したものを |raw 出力する際は全体を括弧 () で括るという記述を発見。

<input  
    type="number"  
    class="form-control"  
    id="{{ item.id }}"  
    name="{{ item.id }}"  
    placeholder="{{ item.placeholder }}"  
    {{ item.condition.min is same as(null) ? '' : (' min="' ~ item.condition.min ~ '"')|raw }}  
    {{ item.condition.max is same as(null) ? '' : (' max="' ~ item.condition.max ~ '"')|raw }}  
>  

再掲になりますが、 (' min="' ~ item.condition.min ~ '"')|raw という書き方ですね。これでようやく意図した出力になりました。

参考

技術ブログをはじめよう Qrunch(クランチ)は、プログラマの技術アプトプットに特化したブログサービスです
駆け出しエンジニアからエキスパートまで全ての方々のアウトプットを歓迎しております!
or 外部アカウントで 登録 / ログイン する
クランチについてもっと詳しく

この記事が掲載されているブログ

アルム=バンドのQrunch

よく一緒に読まれる記事

0件のコメント

ブログ開設 or ログイン してコメントを送ってみよう