Twig - Use variable key for object - php

I am using Twig and I have a problem.
I have a problem when I want to use a variable index for an object.
Here is my code:
{% for label, field in params.fields %}
{{ dump(data.field) }}
{% endfor %}
data is an object containing {'email': 'test#test.fr', 'name': 'John'}.
Field is an array of string containing ['email', 'name']
I can't show the value my object dynamically.
{{ dump(data.email) }} works.
How can I use dynamic indexes?

In Twig syntax, data.field is equal to $data['field'] in PHP. In other words, Twig use field as the array key name instead of taking the value of the field variable and use it as a key name.
If you want something similar to $data[$field], you can use the attribute() function:
The attribute function can be used to access a "dynamic" attribute of a variable:
Example:
{{ dump(attribute(data, field)) }}
{# or simply #}
{{ attribute(data, field) }}

Related

Twig - getting text filed key and value

I hav text filed where I stored some json data.
I am getting in my twig template on dump like:
"{"birthDate":"2021-09-01", "amount":8}"
I want to access keys so I can extract it's values.
Tried with json_encode or:
{% for key, value in item.value %}
but nothing seems to work.
Is the problem with the output data?
It seems that your item is neither object nor array it seems to be a string.
Try to convert your data to object or array json as below:
$objJson = json_decode($yourDBArray['menu']);
$arrJson = json_decode($yourDBArray['menu'],true);
Then you can use to show as below
{% for key,value in menu %}
Key : {{ key }}
Value : {{ value }}
{% endfor %}

How to iterate over many properties in Twig loop?

I have a problem with properties in (probably) Twig. I have controller in Symfony where getCategories(), getWords(), getTranslations() methods (from Doctrine) return the objects (relations). Every property in the controller is an array because I call findAll() method (from Doctrine again) which returns the array. Finally I return all the properties from controller to view (Twig file) where I try display the results by Twig for loop.
The problem is the Twig loop only iterates over flashcards property (I know why ;)) and I have no idea how to make many-properties iterating. I'd like the loop to iterate over all properties returned by the controller.
In the controller foreach loop I tried update the flashcards array with new associative keys such as: category, word and translation so that all the results returned by Doctrine (including relations) are stored in one flashcards property but then Symfony throws exceptions.
I wondered if create one array in the controller to which I would push the flashcards, cateogry, word and translation arrays and then return this one array to the view but I don't think this is good practice.
Here's the controller method code:
public function showAllCards()
{
$flashcards = $this->getDoctrine()->getRepository(Flashcards::class)
->findAll();
foreach ($flashcards as $flashcard) {
$category = $flashcard->getCategories()->getName();
$word = $flashcard->getWords()->getWord();
$translation = $flashcard->getTranslations()->getWord();
}
return $this->render('try_me/index.html.twig', [
'flashcards' => $flashcards,
'category' => $category,
'word' => $word,
'translation' => $translation
]);
}
Here's the Twig loop code:
{% for flashcard in flashcards %}
{{ word }}
<br>
{{ flashcard.pronunciation }}
<br>
{{ flashcard.exampleSentence }}
<br>
{{ category }}
<br>
{{ translation }}
<br>
{% endfor %}
I tried to execute the following controller code...
public function showMeAll()
{
$flashcards = $this->getDoctrine()->getRepository(Flashcards::class)
->findAll();
foreach ($flashcards as $flashcard) {
$flashcards['categories'] = $flashcard->getCategories()->getName();
$flashcards['words'] = $flashcard->getWords()->getWord();
$flashcards['translations'] = $flashcard->getTranslations()->getWord();
}
return $this->render('try_me/index.html.twig', [
'flashcards' => $flashcards,
]);
}
...with the following Twig loop...
{% for flashcard in flashcards %}
{{ flashcard.words }}
<br>
{{ flashcard.pronunciation }}
<br>
{{ flashcard.exampleSentence }}
<br>
{{ flashcard.categories }}
<br>
{{ flashcard.translations }}
<br>
{% endfor %}
...but then Symfony says:
An exception has been thrown during the rendering of a template ("Catchable Fatal Error: Object of class Proxies__CG__\App\Entity\Words could not be converted to string").
Could you give me some tips how to solve this problem, please? I'd like the Twig loop to iterates over many properties (flashcard, word, category, translation). Or write if there's a better solution, please.
Thank you in advance for every answer!
According to your snippets, I'm guessing you want something like the following:
{% for flashcard in flashcards %}
{% for word in flashcard.getWords() %}
{{ word }}<br />
{% endfor %}
{{ flashcard.getPronunciation() }}<br>
{{ flashcard.getExampleSentence() }}<br>
{% for category in flashcard.getCategories()() %}
{{ category.getName() }}<br />
{% endfor %}
{% for translation in flashcard.getTranslations() %}
{{ translation.getWord() }}<br />
{% endfor %}
{% endfor %}
Have a look at this section of the documentation. Basically if you had foo.bar, twig will test if bar is a public property of foo and if not test if there is a public getter, getBar, to fetch bar.
Some sidenotes in both of your loops, the values category, word and translation will only hold the last value of your flashcards, because you are overwriting the value each time.

