Как работать с темами формы

Как работать с темами формы

Каждая частьформы отображается и может быть настроена. Вы вольны изменять то, как отображается каждая "строка" формы, разметку, используемую для отображения ошибок или даже то, как должен быть отображён тег textarea. Нет ничего запрещённого, и разные настройки могут быть использованы в разных местах.

Symfony использует шаблоны, чтобы отобразить каждую часть формы, такие как теги label, input, сообщения об ошибках и всё остальное.

В Twig, каждый "фрагмент" формы представлен блоком Twig. Чтобы настроить любую часть того, как отображается форма, вам просто нужно переопределить соответствующий блок.

В PHP, каждый "фрагмент" формы отображается через индивидуальный файл шаблона. Чтобы настроить любую часть отображения формы, вам просто нужно переопределить существующий шаблон, создав новый.

Чтобы понять, как это работает, настройте фрагмент form_row и добавьте атрибут класса к элементу div, который окружает каждую строку. Чтобы сделать это, создайте новый файл щаблона, который будет хранить новую разметку:

  • Twig
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    {# app/Resources/views/form/fields.html.twig #}
    {% block form_row %}
    {% spaceless %}
        <div class="form_row">
            {{ form_label(form) }}
            {{ form_errors(form) }}
            {{ form_widget(form) }}
        </div>
    {% endspaceless %}
    {% endblock form_row %}
    
  • PHP
    1
    2
    3
    4
    5
    6
    <!-- app/Resources/views/form/form_row.html.php -->
    <div class="form_row">
        <?php echo $view['form']->label($form, $label) ?>
        <?php echo $view['form']->errors($form) ?>
        <?php echo $view['form']->widget($form, $parameters) ?>
    </div>
    

Фрагмент формы form_row используется при отображении большинства полей через функцию form_row(). Чтобы сообщить компоненту формы, что нужно использовать новый фрагмент form_row, определённый выше, добавьте следующее сверху шаблона, отображающего форму:

  • Twig
    1
    2
    3
    4
    5
    6
    7
    {# app/Resources/views/default/new.html.twig #}
    {% form_theme form 'form/fields.html.twig' %}
    
    {# или, если вы хотите использовать несколько тем #}
    {% form_theme form 'form/fields.html.twig' 'form/fields2.html.twig' %}
    
    {# ... render the form #}
    
  • PHP
    1
    2
    3
    4
    5
    6
    7
    <!-- app/Resources/views/default/new.html.php -->
    <?php $view['form']->setTheme($form, array('form')) ?>
    
    <!-- или, если вы хотите использовать несколько тем -->
    <?php $view['form']->setTheme($form, array('form', 'form2')) ?>
    
    <!-- ... render the form -->
    

Тег form_theme (в Twig) "импортирует" фрагменты, определённые в данном шаблоне и использует их при отображении формы. Другими словами, когда позже в этом шаблоне будет вызвана функция form_row(), она будет использовать блок form_row из вашей пользовательской темы (вместо блока form_row по умолчанию, который поставляется в Symfony).

Ваша пользовательская тема не должна переопределять все блоки. При отображении блока, который не переопределяется в вашей пользовательской теме, механизм тем будет использовать глобальную тему в качестве отката (определённую на уровне пакетов).

Если предоставлены несколько пользовательских тем, будет вестись их поиск в определённом порядке перед тем, как использовать глобальную тему в качестве резерва.

Чтобы настроить любую часть формы, вам просто нужно переопределить соответствующий фрагмент. Понимание того, какой именно блок или файл нужно переопределить является темой следующего раздела.

Для более подробной дискуссии, смотрите How to Customize Form Rendering.

Именование фрагментов шаблона

В Symfony, каждая часть отображённой формы - HTML-элементы формы, ошибки, ярлыки и т.д. - определяются в базовой теме, которая является коллекцией блоков в Twig и коллекцией файлов шаблонов в PHP.

В Twig, каждый необходимый блок определён в единственном файле шаблона (например, form_div_layout.html.twig), который живет внутри Моста Twig. Внутри этого файла, вы можете увидеть каждый необходимый для отображения формы блок и каждый тип поля по умолчанию.

В PHP, фрагменты - это индивидуальные файлы шаблонов. По умолчанию, они находятся в каталоге Resources/views/Form FrameworkBundle (посмотреть на GitHub).

Каждое имя фрагмента следует одной базовой схеме и разделяется на две части, разделённые одним символом нижнего подчёркивания (_). Вот несколько примеров:

  • form_row - используется form_row() для отображения большинства полей;
  • textarea_widget - используется form_widget() для отображения типа поля``textarea``;
  • form_errors - используется form_errors() для отображения ошибок поля;

Каждый фрагмент следует одной базовой схеме: type_part. Часть type соответствует типу отображаемого поля (например, textarea, checkbox, date, и т.д.), а часть part - тому, что отображается (например, label, widget, errors, и т.д.). По умолчанию, существует 4 возможных части формы, которые можно отобразить:

label (например, form_label()) | отображает ярлык поля
widget (например, form_widget()) | отображает HTML-представление поля
errors (например, form_errors()) | отображает ошибки поля
row (например, form_row()) | отображает всю строку поля (ярлык, виджет и ошибки

Note

На самом деле есть ещё 2 другие части - rows и rest - но вам очень редко, либо вообще никогда, не понадобится переопределять их.

Зная тип поля (например, textarea) и то, какую часть вы хотите настроить (например, widget), вы можете построить имя фрагмента, которое нужно переопределить (например, textarea_widget).

Наследование фрагментов шаблона

В некоторых случаях, фрагмент, который вы хотите настроить, будет отсутствовать. Например, не существует фрагмента textarea_errors в темах, предоставленных Symfony по умолчанию. Так как же отображаются ошибки для текстового поля?

Ответ: через фрагмент form_errors. Когда Symfony отображает ошибки для типа текстового поля, она в первую очередь ищет фрагмент textarea_errors до того, как использовать резеврный фрагмент form_errors. Каждый тип поля имеет родительский тип (родительский тип textarea - text, а его родитель - form), и Symfony использует фрагмент для родительского типа, если базовый фрагмент не существует.

Итак, чтобы переопределить ошибки только для полей textarea, скопируйте фрагмент form_errors, переименуйте его на textarea_errors и настройте его. Чтобы переопределить отображение ошибки по умолчанию для всех полей, скопируйте и настройте фрагмент form_errors напрямую.

Tip

"Родительский" тип каждого типа поля доступен в справочнике типов полей.

Глобальные темы

В примере выше, вы использовали помощник form_theme (в Twig), чтобы "импортировать" пользовательские фрагменты формы только в эту форму. Вы также можете сказать Symfony испортировать пользовательские формы по всему вашему проекту.

Twig

Чтобы автоматически включить настроенные блоки из шаблона fields.html.twig, созданного ранее во все шаблоны, измените ваш файл конфигурации приложения:

  • YAML
    1
    2
    3
    4
    5
    # app/config/config.yml
    twig:
        form_themes:
            - 'form/fields.html.twig'
        # ...
    
  • XML
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    <!-- app/config/config.xml -->
    <?xml version="1.0" encoding="UTF-8" ?>
    <container xmlns="http://symfony.com/schema/dic/services"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:twig="http://symfony.com/schema/dic/twig"
        xsi:schemaLocation="http://symfony.com/schema/dic/services
            http://symfony.com/schema/dic/services/services-1.0.xsd
            http://symfony.com/schema/dic/twig http://symfony.com/schema/dic/twig/twig-1.0.xsd">
    
        <twig:config>
            <twig:theme>form/fields.html.twig</twig:theme>
            <!-- ... -->
        </twig:config>
    </container>
    
  • PHP
    1
    2
    3
    4
    5
    6
    7
    // app/config/config.php
    $container->loadFromExtension('twig', array(
        'form_themes' => array(
            'form/fields.html.twig',
        ),
        // ...
    ));
    

Любые блоки внутри шаблона fields.html.twig теперь используются глобально, чтобы определить вывод формы.

В Twig, вы также можете настроить блок формы прямо внутри шаблона, где требуется пользовательская настройка:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
{% extends 'base.html.twig' %}

{# имппортирует "_self" в качестве темы формы #}
{% form_theme form _self %}

{# настроить фрагмент формы #}
{% block form_row %}
    {# вывод строки пользователького поля #}
{% endblock form_row %}

{% block content %}
    {# ... #}

    {{ form_row(form.task) }}
{% endblock %}

Тег {% form_theme form _self %} позволяет блокам формы быть настроенными прямо внутри шаблона, который будет использовать эти настройки. Используйте этот метод, чтобы быстро настроить вывод формы, который будет нужен только в одном шаблоне.

Caution

Функция {% form_theme form _self %} будет работать только, если ваш шаблон расширяет другой. Если ваш шаблон этого не делает, вы должны направить form_theme на отдельный шаблон.

PHP

Чтобы автоматически включать настроенные шаблоны из каталога app/Resources/views/form, созданного ранее во все щаблоны, измените ваш файл конфигурации приложения:

  • YAML
    1
    2
    3
    4
    5
    6
    7
    # app/config/config.yml
    framework:
        templating:
            form:
                resources:
                    - 'form'
    # ...
    
  • XML
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    <!-- app/config/config.xml -->
    <?xml version="1.0" encoding="UTF-8" ?>
    <container xmlns="http://symfony.com/schema/dic/services"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:framework="http://symfony.com/schema/dic/symfony"
        xsi:schemaLocation="http://symfony.com/schema/dic/services
            http://symfony.com/schema/dic/services/services-1.0.xsd
            http://symfony.com/schema/dic/symfony http://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
    
        <framework:config>
            <framework:templating>
                <framework:form>
                    <framework:resource>form</framework:resource>
                </framework:form>
            </framework:templating>
            <!-- ... -->
        </framework:config>
    </container>
    
  • PHP
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    // app/config/config.php
    $container->loadFromExtension('framework', array(
        'templating' => array(
            'form' => array(
                'resources' => array(
                    'form',
                ),
            ),
        ),
        // ...
    ));
    

Любые фрагменты внутри каталога app/Resources/views/form теперь используются глобально, чтобы определить вывод формы.

Эта документация является переводом официальной документации Symfony и предоставляется по свободной лицензии CC BY-SA 3.0.