Twig translate dynamic value/string from database - twig

Explanation:
I pull these values from my local database and try to display them on the front-end. The issue is, that I have 2 languages that I need to cater to.
Example:
{% if activeLocale == "si" %}
{{ record.estate_type_SI|raw }}
{% elseif activeLocale == "en" %}
{{ record.estate_type_EN|raw }}
{% endif %}
This works, but when I have multiple items it gets gruesome because I have to write everything down two times. What this does is that depending on the language a value from a different column in the database is pulled.
I am wondering if I can do something similar to this:
{{ record.estate_type_{{"SI"|trans}}|raw }}
I will gladly buy you a beer if you can help me out with this.
Cheers!
EDIT: Variables

Using attribute , you can access a property of an object in a dynamic way. Then you just have to use upper filter to match what you need.
{{ attribute(record, 'estate_type_'~ activeLocale|upper)|raw }}

Related

Jinja2 Get the first item in a sorted list

I'm currently using Jinja2 to display reviews (taken from a database) on my webpage, and I stumbled upon the sort() filter. So I wrote some code to sort the reviews by their lowest rating.
{% for reviews in reviews.all()|sort(attribute='rating', reverse=false) %}
{{ reviews.text }}
{{ reviews.rating }}
{% endfor %}
The code above works, but now I want to get the very first sorted items (reviews.text, reviews.rating) from the list. I tried using:
{{ reviews.text[0] }}
{{ reviews.rating[0] }}
But this only returns the first character. I also tried using the |first filter, but this didn't work either.
Sorry if this seems like a silly question - I'm still getting to grips with Jinja2 - but is there any way I can pick out the first sorted item from my list?
Okay, the solution was simple (bear with me): Jinja2 has a list of control structures, one of them being loop.first which can be used in this instance.
{% for reviews in reviews.all()|sort(attribute='rating', reverse=false) %}
{% if loop.first %}
{{ reviews.text }}
{{ reviews.rating }}
{% endif %}
{% endfor %}

How can I check the value of a dropdown menu in craft cms / twig?

I have a dropdown menu with 2 options
Ordered
Unordered
I want to check if the value is Unordered or Ordered
{% set viewModel = {
cards: content['cards'] ?? [],
cardListType: content.cardListType ?? ''
} %}
{{ viewModel.cardListType|json_encode() }}
Returns this to me
{"0":{"label":"Unordered","value":"unordered","selected":true}}
I want to check if the value of viewModel.cardListType is unordered and that it's selected.
I have tried
{% if viewModel.cardListType.value is unordered %}
<p>UNORDERED</p>
{% endif %}
and
{% if viewModel.cardListType.value:unordered %}
<p>UNORDERED</p>
{% endif %}
and several other variations of this.
I don't understand the documentation/ syntax for dropdowns in craft or twig.
Can someone please explain like I'm 5 how this works and how to check the value?
I am using Craft 3 if this changes the syntax
Thanks in advance

Dynamic variable in Twig, example?

I don't quite understand how the attribute function in Twig works. Can somebody help me with an example?
I have a field in a SQL that is named dynamic. I could be eg "field27", but I don't know the number, the number is saved in radio.id. I would like to do someting like this:
{% for radio in gruppeType.radios %}
<td><!-- value of "field" + radio.id--></td>
{% endfor %}
How can I use field + radio.id as the name of the twig-variable?
You can build the field name with a variable, then use it in the attribute function to access the data within the object/array. As example:
{% set fieldName = "field" ~ radio.id %}
{{ attribute(gruppeType, fieldName) }}
A working example can be seen in this twigfiddle
Hope this helps.

Twig Access Array Index?

Is it possible to directly access an array index from within a Twig template?
Here's my setup, using Silex:
return $app['twig']->render('template', array('numbers' => array('one', 'two', 'three')));
so can I do something like this?
{{numbers[0]}}
Just before posting this I realized, that's exactly what you can do, but as I didn't find the answer anywhere in the docs or google (correct me if I'm wrong), I've posted this anyway.
{{numbers[0]}}
The answer of Adam, is correct, only to make it clear and improve,
you can have access directly to array index
{{ myArray[0] }}
if you need to access in a loop
{% set arrayOfItems = ['ZERO', 'ONE'] %}
{% set myArray = ['APPLE', 'ORANGE'] %}
{% for oneItem in arrayOfItems %}
<p>{{ oneItem }} equals {{ myArray[loop.index0] }}</p>
{% endfor %}
in this example I used an array inside a non related loop so the result is:
ZERO equals APPLE
ONE equals ORANGE
Thats actually something what doesnt work for me when using Twig with shopware 6.
I try to access an object like
{{ page.cart.lineItems.elements[0].quantity }}
what will lead into a parsing error of the Twig Template
I can use
{{ page.cart.lineItems.elements | first }}
to get the first Element, but dont know how i can then access a property of this first element

How do you translate array items and join them?

Using twig, how can I translate all items in an array and join them with a slash?
Do I have to use an additional variable or is there a cleverer method?
For the moment, I'm doing something like this:
{% set labels = [] %}
{% for feature in menu_item.features %}
{% set labels = labels|merge([feature|trans([], 'features')]) %}
{% endfor %}
{{ labels | join(' / ')}}
It sucks.
Why not just output the content while you're looping ?
{% for feature in menu_item.features %}
{% if loop.index0 > 0 %}/{% endif %}
{{feature|trans}}
{% endfor %}
Maybe I'm late to the party, but you can now do this easily with the map filter:
{{ menu_item.features|map(feature => feature|trans)|join(' / ') }}
See documentation:
Twig >v1.41: https://twig.symfony.com/doc/1.x/filters/map.html
Twig >v2.10: https://twig.symfony.com/doc/2.x/filters/map.html
Twig v3.x: https://twig.symfony.com/doc/3.x/filters/map.html
Not everything should be done within the "view".
This type of code is probably much better placed within your controller logic and then passed into the view as the merged+joined result. Because in your example all you're doing is compiling a result which can much more easily be done within code.

Resources