Élément de réglage du tableau de Twig

126

Comment puis-je définir un membre d'un tableau déjà existant depuis Twig?

J'ai essayé de le faire de la manière suivante:

{% set arr['element'] = 'value' %}

mais j'ai eu l'erreur suivante:

Jeton "ponctuation" inattendu de la valeur "[" ("fin du bloc d'instructions" attendu) dans ...

Falinsky
la source

Réponses:

211

Il n'y a pas de bonne façon de faire cela dans Twig. Il est cependant possible en utilisant le filtre de fusion:

{% set arr = arr|merge({'element': 'value'}) %}
Paul
la source
"." - la déclaration est la même que "[]" donc ce n'est pas la solution
falinsky
@falinsky Vous avez raison. .et []sont très similaires dans Twig et je me suis trompé. J'ai recherché et modifié ma réponse.
Paul
17
Je cherchais un moyen de définir une clé variable dynamique en remplacement de 'element'. J'ai trouvé la réponse de @ LivaX ci-dessous. Donc, ce serait {% set arr = arr|merge({(key): 'value'}) %}.
Sithu
C'est tellement idiot. Pourquoi twig ne permet-il pas de définir des valeurs de tableau?
Matt Cavanagh
1
@MattCavanagh parce que les fichiers de vue (tels que Twig) ne sont pas censés contenir une logique métier, cela devrait finalement être géré dans le modèle. La vue est vraiment censée rendre simplement ce qui est là. Le problème dans mon cas, et pourquoi je suis également d'accord avec vous, est que je crée des macros de brindilles pour rendre les objets de l'interface utilisateur, par exemple. {{ UI.button({'type':'submit'}) }}et toutes ces macros utilisent | merge pour définir les paramètres par défaut, il y a donc un besoin logique pour cela ...
Prof83
80

J'ai rencontré ce problème mais j'essayais de créer des index entiers au lieu d'index associatif comme «élément».

Vous devez également protéger votre clé d'index en ()utilisant le filtre de fusion:

{% set arr = arr|merge({ (loop.index0): 'value'}) %} 

Vous pouvez maintenant ajouter une clé d'index personnalisée comme ('element'~loop.index0)

LivaX
la source
C'est la vraie solution lorsque vous essayez d'insérer des clés de manière dynamique, merci LivaX!
nicolallias
18

Si l'initialisation nécessite uniquement:

{% set items = { 'apple': 'fruit', 'orange': 'fruit', 'peugeot': 'unknown' } %}
pleerock
la source
9
Ce n'était pas la question.
redreinard
2

J'ai essayé la réponse de @LivaX mais cela ne fonctionne pas, fusionner un tableau où les clés sont numériques ne fonctionnera pas ( https://github.com/twigphp/Twig/issues/789 ).

Cela ne fonctionnera que lorsque les clés sont des chaînes

Ce que j'ai fait, c'est recréer une autre table ( temp) à partir de la table initiale ( t) et faire des clés une chaîne, par exemple:

{% for key , value in t%}
{% set temp= temp|merge({(key~'_'):value}) %}
{% endfor %}

t touches: 0, 1, 2 ..

temp clés: 0_, 1_, 2_ ....

zizoujab
la source
Même problème, pas de solution pour l'instant.
TyrionGraphiste
2
{% set links = {} %}

