I got a variable from a controller in the form of an array (variable ads), on twig, I used:
{% for ad in ads%}
<tr> <td> {{ad.xxx}}
{% if app.user and app.user == ad.author%}
{{ad.yyyy}}
{% endif%}
</td> </tr>
{$ endfor%}
there is no problem, it's classic.
I want to use for example
{% if app.user and app.user == ad.author%}
just before the for loop, to hide a balise for logged in users but it’s not their announcement
If userAds is a collection from ads from one and the same author, you could go with the following snippet(s):
{{ attribute(userAds|first, 'author') }}
{{ (userAds|first).author}}
{{ (userAds|first)['author'] }}
{% if app.user and (userAds|first).author == app.user %}
<th>Action</th>
{% endif %}
Related
I am trying to access a variable of a object in jinja2 using this code:
{% for row in rows.items %}
<tr>
{% for column in model_settings['table_columns'] %}
<td>
<p>{{ row.column }}</p>
</td>
{% endfor %}
</tr>
{% endfor %}
what I want is if column was username I would want it to give me
row.username. sorry for the bad explanation.
Jinja2 has the builtin attr filter to access an attribute of an object. The name of the attribute can be a static string, or in your case: a string stored in a variable:
{% for row in rows.items %}
<tr>
{% for column in model_settings['table_columns'] %}
<td>
<p>{{ row|attr(column) }}</p>
</td>
{% endfor %}
</tr>
{% endfor %}
I have a question about shopware 6.
I have created an extra table for my property_group options, called property_group_extension.
So I have extended this table in my theme:
class PropertyGroupExtension extends EntityExtension
{
public function extendFields(FieldCollection $collection): void
{
$collection->add(
new OneToOneAssociationField('property_group_extension', 'id', 'property_group_id', PropertyGroupExtensionDefinition::class, true)
);
}
public function getDefinitionClass(): string
{
return PropertyGroupDefinition::class;
}
}
But how can I call this extra db-table property_group_extension (with a column test) in my twig template?
This is NOT working:
properties.html.twig:
{% for group in page.product.sortedProperties %}
{% block page_product_detail_properties_table_row %}
<tr class="properties-row">
{% block page_product_detail_properties_item_label %}
<th class="properties-label">
{{ group.test }} - {# <= HOW CAN I INSERT HERE MY TEST COLUMN??? #}
{{ group.translated.name|e }}:
</th>
{% endblock %}
{% block page_product_detail_properties_item_value %}
<td class="properties-value">
{% apply spaceless %}
{% for option in group.options %}
{% set i = ( i | default(0) ) + 1 %}
<span>{% if i > 1 %}, {% endif %}{{ option.translated.name|e }}</span>
{% endfor %}
{% endapply %}
</td>
{% endblock %}
</tr>
{% endblock %}
{% endfor %}
I believe, the data does not automatically populate to the data structures in the twig by adding an extension.
You usually would hook into an even that is triggered for the page you want to access the data in.
Next you add an extension to the result so it is accessible in the twig template.
i have a lot of sub entities, so i want to add/update them reusing one controller, view.
So i need before every form print out list of sub entities already created.
Sub entity name is variable
{% form_theme form 'bootstrap_4_horizontal_layout.html.twig' %}
<table class="table">
{% for entity in parentEntity.{{ subEntityName }} %}
<tr>
<td>{{ entity }}</td>
</tr>
{% endfor %}
</table>
{{ form_start(form) }}
{{ form_widget(form) }}
{{ form_end(form) }}
But this is not working, also
~ subEntityName ~
Not works
Cant find any suggestion. Is possible to use variables in twig loop definition
Found solution
{% set entities = attribute(parentEntity, entityName) %}
{% for entity in entities %}
<tr>
<td>{{ entity }}</td>
</tr>
{% endfor %}
And this works for me like a charm!
Instead of creating a new variable entities, you can also simply do:
{% for entity in attribute(parentEntity, entityName) %}
And instead of using the attribute function, you can use the bracket notation, at least if parentEntity is an array:
{% for entity in parentEntity[entityName] %}
I'm (finally) switching my site from Drupal7 to Symfony3.
I'm working on migrating my layout to .twig.
I've got a question about loops and key-value arrays.
I've configured a k/v array
{% set test = {
sec1: {
title: "title 1",
content: "content 1"
},
sec2: {
title: "title 2",
content: "content 2"
},
}
%}
I can reference any specific array element in other markup. E.g., this works as intended
<ul>
<li>
<h1>{{ test.sec1.title }}</h1>
<div>
<p>{{ test.sec1.content }}</p>
</div>
</li>
</ul>
Now I want to loop/repeat the block over a count of n. But trying this,
<ul>
{% for i in 1..5 %}
<li>
<h1>{{ test.sec{{ i }}.title }}</h1>
<div>
<p>{{ test.sec{{ i }}.content }}</p>
</div>
</li>
{% endfor %}
</ul>
fires an error
Unexpected token "punctuation" of value "{" ("end of print statement" expected) in default/index.html.twig at line 67.
500 Internal Server Error - Twig_Error_Syntax
I've been working with variations of these
http://twig.sensiolabs.org/doc/tags/for.html#iterating-over-keys
but can't get anything to work yet.
What's the right way to loop this list over the secN's in the key-value array?
The reason why your script does not work is that you cannot compose an object-property accessor like this.
What you probably need is iterating over a subset:
{% for sec in test|slice(0, 5) %}
{{ sec.title }}
{% endfor %}
Or, if you do indeed need access to the key: iteration over key and value:
{% for key, sec in test %}
{{ sec.title }}
{{key}}
{% endfor %}
If you need to slice while still accessing the key, you could combine the latter with a check to the loop variables:
{% for key, sec in test %}
{% if loop.index0 < 5 %}
{{ sec.title }}
{{key}}
{% endif %}
{% endfor %}
{% for key, item in content.field_invoice_no if key|first != '#' %}
<tr>
<td>{{ item }}</td>
<td> {{ content.field_invoice_date[key] }} </td>
</tr>
{% endfor %}
Iterating over key-value arrays in Twig
for reference entity code below
{% for key, item1 in node.field_quotation.entity.field_product %}
<tr>
<td>{{ loop.index }}</td>
<td>{{ item1.entity.body.value |raw }}</td>
<td> {{ item1.entity.field_product_unit_required.value }}</td>
<td>{{ item1.entity.field_hsn_code.value }}</td>
<td>{{item1.entity.field_pro.number|number_format(2, '.', ',')}}</td>
{% endfor %}
</tr>
I'm trying to custom the add/delete feature of a collection with the data-prototype attr.
To do so, I use some twig macro:
view called by the controller
{# the principal view .html.twig #}
{% from"AppBundle:Macros:tabRangeVal.html.twig" import tableau %}
[...]
{{ tableau('InstrumentSharedUtils/File',form.documentations) }}
{{ tableau('SpecificationsSheet/SpecificationSheet',form.list) }}
[...]
macro for tableau
{# /src/AppBundle/Resources/views/Macros/tabRangeVal.html.twig #}
{% macro tableau(classe, arrayVar) %}
{% from "AppBundle:Form:"~ classe ~ ".html.twig" import val %}
{% from "AppBundle:Form:"~ classe ~ ".html.twig" import label %}
{% from "AppBundle:Macros:dataProto.html.twig" import proDataType %}
<div class="well well-sm">
<h5> {{ form_label(arrayVar) }}</h5>
<table class="table">
<thead>
<tr>
<th><button class="btn btn-default btn-add-row" type="button" id="{{ "add_#{arrayVar.vars.id}" }}"><span class="glyphicon glyphicon-plus"></span></button></th>
{{ label() }}
</tr>
</thead>
<tbody id="{{ "container_#{arrayVar.vars.id}" }}" data-prototype="{{ proDataType(classe, arrayVar.vars.prototype)|e }}">
{% for i in arrayVar %}
<tr >
<td><button class="btn btn-default btn-delete-row"><span class="glyphicon glyphicon-minus"></span></button></td>
{{ val(i) }}
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endmacro %}
macro for the data-prototype field
{# /src/AppBundle/Resources/views/Macros/dataProto.html.twig #}
{% macro proDataType(classe, value) %}
{% from "AppBundle:Form:"~ classe ~ ".html.twig" import val %}
<tr>
{% for v in value %}
<td><button class="btn btn-default btn-delete-row"><span class="glyphicon glyphicon-minus"></span></button></td>
{{ val(v) }}
{% endfor %}
</tr>
{% endmacro %}
an exemple of the AppBundle:Form:"~ classe ~ ".html.twig
{# /src/AppBundle/Resources/views/Form/InstrumentSharedUtils/File.html.twig #}
{% macro val(var) %}
<td>{{ form_widget(var.name, { 'attr': { 'class':'form-control' } }) }}</td>
<td>{{ form_widget(var.path, { 'attr': { 'class':'form-control' } }) }}</td>
<td>{{ form_widget(var.isExtra) }}</td>
{% endmacro %}
{% macro label() %}
<th>Name</th>
<th>Path</th>
<th>Is Extra</th>
{% endmacro %}
The problem is that I get the error
Method "name" for object "Symfony\Component\Form\FormView" does not exist in AppBundle:Form:InstrumentSharedUtils/File.html.twig at line 2
The thing that really bothers me is that I can access to the name (and even the others prototype.vars.children) if I dont use macro
by exemple, the following code works:
{# principal view .html.twig #}
{% for i in form.documentations.vars.prototype %}
{{ form_widget(i) }}
{% endfor %}
and i feel like its the exact same as above, with
form.documentations => arrayVar,
arrayVar.vars.prototype => value, and
{% for i in value %}
{{ form_widget(i.name) }}
{{ form_widget(i.path) }}
{{ form_widget(i.isExtra) }}
{% endfor %}
the output should be the same ...
could you help me to find what is wrong in there?
Ok, I will probably flog myself to be so stupid, but by writing it down, I realised (in the last code section) that I made a mistake:
the i in value at the end is already either name or path or isExtra...
so when I try to access to form.documentations.vars.prototype.name.name its logic that I get a beautifull exception...
so the solution was to modify the dataproto macro
{% macro proDataType(classe, value) %}
<tr class='block-to-remove'>
<td><button class='btn btn-default btn-delete-row'><span class='glyphicon glyphicon-minus'></span></button></td>
{% for truc in value %}
<td>{{ form_widget(truc, { 'attr': { 'class':'form-control' } }) }}</td>
{% endfor %}
</tr>
{% endmacro %}
and to send a arrayVar.vars.prototype to it