次のように、Twig を使用してフォーム ボタン内に HTML を配置しようとしています。
{{ form_widget(form.jiraStatus, {
'label': '<i class="fa fa-bug"></i>Bug',
'attr':{'class': 'btn btn-large btn-default btn-block' }
}) }}
しかし、これを行うと、レンダリングされたボタンは次のように表示されます。
<button type="submit" name="SolveTask[taskTypesFormObj][bugStatus]"
class="btn btn-large btn-default btn-block">
<i class="fa fa-bug"></i>Bug
</button>
ご覧のとおり、ボタン内の HTML はエンコードされています。raw フィルターを使用しようとしましたが、効果は同じです。これを行う方法はありますか?
ありがとう!
ベストアンサー1
はい、カスタマイズする必要がありますフォームのテーマ。
注記:この回答は、Symfony 2.8 3.x および 4.x と互換性があるように編集されています。古いバージョンについては、編集履歴を参照してください。
ボタンのアイコンをサポートする良い方法は、フォーム拡張機能を使用することです。まず、新しいプロパティを定義するフォーム拡張クラスを作成します。アイコンフォームで使用できるもの:
<?php
namespace Foo\BarBundle\Form\Extension;
use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\Form\Extension\Core\Type\ButtonType;
use Symfony\Component\OptionsResolver\OptionsResolver;
class ButtonTypeIconExtension extends AbstractTypeExtension
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->setAttribute('icon', $options['icon']);
}
/**
* @param FormView $view
* @param FormInterface $form
* @param array $options
*/
public function buildView(FormView $view, FormInterface $form, array $options)
{
$view->vars['icon'] = $options['icon'];
}
/**
* @param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(['icon' => null]);
$resolver->setDefined(['icon']);
}
/**
* Returns the name of the type being extended.
*
* @return string The name of the type being extended
*/
public function getExtendedType()
{
return ButtonType::class; // Extend the button field type
}
}
この拡張機能を services.yml (または xml ファイル) に登録します。エイリアスは、上記のgetExtendedType()
メソッドによって返される文字列と一致する必要があります。
# Form extension for adding icons
foobar.form_extension.icon:
class: Foo\BarBundle\Form\Extension\ButtonTypeIconExtension
tags:
- { name: form.type_extension, extended_type: Symfony\Component\Form\Extension\Core\Type\ButtonType }
次に、 をオーバーライドします。(上記のリンクを参照)これらのテーマで を変数としてform_div_layout.html.twig
使用できるようになりました。 ボタンの場合は、ブロックをオーバーライドします。icon
button_widget
{% block button_widget -%}
{% set attr = attr|merge({class: (attr.class|default('') ~ ' btn')|trim}) %}
{% if label is empty -%}
{%- if label_format is not empty -%}
{% set label = label_format|replace({
'%name%': name,
'%id%': id,
}) %}
{%- else -%}
{% set label = name|humanize %}
{%- endif -%}
{%- endif -%}
{% if icon|default %}
{% set iconHtml = '<i class="fa ' ~ icon ~ '"></i> ' %}
{% else %}
{% set iconHtml = '' %}
{% endif %}
<button type="{{ type|default('button') }}" {{ block('button_attributes') }}>{{ iconHtml|raw }}{{ label|trans({}, translation_domain) }}</button>
{%- endblock button_widget %}
最後に、テンプレートでアイコン オプションを使用できます。
{{ form_widget(form.jiraStatus, {
'icon': 'fa-bug',
'label': 'Bug',
'attr':{'class': 'btn btn-large btn-default btn-block' }
}) }}
またはフォーム クラスで:
$builder
->add('jiraStatus', SubmitType::class, [
'label' => 'Bug',
'icon' => 'fa-bug',
'attr' => [
'class' => 'btn btn-large btn-default btn-block',
],
]
);
注: アイコンはプレゼンテーションの問題であり、フォーム クラスは実際にはビジネス ロジックに関するものである必要があるため、通常はテンプレートにアイコンを追加する方が適切です。
さらに一般的な例を挙げます。
getExtendedType() で ButtonType の FQCN を返すことで、Symfony に継承可能なすべてのフォーム要素を拡張していることを伝えます。ボタンタイプのような送信タイプ残念ながら、すべてのフォーム要素をターゲットにできるタイプはありませんが、ターゲットとする追加の拡張機能を追加することができます。フォームタイプ入力ボックスや選択要素などのすべてのフォームフィールドはこのタイプを継承します。したがって、両方のフォームフィールドで動作させたい場合そしてボタンについては、次のことをお勧めします。
abstract class AbstractIconExtension extends AbstractTypeExtension
上記とまったく同じ内容の抽象クラスを作成しますが、getExtendedType
メソッドは除きます。次に、このクラスから拡張する 2 つのクラス (たとえば、FieldTypeIconExtension
とButtonTypeIconExtension
) を作成します。これらのクラスには メソッドのみが含まれますgetExtendedType
。1 つは の FQCN を返しFormType
、もう 1 つは の FQCN を返しますButtonType
。
Foo/BarBundle/Form/Extension/ButtonTypeIconExtension.php:
<?php
namespace Foo\BarBundle\Form\Extension;
use Symfony\Component\Form\Extension\Core\Type\ButtonType;
class ButtonTypeIconExtension extends AbstractIconExtension
{
/**
* Returns the name of the type being extended.
*
* @return string The name of the type being extended
*/
public function getExtendedType()
{
return ButtonType::class; // extend all buttons
}
}
Foo/BarBundle/Form/Extension/FieldTypeIconExtension.php:
<?php
namespace Foo\BarBundle\Form\Extension;
use Symfony\Component\Form\Extension\Core\Type\FormType;
class FieldTypeIconExtension extends AbstractIconExtension
{
/**
* Returns the name of the type being extended.
*
* @return string The name of the type being extended
*/
public function getExtendedType()
{
return FormType::class; // extend all field types
}
}
対応するエイリアスを使用して、これらの 2 つのクラスをサービスに登録します。
# Form extensions for adding icons to form elements
foobar.form_extension.button_icon:
class: Foo\BarBundle\Form\Extension\ButtonTypeIconExtension
tags:
- { name: form.type_extension, extended_type: Symfony\Component\Form\Extension\Core\Type\ButtonType }
foobar.form_extension.form_icon:
class: Foo\BarBundle\Form\Extension\FieldTypeIconExtension
tags:
- { name: form.type_extension, extended_type: Symfony\Component\Form\Extension\Core\Type\FormType }
icon
これで、フォーム テーマの他の場所でも変数を使用できるようになりました。たとえば、ラベルにアイコンを追加するには、form_label
ブロックをオーバーライドします。
{% block form_label -%}
{% if label is not sameas(false) -%}
{% if not compound -%}
{% set label_attr = label_attr|merge({'for': id}) %}
{%- endif %}
{% if required -%}
{% set label_attr = label_attr|merge({'class': (label_attr.class|default('') ~ ' required')|trim}) %}
{%- endif %}
{% if label is empty -%}
{%- if label_format is not empty -%}
{% set label = label_format|replace({
'%name%': name,
'%id%': id,
}) %}
{%- else -%}
{% set label = name|humanize %}
{%- endif -%}
{%- endif -%}
{% if icon|default %}
{% set iconHtml = '<i class="fa ' ~ icon ~ '"></i> ' %}
{% else %}
{% set iconHtml = '' %}
{% endif %}
<label{% for attrname, attrvalue in label_attr %} {{ attrname }}="{{ attrvalue }}"{% endfor %}>{{ iconHtml|raw }}{{ label|trans({}, translation_domain) }}</label>
{%- endif %}
{%- endblock form_label %}
次に、フォーム クラスのそのフィールドのラベルにアイコンを追加します。
$builder
->add('mytextfield', TextType::class, [
'label' => 'My fancy text field',
'icon' => 'fa-thumbs-o-up'
]
);