Dyanamic Variable names in Twig - symfony

For a series of similar named string how to I case them to a variable similar to php's $$variable ?
I have tried
{% for col in 1..cols %}
{% set field = 'field'~col %}
<td>
{{ form_widget(form.field) }}
</td>
{% endfor %}
But I get error property does not exist.

Solved it:
{% for col in 1..cols %}
{% set field = 'field'~col %}
<td>
{{ form_widget(attribute(form,field)) }}
</td>
{% endfor %}

Related

Twig - passing a parameter to a function with a dynamic variable name

I have Twig variables:
{{ totalAmountMonth0 }} ... {{ totalAmountMonth10 }}
I have a loop and I want to call this variable for example:
{{ totalAmountMonth5 }}
I want to give this variable to a function like this:
totalAmount.percentFromTotalAmount((totalAmountMonth5))
But this doesn't work:
{% for i in 0..10 %}
{{ totalAmount.percentFromTotalAmount(totalAmountMonth~i) }}
{% endfor %}
This doesn't work either:
{% for i in 0..10 %}
{{ totalAmount.percentFromTotalAmount('totalAmountMonth'~i) }}
{% endfor %}
Untested, but try this:
{% for i in 0..10 %}
{{ totalAmount.percentFromTotalAmount(attribute(_context, 'totalAmountMonth'~i)) }}
{% endfor %}
Just provide to your twig an array, which I suggest, or build it (see below example)
// use line below only if array isn't provided to twig
{% set totalAmounts = { totalAmount1, totalAmount2, ..., totalAmount10 } %} // pseudo-code; you need to declare all variables here
{% for ta in totalAmounts %}
{{ totalAmount.percentFromTotalAmount(ta) }}
{% endfor %}
Try to set that variable before and use it.
{% for i in 0..10 %}
{% set temp = 'totalAmountMonth'~i %}
{{ totalAmount.percentFromTotalAmount(temp) }}
{% endfor %}

How to retrieve the value (string) of an array's element and use it to retrieve the property value of an entity?

how to retrieve the value (string) of an array's element and retrieve the property value of an entity? I tried this:
{% for item in items %} //item is an entity
{% for column in columns %} //column is just an array with name of columns
{% set columna = column.value %}
{{ item.columna }}
{% endfor %}
{% endfor %}
If you want to access dynamically a property of an object, you can use the attribute function :
{% for item in items %}
{% for column in columns %}
{{ attribute(item , column.value) }}
{% endfor %}
{% endfor %}
Try this:
{% for item in items %} //item is an entity
{% for column in columns %} //column is just an array with name of columns
{% set columna = column.value %}
{{ attribute(item, columna) }}
{% endfor %}
{% endfor %}
I recommend reading the documentation.

count in twig without for loop

I want to total count resuslt. I have already done it like total group result and In total result in one product....
like:-
Total Group of Product = 15
In one group showing 36 product.
In second group showing 56 product.
I want to show total group product result = 36+56 => 92.
without for loop.
twig file:
<table>
<h2> Showing {{ templates | length }} Products</h2>
{% for groupResults in templates %}
{% if groupResults.doclist.docs[0].first_product_name is defined %}
Show all {{ groupResults | length }} results
<tr>
<td>
{{ groupResults.doclist.docs[0].first_product_name }}
{% if groupResults.doclist.numFound > 4 %}
Show all {{ groupResults.doclist.numFound }} results
{% endif %}
</td>
</tr>
<tr>
{% set count = 0 %}
{% for template in groupResults.doclist.docs %}
<td>
<a href="{{ path("customer_design_editor", { "templateSlug": template.slug, "productSlug": template.product_slug[0] }) }}">
<img src="{{ path("design_template_thumbnail_by_slug", { "slug": template.slug}) }}" alt="" />
</a>
</td>
{% set count = count + 1 %}
{% endfor %}
{% if count < 4 %}
{% for i in count..3 %}
<td> </td>
{% endfor %}
{% endif %}
{% else %}
{% endif %}
{% endfor %}
How about:
{% set totalCount = firstGroup|length + secondGroup|length %}

symfony2 form error vs field error theme (twig)

In Twig, is there a way to define a different theme for field errors as oppose to form related errors like CSRF error or composite unique constraints?
I want to display the field errors with a <span> and the form errors with a <ul>
{{ form_errors(form) }}
<table>
<tbody>
<tr>
<td>{{ form_label(form.tabla) }}</td>
<td>
{{ form_widget(form.tabla) }}
{{ form_errors(form.tabla) }}
</td>
<td></td>
<td>{{ form_label(form.descripcion) }}</td>
<td>
{{ form_widget(form.descripcion) }}
{{ form_errors(form.descripcion) }}
</td>
<td></td>
</tr>
</tbody>
</table>
This is my form theme that is being used for both cases (not what I want).
{% block field_errors %}
{% if errors|length > 0 %}
<span class="val-error">
{% for error in errors %}
{{ error.messageTemplate|trans(error.messageParameters, 'validators')~'. ' }}
{% endfor %}
</span>
{% endif %}
{% endblock field_errors %}
Is there a way to differentiate both cases?
Form class extends Field. If you set a new theme to field it will be applied to form.
You should override the field_errors block as you did, and then define the form_errors block using another template (with th ul tag).
{% block field_errors %}
{% if errors|length > 0 %}
<span class="val-error">
{% for error in errors %}
{{ error.messageTemplate|trans(error.messageParameters, 'validators')~'. ' }}
{% endfor %}
</span>
{% endif %}
{% endblock field_errors %}
{% block form_errors %}
{% if errors|length > 0 %}
<ul class="val-error">
{% for error in errors %}
<li>{{ error.messageTemplate|trans(error.messageParameters, 'validators')~'. ' }}</li>
{% endfor %}
</ul>
{% endif %}
{% endblock form_errors %}
Since field_* is removed in 2.3 the approved solution will no longer work. A hacky solution I have found is
{% block form_errors %}
{% if errors|length > 0 %}
{% if form.parent is empty %}
<ul class="val-error">
{% for error in errors %}
<li>{{ error.messageTemplate|trans(error.messageParameters, 'validators')~'. ' }}</li>
{% endfor %}
</ul>
{% else %}
<span class="val-error">
{% for error in errors %}
{{ error.messageTemplate|trans(error.messageParameters, 'validators')~'. ' }}
{% endfor %}
</span>
{% endif %}
{% endif %}
{% endblock form_errors %}
So basically what this does is if there is no parent, it knows it is the top level.

Symfony2 presenting an array value as a translated text

it does not seem possible to use a value i am getting right from an array, as a translated text....so when i have
{% for key,value in ratings %}
<th scope="row">
{% trans %}
{{ value.type }}
{% endtrans %}</th>
<td ><div class="rating" id= "{{ value.type }}" data-rating="{{ value.ratingaverage }}"
thread="{{thread_id}}" rating_readonly= "{{ value.readOnly }}" route="{{ path('addrating') }}" ></div> </td>
{% endfor %}
i get the error
A message must be a simple text in TrackerMembersBundle::rating.html.twig at line 92
what is meant here, is the line with
{% trans %}
{{ value.type }}
{% endtrans %}
i cannot seem to be able to use trans upon the value coming directly from array? the value would be for example "file.quality"
Perhaps its better when you search here before.
Symfony2+Twig, variable in translation return "A message must be a simple text"
The mistake is the variable in the translation block. You have to set an placeholder and replace this with a value.
{% trans with {'%type%':value.type} %}
This is my %type%!
{% endtrans %}

Resources