HTML в символах формы Symfony2 вместо обычного текста

Я пытаюсь реализовать что-то вроде этого:

<div>
    <input type="checkbox" name="checkbox" id="checkbox_id" />
    <label for="checkbox_id">I agree to the <a href="/tos">Terms of Service</a></label>
</div>

Ближайший я пришел реализовать это через:

<div>
    {{ form_widget(form.agreeWithTos) }}
    <label for="{{ form.agreeWithTos.vars.id }}">I agree to the <a href="#">Terms of Service</a></label>
</div>

Есть ли лучший способ? Необходимо указать {{form.agreeWithTos.vars.id}} неэлегантно.:)

Ответ 1

Решил эту проблему, используя следующий код в моей форме-теме:

{# ---- form-theme.html.twig #}
{% block checkbox_row %}
{% spaceless %}
<div>
    {{ form_errors(form) }}

    <label class="checkbox" for="{{ form.vars.id }}">
        {{ form_widget(form) }}
        {{ label|default(form_label(form)) | raw }}
    </label>
</div>
{% endspaceless %}
{% endblock %}

в вашем шаблоне формы, вы можете использовать:

{% form_theme form '::form-theme.html.twig' %}

{{form_row(form.termsOfServiceAccepted, {
        'label' : 'I have read and agree to the <a href="#">Terms and conditions</a>'
    })
}}

таким образом, блок из формы-темы применим к любому флажку на странице. Если вам нужно также использовать тему по умолчанию, вы можете добавить параметр для включения специального рендеринга:

{# ---- form-theme.html.twig #}
{% block checkbox_row %}
{% spaceless %}
    {% if not useTosStyle %}
        {{ parent() }}
    {% else %}
        {# ... special rendering ... #}
    {% endif %}
{% endspaceless %}
{% endblock %}

который будет использоваться следующим образом:

{% form_theme form '::form-theme.html.twig' %}

{{form_row(form.termsOfServiceAccepted, {
        'useTosStyle' : true,
        'label' : 'I have read and agree to the <a href="#">Terms and conditions</a>'
    })
}}

Ответ 2

Я бил свою голову над этим, тогда был момент эврики. Самый простой способ сделать это - BY FAR - создать расширение Twig.

Вот мой код Twig:

{# twig example #}
{% block form_label %}
    {% set label = parent() %}
    {{ label|unescape|raw }}
{% endblock %}

и PHP:

<?php
new Twig_SimpleFilter('unescape', function($value) {
    return html_entity_decode($value);
});

Несколько примечаний:

  • Это освобождает все ранее сэкономленные коды. После этого вам обязательно нужно вернуться после этого.
  • Для тэга целевой темы требуется тэг extends в вашей собственной теме пользовательской формы, которую вы можете использовать в своих последующих формах. Поместите код ветки в тему пользовательской формы и замените ссылки на вашу другую тему темы/темы с помощью этого.

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

Ответ 3

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

{% form_theme form _self %}

{% block form_label %}
    {{ label | raw }}
{% endblock %}

{{ form_start(form) }}

Смотрите соответствующий раздел в документации:

https://symfony.com/doc/current/form/form_customization.html#method-1-inside-the-same-template-as-the-form

Самый простой способ настроить блок [...] - настроить его непосредственно в шаблоне, который фактически отображает форму.

Используя специальный тег {% form_theme form _self%}, Twig ищет внутри одного и того же шаблона любые переопределенные блоки формы. [...]

Недостатком этого метода является то, что настраиваемый блок формы нельзя использовать повторно при отображении других форм в других шаблонах. Другими словами, этот метод наиболее полезен при создании настроек формы, специфичных для одной формы в вашем приложении. Если вы хотите повторно использовать настройку формы для нескольких (или всех) форм в вашем приложении, читайте следующий раздел.

Ответ 4

Я думаю, что вы ищете форму. Таким образом, вы можете в любой момент стилизовать каждую часть формы в независимом файле, а затем просто визуализировать ее "элегантным" способом, рядом с {{ form_row(form) }} или просто с {{ form_widget(form) }}. Это действительно зависит от вас, как вы его настроили.

Ответ 5

Другой подход заключается в использовании простой замены Twig:

{% set formHtml %}
   {{ form(oForm) }}
{% endset %}

{{ formHtml|replace({'[link]': '<a href=" ... ">', '[/link]': '</a>'})|raw }}

В вашей форме у вас есть что-то вроде этого, чтобы заставить его работать:

$formBuilder->add('conditions', CheckboxType::class, [
        'label' => 'Yes, I agree with the [link]terms and conditions[/link].'
    ]
);

Конечно, вы можете изменить [ссылку] на что-нибудь еще. Обратите внимание, что вы не используете теги HTML ;-)

Ответ 6

Таким образом, оформление формы довольно сложно. Самое легкое, что я нашел, это просто подавить метку поля ('label'=> false в классе формы Symfony), а затем просто добавить ярлык html в html twig.

Ответ 7

Вы можете использовать форму в другом виде: вы можете переместить тег <label> вне form_label().

Создайте настраиваемую тему формы, а для флажков переместите тег <label> вне функции form_label:

{% block checkbox_row %}
    <label>{{ form_label(form) }}</label>
    {{ form_errors(form) }}
    {{ form_widget(form) }}
{% endblock checkbox_row %}

{% block checkbox_label %}
    {{ label }}
{% endblock checkbox_label %}

Теперь, в вашем тесте, переопределите label вашего флажка и, таким образом, эффективно вставьте HTML в функцию метки:

{% form_theme form 'yourtheme.html.twig' _self %}

{% block _your_TOS_checkbox_label %}
    I agree with <a href="#" target="_blank">terms and conditions</a>
{% endblock _your_TOS_checkbox_label %}

Ответ 8

Symfony 4.2

TWIG:

{% block main %} 
   .... 
   {% form_theme form _self %}
...
 {{ form_row(form.policy, {'label': 'security.newPassword.policy'|trans({"%policyLink%":policyLink, "%termsLink%":termsLink})}) }}
   ...
{% endblock %}

{% block checkbox_radio_label %}
    <label{% with { attr: label_attr } %}{{ block('attributes') }}{% endwith %}>
        {{- widget|raw }} {{ label|unescape|raw }}
    </label>
{% endblock checkbox_radio_label %}

PHP:

use Twig\Extension\AbstractExtension;
use Twig\TwigFilter;

class AppExtension extends AbstractExtension
{
    public function getFilters()
    {
        return [
            new TwigFilter('unescape', function ($value) {
                return html_entity_decode($value);
            }),
        ];
    }
}