I have a hard space (
) inside some of my choice options. Somehow, somewhere, they are being escaped. I have tried:
{% autoescape false %}
{{ form_widget(foobar) }}
{% endautoescape %}
As well as
{{ form_widget(foobar)|raw }}
And the following under Twig in config.yml
autoescape: false
Yet the choice fields are still rendered as Choice Text Here
instead of Choice Text Here
, and in the source they are being encoded as  Choice Text Here
In the controller I have:
$form ->add('foo', 'choice', array(
'label' => 'Foo Label',
'choices' => $fooChoices,
'required' => true));
$form = $form->getForm();
$foobar = $form->createView();
If I print_r
$fooChoices
I get:
Array ( [1] => 60# FooBar [5] => 60# BatBar [11] => 60# DooWop )
Which shows me the proper
(note the double space in front of the 60's). Somewhere between the FormBuilder and the rendering, it is getting escaped.
Is there built-in escaping inside the Form Builder?
What I have deduced is that through the point that the form view is rendered via $form->createView()
the data is still unescaped. But, by the time it reaches Twig via form_widget, it has been escaped. Doing form_widget(foobar)|raw
shows this.
Edit: I have added a workaround as an answer, but I'm still interested in accepting an answer that explains how to prevent the initial escaping from occurring altogether.
I ran into the same problem with radio labels. This solves it.
{% for child in form %}
{% autoescape false %}
{{ child.vars.label }}
{% endautoescape %}
{{ form_widget(child) }}
{% endfor %}
I've ended up creating a Twig extension that decodes encoded HTML and added it as a service:
The extension in Vendor/Bundle/Extensions/Twig
namespace Vendor\Bundle\Extensions\Twig;
class HTMLDecodeTwigExtension extends \Twig_Extension
{
public function getFilters()
{
return array(
'htmldecode' => new \Twig_Filter_Method($this, 'htmldecode', array(
'is_safe' => array('html'))
),
);
}
// your custom function
public function htmldecode($string)
{
return html_entity_decode($string);
}
// Name for Service
public function getName()
{
return 'html_decode_twig_extension';
}
}
Registering the service in Vendor/Bundle/Resources/config/services.yml
vendor_bundle.htmldecode:
class: Vendor\Bundle\Extensions\Twig\HTMLDecodeTwigExtension
tags:
- { name: twig.extension }
The usage:
{{ form_widget(foobar)|htmldecode }}
I still don't know where the escaping is being performed, as it is only performed on the data itself (and I tried creating a data event to modify the form's data), but this at least gives me the end result I'm looking for.
What you really should be doing is over-riding the form_label template
{% block form_label %}
{% spaceless %}
{% 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 %}
{% set label = name|humanize %}
{% endif %}
{% autoescape false %}<label{% for attrname, attrvalue in label_attr %} {{ attrname }}="{{ attrvalue }}"{% endfor %}>{{ label|trans({}, translation_domain) }}</label>{% endautoescape %}
{% endif %}
{% endspaceless %}
{% endblock form_label %}
Note the addition of the autoescape sections.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With