概要
EC-CUBE3をカスタマイズしていると必ずぶち当たるフォームのカスタマイズ
その中でも中々情報が落ちてないform_themeについて自分メモ。
環境
EC-CUBE 3.0.16
PHP 7.19
そもそもなぜラジオボタンとチェックボックスにattrが使えないのか
参考:http://d.hatena.ne.jp/shimooka/20120726/1343280157
デフォルトのフォームテーマ(form_div_layout.html.twig)では、choice_widgetブロック内でexpandedの場合に改めてform_widget関数を呼び出しているが属性情報を引き継いでいないため、ラジオボタンとチェックボックスに属性を直接付けることができない。
らしいです。(非力)
そこでform_theme
の出番なのです。
EC-CUBE3ではformのレイアウトはデフォルトで以下のファイルを読み込んでいます。
src/Eccube/Resource/template/Form/form_layout.twig
あの忌まわしいClass="form-group"
をここで外すこともできます。
(その場合は該当するType全てのClass="form-group"
が外れてしまいます。)
さて話しが逸れましたが、form_theme
使っていきます。
form_widget(form.test)
の中がラジオボタンorチェックボックスだったとします。
そしてそのformにクラスtest-classを付けたいとします。
先ずはソースから↓
<div class="form-group">
{% form_theme form _self %}
{% block choice_test_widget %}
{% spaceless %}
{% for child in form.test %}
{{ form_widget(child,{attr : {'class': 'test-class'}}) }}
{% endfor %}
{% endspaceless %}
{% endblock choice_test_widget %}
</div>
...はい、よく分かりませんね。
一行ずつ解説。
{% form_theme form _self %}
参照:https://symfony.com/doc/current/form/form_customization.html
特別な{% form_theme form _self %}タグを使用することで、Twigはオーバーライドされたフォームブロックに対して同じテンプレート内を調べます。form.age フィールドがintegerタイプフィールドであると仮定すると、そのウィジェットがレンダリングされると、カスタマイズされた integer_widgetブロックが使用されます。
twigを何かしらオーバーライド(上書き)するみたいです。
{% block choice_test_widget %}
//何かしらの処理
{% endblock choice_test_widget %}
choice
はフォームタイプのことです。test_widget
がブロック名ですね。
{% spaceless %}
//何かしらの処理
{% endspaceless %}
HTMLの空白行を取り除いてくれるそうです。(適当)
{% for child in form.test %}
//何かしらの処理
{% endfor %}
form.test
がウィジェットの形だとform_widget(form.test)
となる部分ですね。
いわゆる、該当するフォームを指定。
分かりやすいようにchild
という変数に代入しています。
(もちろん何でもOK)
{{ form_widget(child,{attr : {'class': 'test-class'}}) }}
ここで今回の記事のメインです。普段ならform_widget(form.test)
とやるところを
form_widget(child ~
としています。
これは先ほどのforで回したform.test
が変数child
に入っているということなんですね。
こうやってバラすことで{attr : {'class': 'test-class'}}
が適用されるようになります。
ちなみに上記のやり方でレイアウトを好きに作れるので、個別にclass="form-control"を
外したい時などにも使えます。
まとめ
Symfony2はク〇めんどい。
以上。