How to Work with Form Themes

This article explains how to use in your app any of the form themes provided by Symfony and how to create your own custom form theme.

この記事では、Symfony が提供するフォーム テーマをアプリで使用する方法と、独自のカスタム フォーム テーマを作成する方法について説明します。

Symfony Built-In Form Themes

Symfony comes with several built-in form themes that make your forms look great when using some of the most popular CSS frameworks. Each theme is defined in a single Twig template and they are enabled in the twig.form_themes option:

symfony には、いくつかの最も人気のある CSS フレームワークを使用するときにフォームの見栄えを良くする組み込みのフォーム テーマがいくつか付属しています。各テーマは 1 つの Twig テンプレートで定義され、twig.form_themes オプションで有効になります。
  • form_div_layout.html.twig, wraps each form field inside a <div> element and it's the theme used by default in Symfony applications unless you configure it as explained later in this article.
    form_div_layout.html.twig は、各フォーム フィールドを要素内にラップします。これは、この記事の後半で説明するように構成しない限り、Symfony アプリケーションでデフォルトで使用されるテーマです。
  • form_table_layout.html.twig, wraps the entire form inside a <table> element and each form field inside a <tr> element.
    form_table_layout.html.twig は、フォーム全体を要素内にラップし、各フォーム フィールドを要素内にラップします。
  • bootstrap_3_layout.html.twig, wraps each form field inside a <div> element with the appropriate CSS classes to apply the styles used by the Bootstrap 3 CSS framework.
    bootstrap_3_layout.html.twig は、要素内の各フォーム フィールドを適切な CSS クラスでラップし、Bootstrap 3 CSS フレームワークで使用されるスタイルを適用します。
  • bootstrap_3_horizontal_layout.html.twig, it's similar to the previous theme, but the CSS classes applied are the ones used to display the forms horizontally (i.e. the label and the widget in the same row).
    bootstrap_3_horizo​​ntal_layout.html.twig、これは前のテーマに似ていますが、適用される CSS クラスは、フォームを水平に表示するために使用されるものです (つまり、ラベルとウィジェットが同じ行に表示されます)。
  • bootstrap_4_layout.html.twig, same as bootstrap_3_layout.html.twig, but updated for Bootstrap 4 CSS framework styles.
    bootstrap_4_layout.html.twig、bootstrap_3_layout.html.twig と同じですが、Bootstrap 4 CSS フレームワーク スタイル用に更新されています。
  • bootstrap_4_horizontal_layout.html.twig, same as bootstrap_3_horizontal_layout.html.twig but updated for Bootstrap 4 styles.
    bootstrap_4_horizo​​ntal_layout.html.twig は、bootstrap_3_horizo​​ntal_layout.html.twig と同じですが、Bootstrap 4 スタイル用に更新されています。
  • bootstrap_5_layout.html.twig, same as bootstrap_4_layout.html.twig, but updated for Bootstrap 5 CSS framework styles.
    bootstrap_5_layout.html.twig、bootstrap_4_layout.html.twig と同じですが、Bootstrap 5 CSS フレームワーク スタイル用に更新されています。
  • bootstrap_5_horizontal_layout.html.twig, same as bootstrap_4_horizontal_layout.html.twig but updated for Bootstrap 5 styles.
    bootstrap_5_horizo​​ntal_layout.html.twig は、bootstrap_4_horizo​​ntal_layout.html.twig と同じですが、Bootstrap 5 スタイル用に更新されています。
  • foundation_5_layout.html.twig, wraps each form field inside a <div> element with the appropriate CSS classes to apply the default styles of the version 5 of Foundation CSS framework.
    foundation_5_layout.html.twig は、要素内の各フォーム フィールドを適切な CSS クラスでラップし、Foundation CSS フレームワークのバージョン 5 のデフォルト スタイルを適用します。
  • foundation_6_layout.html.twig, wraps each form field inside a <div> element with the appropriate CSS classes to apply the default styles of the version 6 of Foundation CSS framework.
    foundation_6_layout.html.twig は、要素内の各フォーム フィールドを適切な CSS クラスでラップし、Foundation CSS フレームワークのバージョン 6 のデフォルト スタイルを適用します。
  • tailwind_2_layout.html.twig, wraps each form field inside a <div> element with the absolute minimum styles to make them usable. It is based on the Tailwind CSS form plugin.
    tailwind_2_layout.html.twig は、各フォーム フィールドを要素内にラップし、絶対に最小限のスタイルを使用できるようにします。これは、Tailwind CSS フォーム プラグインに基づいています。