{# Use our array to wrap up our links. #}
{% for item in items %}
  {% set links = links|merge({ (loop.index0) : {'url': item.content['#url'].getUri(), 'text': item.content['#title']} }) %}
{% endfor %}

{%
set linkList = {
  'title': label,
  'links': links
}
%}

{% include '<to twig file>/link-list.twig'%}

Merci pour ce fil - j'ai également pu créer un tableau avec (loop.index0) et l'envoyer à twig.

n8tron
la source
1

J'ai trouvé ce problème très ennuyeux, et ma solution est peut-être orthodoxe et non conforme à la philosophie Twig, mais j'ai développé ce qui suit:

$function = new Twig_Function('set_element', function ($data, $key, $value) {
    // Assign value to $data[$key]
    if (!is_array($data)) {
        return $data;
    }
    $data[$key] = $value;
    return $data;
});
$twig->addFunction($function);

qui peut être utilisé comme suit:

{% set arr = set_element (arr, 'element', 'value')%}

sauvéario
la source
1

Utilisez simplement ceci comme {% set arr={'key':'value'} %}(sans espace après le :), cela fonctionne bien.

Mais quand je l'utilise dans une boucle for, pour en faire un tableau, cela ne fonctionne pas en dehors de la portée for.

{% for group in user.groups %}
  {% set foo={'loop.index0':'group.id'} %}
  {% set title={'loop.index0':'group.title'} %}
  {{ title }} //it work 
{% else %}
  {% set foo={'0':'-1'} %}
  {% set title={'0':'未分组'} %}
{% endfor %}
{{ title }}  //it does not work, saying title is not defined
user1321109
la source
1
Si vous souhaitez utiliser la variable en dehors de la boucle for, vous devez la définir en dehors de la boucle for, voir ici: twig.sensiolabs.org/doc/tags/set.html
user2019515
5
Ce sont toutes sortes de mal. L'espace après le côlon n'a pas d'importance. Vous créez de nouveaux tableaux, vous ne définissez pas un élément du tableau qui était la question. Vous ne pouvez pas sortir un tableau comme {{array}}, qui générerait une erreur. Cette réponse est pleine d'échecs et sans rapport avec la question posée.
redreinard
3
Je ne comprends pas pourquoi cela a des votes positifs, comme indiqué ci-dessus, presque tout est incorrect dans cette "réponse" ...
MariusJP
0

J'avais un tableau multidimensionnel. La seule solution que j'ai pu trouver est de créer un nouveau tableau temporaire et de mettre à jour / ajouter les informations, qui ont ensuite été transmises à une autre fonction de brindille.

Shobekhan
la source
0

J'ai eu ce problème il y a quelque temps. Imaginez que vous ayez un tableau comme celui-ci:

data = {
    'user': 'admin',
    'password': 'admin1234',
    'role': 'admin',
    'group': 'root',
    'profile': 'admin',
    'control': 'all',
    'level': 1,
    'session': '#DFSFASADASD02',
    'pre_oa': 'PRE-OA',
    'hepa_oa': 'HEPA-OA',
    'pre_ra': 'HEPA-RA',
    'hepa_ra': 'HEPA-RA',
    'deodor_ra': 'DEODOR-RA'
}

Donc, vous voulez afficher ces données sur deux lignes, mais supprimez le mot de passe de cette liste. À cette fin, diviser en 2 tableaux sera facile avec le slicefiltre. Cependant, nous devons supprimer le mot de passe. Pour cette raison, j'utilise cet extrait. L'idée est de mettre tous les éléments inférieurs à la datataille des éléments divisée par 2. Pour calculer cela, nous utilisons le filtre length. Maintenant, pour obtenir l'index de l'élément courant que nous utilisons loop.index. Et enfin nous * poussons un élément associatif dans le tableau de gauche ou de droite. Un tableau associatif a deux composants keyet value. Pour référencer une clé de tableau dans twit, nous opérateur ()et nous utilisons le mergefiltre pour pousser dans le tableau comme indiqué ici{% set left_list = left_list|merge({ (key): value }) %}

C'est la solution complète.

{% set left_list = {} %}
{% set right_list = {} %}
{% set limit = data|length // 2 %}
{% for key, value in data|cast_to_array %}
{% if key != 'password' %}
{% if loop.index <= limit %}
{% set left_list = left_list|merge({ (key): value }) %}
{% else %}
{% set right_list = right_list|merge({ (key): value }) %}
{% endif %}
{% endif %}
{% endfor %}
{% for key, value in left_list %}
<p>
<label for="{{key}}">{{key}}</label>
<input type="text" name="{{key}}" id="{{key}}" value="{{value}}"
       class="text ui-widget-content ui-corner-all">
</p>
{% endfor %}
Teocci
la source
0

Vous pouvez également utiliser la syntaxe suivante:

{% set myArray = myArray + myArray2 %}
GarryOne
la source