Вспомогательная функция средства визуализации пользовательских форм Symfony2


Я хочу определить новую функцию ветки "form_field", которая отображает form_label, form_widget и form_errors. Я не хочу переопределять form_row, потому что я уже сделал это для другой цели: form_row также обертывает контейнер <div/>, необходимый для моего макета. В частности, я добавляю классы начальной загрузки.

Зачем мне это нужно? Обычно я использую form_row, но у меня много строк формы, для которых я хочу разместить два или более полей в одной строке (например, "имя" и "фамилия"). В этих случаях я определяю свой перенос <div/> вручную, но я не хочу писать три вызова функций (form_label, form_widget и form_errors) каждый раз.

Я попытался указать пользовательскую функцию, но я получаю исключение при вызове функций twig там. Для этого решения мне нужно знать, как вызывать функции Twig из пользовательской функции.

Моя вторая попытка состояла в том, чтобы адаптировать решение Symfony для своих собственных помощников по форме. Я нашел эту строку в vendor/symfony/symfony/src/Symfony/Bridge/Twig/Extension/FormExtension.php :

new \Twig_SimpleFunction('form_widget', null, array('node_class' => 'Symfony\Bridge\Twig\Node\SearchAndRenderBlockNode', 'is_safe' => array('html'))),

Выглядит как функция, которая на самом деле просто отображает блок. Когда я адаптировал эту строку в своем приложении, возникло исключение, в котором Symfony утверждал, что блок с именем "form_field" не определен. Однако я определил этот блок в своем шаблоне пользовательской формы:

{% use 'bootstrap_3_horizontal_layout.html.twig' %}

{%- block form_field -%}
    {{- form_label(form) -}}
    {{- form_widget(form) -}}
    {{- form_errors(form) -}}
{%- endblock form_field -%}
Author: fishbone, 2016-04-18

1 answers

Объявите форму шаблона ветки/form_field.html.ветка:

{%- block form_field -%}
    {{- form_label(form, label) -}}
    {{- form_widget(form) -}}
    {{- form_errors(form) -}}
{%- endblock form_field -%}

Затем я использовал метод renderBlock в своей пользовательской функции Twig. Это мой файл расширения twig, как описано здесь:

namespace AppBundle\Twig;

class AppExtension extends \Twig_Extension
{
    protected $environment;
    private $template;

    public function __construct(\Twig_Environment $env)
    {
        $this->environment = $env;
    }


    public function getFunctions()
    {
        return array(
            'form_field' => new \Twig_SimpleFunction('form_field', array($this, 'formField'), array(
                'is_safe' => array('html')
            ))
        );
    }

    public function formField($form, $label = null)
    {
        $this->template = $this->environment->loadTemplate( '::Form/form_field.html.twig' );

        return $this->template->renderBlock('form_field', array(
            'form' => $form,
            'label' => $label
        ));
    }

    /**
     * Returns the name of the extension.
     *
     * @return string The extension name
     */
    public function getName()
    {
        return 'app_extension';
    }
}

Я настроил контейнер DI для передачи среды Twig_Environment для службы Appextension:

services:
    app.twig_extension:
        class: AppBundle\Twig\AppExtension
        arguments:
            - '@twig'
        tags:
            - { name: twig.extension }
 1
Author: fishbone, 2016-04-18 13:39:31