3
votes

I'm rendering a prototype using below code:

{{form_widget(form.get('prototype').myField, {'attr': {'value': '<%= myModelProperty %>'} }) }}

BackboneJS is supposed to read the code generated by this twig block, and replace the <%= myModelProperty %> by some model property value.

And this doesn't happen because the value is escaped in twig and thus replaced by:

&lt;%= viewport %&gt;

I've tried to force the value to RAW in the *form_div_layout.html* file:

> {% block field_widget %} {% spaceless %}
>     {% set type = type|default('text') %}
>     <input type="{{ type }}" {{ block('widget_attributes') }} {% if value is not empty %}value="{{ value|raw }}" {% endif %}/> {%
> endspaceless %} {% endblock field_widget %}

but without success.

So my question is how not to escape the field value in twig.

Thanks!

EDIT

Solution: So in fact the method was right, I have to use the "raw" filter to get my variable not escaped. I've an autoescape block set that englobe this particular output which is why the reason it has to be "un-escaped".

Twig bundle of Symfony 2 provided several block to render form data, and those uses a specific block for attribute rendering called "{% block widget_attributes %}".

What I did is edit this block (I've a separated template file with all my customized blocks) so I can add a layer of "should this value be escaped or not":

{% block widget_attributes %}
{% spaceless %}
    id="{{ id }}" name="{{ full_name }}"{% if read_only %} disabled="disabled"{% endif %}{% if required %} required="required"{% endif %}{% if max_length %} maxlength="{{ max_length }}"{% endif %}{% if pattern %} pattern="{{ pattern }}"{% endif %}

    {% for attrname,attrvalue in attr %}
        {# Attribute value can be defined as an array. ['data']: contains the actual value, ['escape']: boolean (true if the value HAS to be escaped)#}
        {% if attrvalue.data is defined %}
            {% if not attrvalue.escape %}
                {{attrname}}="{{ attrvalue.data|raw }}"
            {% else %}
                {{attrname}}="{{ attrvalue.data|e }}"
            {% endif %}
        {% else %}
            {{attrname}}="{{attrvalue}}"
        {% endif %} 
    {% endfor %}

{% endspaceless %}
{% endblock widget_attributes %}

Called from my twig file:

{{ form_widget(form.displays.get('prototype').myField, {'attr': {'value': { 'data': myvalue, 'escape': false } } }) }}

The escape is done when printing the value so in the {{ }} twig tag, so what I was doing earlier was sending an unescaped value to a block where the print is actually called and where the value was thus escaped.

This works for me! thanks!

2
Why don't you try to unescape the value in javascript ? If possible in JS, it will be easier.AdrienBrault
That might be a way to do it, but the cleaner way will be not to have it escaped it at first.LEM01
I found the solution! Described in the edit of my original post. Thanks everyone for the help!LEM01

2 Answers

3
votes

Solution: So in fact the method was right, I have to use the raw filter to get my variable not escaped. I've an autoescape block set that englobe this particular output which is why the reason it has to be "un-escaped".

Twig bundle of Symfony 2 provided several block to render form data, and those uses a specific block for attribute rendering called {% block widget_attributes %}.

What I did is edit this block (I've a separated template file with all my customized blocks) so I can add a layer of "should this value be escaped or not":

{% block widget_attributes %}
  {% spaceless %}
      id="{{ id }}" name="{{ full_name }}"{% if read_only %} disabled="disabled"{% endif %}{% if required %} required="required"{% endif %}{% if max_length %} maxlength="{{ max_length }}"{% endif %}{% if pattern %} pattern="{{ pattern }}"{% endif %}

      {% for attrname,attrvalue in attr %}
        {# Attribute value can be defined as an array. ['data']: contains the actual value, ['escape']: boolean (true if the value HAS to be escaped)#}
        {% if attrvalue.data is defined %}
          {% if not attrvalue.escape %}
            {{ attrname }}="{{ attrvalue.data|raw }}"
          {% else %}
            {{ attrname }}="{{ attrvalue.data|e }}"
          {% endif %}
        {% else %}
          {{ attrname }}="{{ attrvalue }}"
        {% endif %} 
      {% endfor %}

  {% endspaceless %}
{% endblock widget_attributes %}

Called from my twig file:

{{ form_widget(form.displays.get('prototype').myField, {'attr': {'value': { 'data': myvalue, 'escape': false } } }) }}

The escape is done when printing the value so in the {{ }} twig tag, so what I was doing earlier was sending an unescaped value to a block where the print is actually called and where the value was thus escaped.

This works for me! thanks!

1
votes

Using the raw filter is the proper way to do this. If you're not having success with that, then something else is wrong. Try clearing your cache or disable twig caching in app/config/config.yml

twig:
    cache: ~

If it's not a caching issue, then I'm unsure where to look next.