Tip

ヒント

Read the articles about Bootstrap 4 Symfony form theme and Bootstrap 5 Symfony form theme to learn more about them.

Bootstrap 4 Symfony フォーム テーマと Bootstrap 5 Symfony フォーム テーマに関する記事を読んで、それらについて詳しく学んでください。

Applying Themes to all Forms

Symfony forms use by default the form_div_layout.html.twig theme. If you want to use another theme for all the forms of your app, configure it in the twig.form_themes option:

symfony フォームはデフォルトで form_div_layout.html.twig テーマを使用します。アプリのすべてのフォームに別のテーマを使用する場合は、twig.form_themes オプションで設定します。
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
4
# config/packages/twig.yaml
twig:
    form_themes: ['bootstrap_5_horizontal_layout.html.twig']
    # ...

You can pass multiple themes to this option because sometimes form themes only redefine a few elements. This way, if some theme doesn't override some element, Symfony looks up in the other themes.

フォーム テーマは少数の要素のみを再定義する場合があるため、このオプションに複数のテーマを渡すことができます。このように、一部のテーマが一部の要素をオーバーライドしない場合、Symfony は他のテーマを検索します。

The order of the themes in the twig.form_themes option is important. Each theme overrides all the previous themes, so you must put the most important themes at the end of the list.

twig.form_themes オプションでのテーマの順序は重要です。各テーマは以前のすべてのテーマを上書きするため、最も重要なテーマをリストの最後に配置する必要があります。

Applying Themes to Single Forms

Although most of the times you'll apply form themes globally, you may need to apply a theme only to some specific form. You can do that with the form_theme Twig tag:

ほとんどの場合、フォーム テーマをグローバルに適用しますが、特定のフォームだけにテーマを適用する必要がある場合もあります。 form_theme Twig タグでそれを行うことができます:
1
2
3
4
5
6
{# this form theme will be applied only to the form of this template #}
{% form_theme form 'foundation_5_layout.html.twig' %}

{{ form_start(form) }}
    {# ... #}
{{ form_end(form) }}

The first argument of the form_theme tag (form in this example) is the name of the variable that stores the form view object. The second argument is the path of the Twig template that defines the form theme.

form_theme タグ (この例では form) の最初の引数は、フォーム ビュー オブジェクトを格納する変数の名前です。 2 番目の引数は、フォームのテーマを定義する Twig テンプレートのパスです。

Applying Multiple Themes to Single Forms

A form can also be customized by applying several themes. To do this, pass the path of all the Twig templates as an array using the with keyword (their order is important, because each theme overrides all the previous ones):

複数のテーマを適用して、フォームをカスタマイズすることもできます。これを行うには、 with キーワードを使用して、すべての Twig テンプレートのパスを配列として渡します (各テーマは以前のテーマをすべてオーバーライドするため、順序が重要です)。
1
2
3
4
5
6
7
{# apply multiple form themes but only to the form of this template #}
{% form_theme form with [
    'foundation_5_layout.html.twig',
    'form/my_custom_theme.html.twig'
] %}

{# ... #}

Applying Different Themes to Child Forms

You can also apply a form theme to a specific child of your form:

フォーム テーマをフォームの特定の子に適用することもできます。
1
{% form_theme form.a_child_form 'form/my_custom_theme.html.twig' %}

This is useful when you want to have a custom theme for a nested form that's different from the one of your main form. Specify both your themes:

これは、メイン フォームのテーマとは異なる、ネストされたフォーム用のカスタム テーマが必要な場合に便利です。両方のテーマを指定します。
1
2
{% form_theme form 'form/my_custom_theme.html.twig' %}
{% form_theme form.a_child_form 'form/my_other_theme.html.twig' %}

Disabling Global Themes for Single Forms

Global form themes defined in the app are always applied to all forms, even those which use the form_theme tag to apply their own themes. You may want to disable this for example when creating an admin interface for a bundle which can be installed on different Symfony applications (and so you can't control what themes are enabled globally). To do that, add the only keyword after the list of form themes:

アプリで定義されたグローバル フォーム テーマは、form_theme タグを使用して独自のテーマを適用するものであっても、常にすべてのフォームに適用されます。たとえば、さまざまな Symfony アプリケーションにインストールできるバンドルの管理インターフェースを作成するときに、これを無効にしたい場合があります (したがって、どのテーマをグローバルに有効にするかを制御することはできません)。これを行うには、フォーム テーマのリストの後に only キーワードを追加します。
1
2
3
{% form_theme form with ['foundation_5_layout.html.twig'] only %}

{# ... #}

Caution

注意

When using the only keyword, none of Symfony's built-in form themes (form_div_layout.html.twig, etc.) will be applied. In order to render your forms correctly, you need to either provide a fully-featured form theme yourself, or extend one of the built-in form themes with Twig's use keyword instead of extends to re-use the original theme contents.

only キーワードを使用すると、Symfony の組み込みフォーム テーマ (form_div_layout.html.twig など) は適用されません。フォームを正しくレンダリングするには、完全な機能を備えたフォーム テーマを自分で提供するか、元のテーマ コンテンツを再利用するために extends の代わりに Twig の use キーワードを使用して組み込みフォーム テーマの 1 つを拡張する必要があります。
1
2
3
4
{# templates/form/common.html.twig #}
{% use "form_div_layout.html.twig" %}

{# ... #}

Creating your Own Form Theme

Symfony uses Twig blocks to render each part of a form - field labels, errors, <input> text fields, <select> tags, etc. A theme is a Twig template with one or more of those blocks that you want to use when rendering a form.

symfony は Twig ブロックを使用して、フォームの各部分 (フィールド ラベル、エラー、テキスト フィールド、タグなど) をレンダリングします。テーマは、フォームをレンダリングするときに使用する 1 つ以上のブロックを含む Twig テンプレートです。

Consider for example a form field that represents an integer property called age. If you add this to the template:

たとえば、age という整数プロパティを表すフォーム フィールドを考えてみましょう。これをテンプレートに追加すると:
1
{{ form_widget(form.age) }}

The generated HTML content will be something like this (it will vary depending upon the form themes enabled in your app):

生成された HTML コンテンツは次のようになります (アプリで有効になっているフォーム テーマによって異なります)。
1
<input type="number" id="form_age" name="form[age]" required="required" value="33"/>

Symfony uses a Twig block called integer_widget to render that field. This is because the field type is integer and you're rendering its widget (as opposed to its label or errors or help). The first step to create a form theme is to know which Twig block to override, as explained in the following section.

Symfony は integer_widget と呼ばれる Twig ブロックを使用してそのフィールドをレンダリングします。これは、フィールド タイプが整数であり、そのウィジェットを (ラベル、エラー、またはヘルプとは対照的に) レンダリングしているためです。フォーム テーマを作成する最初のステップは、次のセクションで説明するように、どの Twig ブロックをオーバーライドするかを知ることです。

Form Fragment Naming

The naming of form fragments varies depending on your needs:

フォーム フラグメントの命名は、必要に応じて異なります。
  • If you want to customize all fields of the same type (e.g. all <textarea>) use the field-type_field-part pattern (e.g. textarea_widget).
    同じタイプ (例: all ) のすべてのフィールドをカスタマイズする場合は、field-type_field-part パターン (例: textarea_widget) を使用します。
  • If you want to customize only one specific field (e.g. the <textarea> used for the description field of the form that edits products) use the _field-id_field-part pattern (e.g. _product_description_widget).
    特定のフィールドを 1 つだけカスタマイズする場合 (例: 製品を編集するフォームの説明フィールドに使用されるフィールド)、_field-id_field-part パターン (例: _product_description_widget) を使用します。

In both cases, the field-part can be any of these valid form field parts:

どちらの場合も、field-part は次の有効なフォーム フィールド パーツのいずれかになります。

Fragment Naming for All Fields of the Same Type

These fragment names follow the type_part pattern, where the type corresponds to the field type being rendered (e.g. textarea, checkbox, date, etc) and the part corresponds to what is being rendered (e.g. label, widget, etc.)

これらのフラグメント名は type_part パターンに従います。ここで、type はレンダリングされるフィールド タイプ (例: textarea、checkbox、date など) に対応し、part はレンダリングされるもの (例: label、widget など) に対応します。

A few examples of fragment names are:

フラグメント名の例は次のとおりです。
  • form_row - used by form_row() to render most fields;
    form_row - ほとんどのフィールドをレンダリングするために form_row() によって使用されます。
  • textarea_widget - used by form_widget() to render a textarea field type;
    textarea_widget - form_widget() で textarea フィールド タイプをレンダリングするために使用されます。
  • form_errors - used by form_errors() to render errors for a field;
    form_errors - フィールドのエラーを表示するために form_errors() によって使用されます。

Fragment Naming for Individual Fields

These fragment names follow the _id_part pattern, where the id corresponds to the field id attribute (e.g. product_description, user_age, etc) and the part corresponds to what is being rendered (e.g. label, widget, etc.)

これらのフラグメント名は _id_part パターンに従います。ここで、id はフィールド ID 属性 (例: product_description、user_age など) に対応し、パーツはレンダリングされるもの (例: ラベル、ウィジェットなど) に対応します。

The id attribute contains both the form name and the field name (e.g. product_price). The form name can be set manually or generated automatically based on your form type name (e.g. ProductType equates to product). If you're not sure what your form name is, look at the HTML code rendered for your form. You can also define this value explicitly with the block_name option:

id 属性には、フォーム名とフィールド名 (例: product_price) の両方が含まれます。フォーム名は手動で設定することも、フォーム タイプ名に基づいて自動的に生成することもできます (例: ProductType は製品に相当します)。フォーム名がわからない場合は、フォーム用にレンダリングされた HTML コードを確認してください。 block_name オプションを使用して、この値を明示的に定義することもできます。
1
2
3
4
5
6
7
8
9
10
11
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;

public function buildForm(FormBuilderInterface $builder, array $options): void
{
    // ...

    $builder->add('name', TextType::class, [
        'block_name' => 'custom_name',
    ]);
}

In this example, the fragment name will be _product_custom_name_widget instead of the default _product_name_widget.

この例では、フラグメント名はデフォルトの _product_name_widget ではなく _product_custom_name_widget になります。

Custom Fragment Naming for Individual Fields

The block_prefix option allows form fields to define their own custom fragment name. This is mostly useful to customize some instances of the same field without having to create a custom form type:

block_prefix オプションを使用すると、フォーム フィールドで独自のカスタムフラグメント名を定義できます。これは、カスタム フォーム タイプを作成することなく、samefield のいくつかのインスタンスをカスタマイズするのに最も役立ちます。
1
2
3
4
5
6
7
8
9
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;

public function buildForm(FormBuilderInterface $builder, array $options): void
{
    $builder->add('name', TextType::class, [
        'block_prefix' => 'wrapped_text',
    ]);
}

Now you can use wrapped_text_row, wrapped_text_widget, etc. as the block names.

これで、wrapped_text_row、wrapped_text_widget などをブロック名として使用できるようになりました。

Fragment Naming for Collections

When using a collection of forms, you have several ways of customizing the collection and each of its entries. First, use the following blocks to customize each part of all form collections:

フォームのコレクションを使用する場合、コレクションとその各エントリをカスタマイズする方法がいくつかあります。まず、次のブロックを使用して、すべてのフォーム コレクションの各部分をカスタマイズします。
1
2
3
4
5
{% block collection_row %} ... {% endblock %}
{% block collection_label %} ... {% endblock %}
{% block collection_widget %} ... {% endblock %}
{% block collection_help %} ... {% endblock %}
{% block collection_errors %} ... {% endblock %}

You can also customize each entry of all collections with the following blocks:

次のブロックを使用して、すべてのコレクションの各エントリをカスタマイズすることもできます。
1
2
3
4
5
{% block collection_entry_row %} ... {% endblock %}
{% block collection_entry_label %} ... {% endblock %}
{% block collection_entry_widget %} ... {% endblock %}
{% block collection_entry_help %} ... {% endblock %}
{% block collection_entry_errors %} ... {% endblock %}

Finally, you can customize specific form collections instead of all of them. For example, consider the following complex example where a TaskManagerType has a collection of TaskListType which in turn has a collection of TaskType:

最後に、フォーム コレクションのすべてではなく、特定のフォーム コレクションをカスタマイズできます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class TaskManagerType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options = []): void
    {
        // ...
        $builder->add('taskLists', CollectionType::class, [
            'entry_type' => TaskListType::class,
            'block_name' => 'task_lists',
        ]);
    }
}

class TaskListType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options = []): void
    {
        // ...
        $builder->add('tasks', CollectionType::class, [
            'entry_type' => TaskType::class,
        ]);
    }
}

class TaskType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options = []): void
    {
        $builder->add('name');
        // ...
    }
}

Then you get all the following customizable blocks (where * can be replaced by row, widget, label, or help):

次に、次のカスタマイズ可能なブロックをすべて取得します (* は、行、ウィジェット、ラベル、またはヘルプに置き換えることができます)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{% block _task_manager_task_lists_* %}
    {# the collection field of TaskManager #}
{% endblock %}

{% block _task_manager_task_lists_entry_* %}
    {# the inner TaskListType #}
{% endblock %}

{% block _task_manager_task_lists_entry_tasks_* %}
    {# the collection field of TaskListType #}
{% endblock %}

{% block _task_manager_task_lists_entry_tasks_entry_* %}
    {# the inner TaskType #}
{% endblock %}

{% block _task_manager_task_lists_entry_tasks_entry_name_* %}
    {# the field of TaskType #}
{% endblock %}

Template Fragment Inheritance

Each field type has a parent type (e.g. the parent type of textarea is text, and the parent type of text is form) and Symfony uses the fragment for the parent type if the base fragment doesn't exist.

各フィールド タイプには親タイプがあり (たとえば、テキストエリアの親タイプはテキストで、テキストの親タイプはフォームです)、基本フラグメントが存在しない場合、Symfony は親タイプにフラグメントを使用します。

When Symfony renders for example the errors for a textarea type, it looks first for a textarea_errors fragment before falling back to the text_errors and form_errors fragments.

たとえば Symfony が textarea タイプのエラーをレンダリングするとき、最初に textarea_errors フラグメントを探してから、text_errors および form_errors フラグメントにフォールバックします。

Tip

ヒント

The "parent" type of each field type is available in the form type reference for each field type.

各フィールド タイプの「親」タイプは、各フィールド タイプのフォーム タイプ リファレンスで利用できます。

Creating a Form Theme in the same Template as the Form

This is recommended when doing customizations specific to a single form in your app, such as changing all <textarea> elements of a form or customizing a very special form field which will be handled with JavaScript.

これは、フォームのすべての要素を変更したり、JavaScript で処理される非常に特殊なフォーム フィールドをカスタマイズしたりするなど、アプリ内の 1 つのフォームに固有のカスタマイズを行う場合に推奨されます。

You only need to add the special {% form_theme form _self %} tag to the same template where the form is rendered. This causes Twig to look inside the template for any overridden form blocks:

特別な {% form_theme form _self %} タグを、フォームがレンダリングされる同じテンプレートに追加するだけで済みます。これにより、Twig はテンプレート内でオーバーライドされたフォーム ブロックを探します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{% extends 'base.html.twig' %}

{% form_theme form _self %}

{# this overrides the widget of any field of type integer, but only in the
   forms rendered inside this template #}
{% block integer_widget %}
    <div class="...">
        {# ... render the HTML element to display this field ... #}
    </div>
{% endblock %}

{# this overrides the entire row of the field whose "id" = "product_stock" (and whose
   "name" = "product[stock]") but only in the forms rendered inside this template #}
{% block _product_stock_row %}
    <div class="..." id="...">
        {# ... render the entire field contents, including its errors ... #}
    </div>
{% endblock %}

{# ... render the form ... #}

The main disadvantage of this method is that it only works if your template extends another ('base.html.twig' in the previous example). If your template does not, you must point form_theme to a separate template, as explained in the next section.

この方法の主な欠点は、テンプレートが別のテンプレート (前の例では「base.html.twig」) を拡張する場合にのみ機能することです。テンプレートがそうでない場合は、次のセクションで説明するように、form_theme を別のテンプレートにポイントする必要があります。

Another disadvantage is that the customized form blocks can't be reused when rendering other forms in other templates. If that's what you need, create a form theme in a separate template as explained in the next section.

もう 1 つの欠点は、他のテンプレートで他のフォームをレンダリングするときに、カスタマイズされたフォーム ブロックを再利用できないことです。それが必要な場合は、次のセクションで説明するように、別のテンプレートでフォームテーマを作成してください。

Creating a Form Theme in a Separate Template

This is recommended when creating form themes that are used in your entire app or even reused in different Symfony applications. You only need to create a Twig template somewhere and follow the form fragment naming rules to know which Twig blocks to define.

これは、アプリ全体で使用されるフォーム テーマを作成する場合や、別の Symfony アプリケーションで再利用する場合にも推奨されます。どこかで Twigtemplate を作成し、フォーム フラグメントの命名規則に従うだけで、どの Twig ブロックを定義するかを知ることができます。

For example, if your form theme is simple and you only want to override the <input type="integer"> elements, create this template:

たとえば、フォームのテーマが単純で、要素のみをオーバーライドする場合は、次のテンプレートを作成します。
1
2
3
4
5
6
{# templates/form/my_theme.html.twig #}
{% block integer_widget %}

    {# ... add all the HTML, CSS and JavaScript needed to render this field #}

{% endblock %}

Now you need to tell Symfony to use this form theme instead of (or in addition to) the default theme. As explained in the previous sections of this article, if you want to apply the theme globally to all forms, define the twig.form_themes option:

次に、デフォルトのテーマの代わりに (またはそれに加えて) このフォーム テーマを使用するように Symfony に指示する必要があります。この記事の前のセクションで説明したように、テーマをすべてのフォームにグローバルに適用する場合は、twig.form_themes オプションを定義します。
  • YAML
    YAML
  • XML
    XML
  • PHP
    PHP
1
2
3
4
# config/packages/twig.yaml
twig:
    form_themes: ['form/my_theme.html.twig']
    # ...

If you only want to apply it to some specific forms, use the form_theme tag:

特定のフォームにのみ適用する場合は、form_theme タグを使用します。
1
2
3
4
5
{% form_theme form 'form/my_theme.html.twig' %}

{{ form_start(form) }}
    {# ... #}
{{ form_end(form) }}

Reusing Parts of a Built-In Form Theme

Creating a complete form theme takes a lot of work because there are too many different form field types. Instead of defining all those Twig blocks, you can define only the blocks you are interested in and then configure multiple form themes in your app or template. This works because when rendering a block which is not overridden in your custom theme, Symfony falls back to the other themes.

さまざまなフォーム フィールド タイプが多すぎるため、完全なフォーム テーマを作成するには多くの作業が必要です。これらの Twig ブロックをすべて定義する代わりに、関心のあるブロックのみを定義して、アプリまたはテンプレートで複数のフォームテーマを構成できます。これが機能するのは、カスタム テーマでオーバーライドされていないブロックをレンダリングするときに、Symfony が他のテーマにフォールバックするためです。

Another solution is to make your form theme template extend from one of the built-in themes using the Twig "use" tag instead of the extends tag so you can inherit all its blocks (if you are unsure, extend from the default form_div_layout.html.twig theme):

もう 1 つの解決策は、extends タグの代わりに Twig の「use」タグを使用して、組み込みテーマの 1 つからフォーム テーマ テンプレートを拡張し、そのすべてのブロックを継承できるようにすることです (よくわからない場合は、defaultform_div_layout.html.twig テーマから拡張します)。 ):
1
2
3
4
{# templates/form/my_theme.html.twig #}
{% use 'form_div_layout.html.twig' %}

{# ... override only the blocks you are interested in #}

Finally, you can also use the Twig parent() function to reuse the original content of the built-in theme. This is useful when you only want to make minor changes, such as wrapping the generated HTML with some element:

最後に、Twig の parent() 関数を使用して、組み込みテーマの元のコンテンツを再利用することもできます。これは、生成された HTML をいくつかの要素でラップするなど、マイナーな変更のみを行いたい場合に便利です。
1
2
3
4
5
6
7
8
{# templates/form/my_theme.html.twig #}
{% use 'form_div_layout.html.twig' %}

{% block integer_widget %}
    <div class="some-custom-class">
        {{ parent() }}
    </div>
{% endblock %}

This technique also works when defining the form theme in the same template that renders the form. However, importing the blocks from the built-in themes is a bit more complicated:

この手法は、フォームをレンダリングする同じテンプレートでフォーム テーマを定義する場合にも機能します。ただし、組み込みテーマからブロックをインポートするのは少し複雑です。
1
2
3
4
5
6
7
8
9
10
11
12
13
{% form_theme form _self %}

{# import a block from the built-in theme and rename it so it doesn't
   conflict with the same block defined in this template #}
{% use 'form_div_layout.html.twig' with integer_widget as base_integer_widget %}

{% block integer_widget %}
    <div class="some-custom-class">
        {{ block('base_integer_widget') }}
    </div>
{% endblock %}

{# ... render the form ... #}

Customizing the Form Validation Errors

If you define validation rules for your objects, you'll see some validation error messages when the submitted data is not valid. These messages are displayed with the form_errors() function and can be customized with the form_errors Twig block in any form theme, as explained in the previous sections.

オブジェクトの検証ルールを定義すると、送信されたデータが有効でない場合に検証エラー メッセージが表示されます。これらのメッセージは form_errors() 関数で表示され、前のセクションで説明したように、フォームテーマの form_errors Twig ブロックでカスタマイズできます。

An important thing to consider is that certain errors are associated to the entire form instead of a specific field. In order to differentiate between global and local errors, use one of the variables available in forms called compound. If it is true, it means that what's being currently rendered is a collection of fields (e.g. a whole form), and not just an individual field:

考慮すべき重要な点は、特定のエラーが特定のフィールドではなくフォーム全体に関連付けられていることです。グローバル エラーとローカル エラーを区別するには、compound という形式で使用できる変数の 1 つを使用します。 true の場合、現在レンダリングされているのは、個々のフィールドだけでなく、フィールドのコレクション (フォーム全体など) であることを意味します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{# templates/form/my_theme.html.twig #}
{% block form_errors %}
    {% if errors|length > 0 %}
        {% if compound %}
            {# ... display the global form errors #}
            <ul>
                {% for error in errors %}
                    <li>{{ error.message }}</li>
                {% endfor %}
            </ul>
        {% else %}
            {# ... display the errors for a single field #}
        {% endif %}
    {% endif %}
{% endblock form_errors %}