Concatenation with dynamic variables for Twig symfony

I have a specific problem with concat of twig.
When I trying to concatenate dynamic variables showing the error.
Here is my code :
{% set i = 0 %}
{% set nbLignes = codeEvt.nb_lignes_~i %}
{% set nbLignesRef = codeEvt.nb_lignes_ref_~i %}
But I have this error message :
Method "nb_lignes_" for object "\DTO\SuiviJourFonc" does not exist in XXXXXXXXX.html.twig at line 211
I would like to take codeEvt.nb_lignes_0 , but i would like build a "for" for others variables like nb_lignes_1, nb_lignes_2 , nb_lignes_3 ...
How can i do this ?
attribute can be used to access a dynamic attribute of a variable:
The attribute function was added in Twig 1.2.
{{ attribute(object, method) }}
{{ attribute(object, method,arguments) }}
{{ attribute(array, item) }}
Try like this,
{{ attribute(codeEvt, 'nb_lignes_ref_' ~ i) }}
You can try the array-like notation:
{{ codeEvt['nb_lignes_ref_' ~ i] }}
Or even use string interpolation:
{{ codeEvt["nb_lignes_ref_#{i}"] }}

Symfony2 Array to string conversion, set empty value

I`am rendering a twig template in symfony2 and its possible to get a variable with value of array type but i am trying to preview the variable and this error pops:
Array to string conversion ...
So my qustion is not how to print out the array, but is it possible in twig to disable this error, so when an array comes and it cannot be outputed, to set an empty value.
In config.yml, under twig i have set
strict_variables: false
But this dose not include printing arrays.
EDIT:
In controller I pass this array to twig, for example:
'data' => array(
'description' => array(
'desc1',
'desc2'
)
);
In twig I am trying to print {{ data['description'] }} and I got the following error:
Array to string conversion ...
This is the normal error that must pop, but I need if I try to print this a no error to pop but instead I need to print nothing(empty value), same way like trying to print an non existing variable with twig set with
strict_variables: false
ANSWER:
Make a custom function:
public function getFunctions()
{
return array(
'to_string' => new \Twig_Function_Method($this, 'toString')
);
}
public function toString($data) {
if(is_array($data)) {
return '';
}
return $data;
}
And in twig template:
{{ to_string(data['description']) }}
You have two desc: desc1 and desc2, what do you want to print? If both you have to use this notation (for instance)
{{ data['description'][desc1] }} - {{ data['description'][desc2] }}
More in general:
{% for desc in data['description'] %}
{{ desc }}
{% endfor %}
EDIT
Ok, now I got it (from your comment):
{% if data['description'] is iterable %}
//echo here an empty string
{% else %}
{{ data['description'] }}
{% endif %}

How to call variable (Object)'s method in expression syntax? [Twig Templating]

How to call a variable's method in expression syntax in twig tempting system.
see the example below
{{ myObj.someMethod() }} {# this print the output of this method #}
i don't want above code because its printing output of this method.
but i want this
{% myObj.someMethod() %}
but its is giving me error that
Unknown tag name "myObj" in "
{% myObj.someMethod() %}" at line 2
even with above error method is also being called.
In twig syntax {{ some variable}} will print the result in variable you need to set variable and then use where you want
{% set myvar = myObj.someMethod() %} /* this will store the result returned from function */
{{ myvar }} /* this will print the result in myvar */

Categories