Einstellungselement des Arrays von Twig

125

Wie kann ich ein Mitglied eines bereits vorhandenen Arrays von Twig festlegen?

Ich habe es als nächstes versucht:

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

aber ich habe folgenden Fehler erhalten:

Unerwartetes Token "Interpunktion" des Werts "[" ("Ende des Anweisungsblocks" erwartet) in ...

falinsky
quelle

Antworten:

210

In Twig gibt es keine gute Möglichkeit, dies zu tun. Es ist jedoch möglich, den Zusammenführungsfilter zu verwenden:

{% set arr = arr|merge({'element': 'value'}) %}
Paul
quelle
"." - Aussage ist die gleiche wie "[]", also ist es nicht die Lösung
falinsky
@ Falinsky Du hast recht. .und []sind in Twig sehr ähnlich und ich habe mich geirrt. Ich habe nachgeschlagen und meine Antwort bearbeitet.
Paul
17
Ich suchte nach einer Möglichkeit, den dynamischen Variablenschlüssel als Ersatz für zu definieren 'element'. Ich habe die Antwort von @ LivaX unten gefunden. So wäre es {% set arr = arr|merge({(key): 'value'}) %}.
Sithu
Das ist so dumm. Warum können mit twig keine Array-Werte festgelegt werden?
Matt Cavanagh
1
@MattCavanagh Da Ansichtsdateien (wie Twig) keine Geschäftslogik enthalten sollen, sollte dies letztendlich im Modell behandelt werden. Die Ansicht soll wirklich einfach rendern, was da ist. Das Problem in meinem Fall und warum ich Ihnen auch zustimme, ist, dass ich Zweigmakros erstelle, um UI-Objekte zu rendern, z. {{ UI.button({'type':'submit'}) }}und all diese Makros verwenden | merge zum Festlegen von Standardparametern, daher besteht eine logische Notwendigkeit dafür ...
Prof83
79

Ich bin auf dieses Problem gestoßen, habe aber versucht, ganzzahlige Indizes anstelle eines assoziativen Index wie 'element' zu erstellen.

Sie müssen Ihren Indexschlüssel auch mit ()dem Zusammenführungsfilter schützen :

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

Sie können jetzt benutzerdefinierte Indexschlüssel wie hinzufügen ('element'~loop.index0)

LivaX
quelle
Das ist die eigentliche Lösung, wenn Sie versuchen, Schlüssel dynamisch einzufügen, danke LivaX!
Nicoleolias
19

Wenn die Initialisierung nur Folgendes benötigt:

{% set items = { 'apple': 'fruit', 'orange': 'fruit', 'peugeot': 'unknown' } %}
Pleerock
quelle
8
Das war nicht die Frage.
Redreinard
2

Ich habe die Antwort von @LivaX ausprobiert, aber sie funktioniert nicht. Das Zusammenführen eines Arrays mit numerischen Schlüsseln funktioniert nicht ( https://github.com/twigphp/Twig/issues/789 ).

Das funktioniert nur, wenn Schlüssel Zeichenfolgen sind

Ich habe eine andere Tabelle ( temp) aus der Anfangstabelle ( t) neu erstellt und die Schlüssel zu einer Zeichenfolge gemacht, zum Beispiel:

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

t Tasten: 0, 1, 2 ..

temp Schlüssel: 0_, 1_, 2_ ....

Zizoujab
quelle
Gleiches Problem, bisher keine Lösung.
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'%}

Danke für diesen Thread - ich konnte auch ein Array mit (loop.index0) erstellen und an twig senden.

n8tron
quelle
1

Ich fand dieses Problem sehr ärgerlich, und meine Lösung ist vielleicht orthodox und entspricht nicht der Twig-Philosophie, aber ich habe Folgendes entwickelt:

$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);

das kann wie folgt verwendet werden:

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

savedario
quelle
1

Verwenden Sie dies einfach wie {% set arr={'key':'value'} %}(ohne Leerzeichen nach dem :), es funktioniert gut.

Aber wenn ich es in einer for-Schleife verwende, um es zu einem Array zu machen, funktioniert es nicht außerhalb des for-Bereichs.

{% 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
quelle
1
Wenn Sie die Variable außerhalb der for-Schleife verwenden möchten, müssen Sie sie außerhalb der for-Schleife definieren, siehe hier: twig.sensiolabs.org/doc/tags/set.html
user2019515
5
Das ist alles Mögliche falsch. Das Leerzeichen nach dem Doppelpunkt spielt keine Rolle. Sie erstellen neue Arrays und setzen kein Element in dem Array, das die Frage war. Sie können kein Array wie {{array}} ausgeben, das einen Fehler erzeugen würde. Diese Antwort ist voller Fehler und hat nichts mit der gestellten Frage zu tun.
Redreinard
3
Ich verstehe nicht, warum dies positive Stimmen hat, wie oben erwähnt, fast alles ist falsch in dieser "Antwort" ...
MariusJP
0

Ich hatte ein mehrdimensionales Array. Die einzige Lösung, die ich herausfinden konnte, besteht darin, ein neues temporäres Array zu erstellen und die Informationen zu aktualisieren / hinzuzufügen , die an eine andere Zweigfunktion weitergegeben wurden.

Shobekhan
quelle
0

Ich hatte dieses Problem vor einiger Zeit. Stellen Sie sich vor, Sie haben ein Array wie dieses:

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'
}

Sie möchten diese Daten also in zwei Zeilen anzeigen, aber das Kennwort aus dieser Liste entfernen. Zu diesem Zweck ist die Aufteilung in zwei Arrays mit dem sliceFilter einfach . Wir müssen jedoch das Passwort entfernen. Aus diesem Grund verwende ich dieses Snippet. Die Idee ist, alle Elemente kleiner als die dataElementgröße geteilt durch 2 zu setzen. Um dies zu berechnen, verwenden wir den Filter length. Nun erhalten wir den Index des aktuellen Elements, das wir verwenden loop.index. Und schließlich * verschieben wir ein assoziatives Element in das linke oder rechte Array. Ein assoziatives Array besteht aus zwei Komponenten keyund value. Um auf einen Array-Schlüssel in twit zu verweisen, operieren wir ()und verwenden den mergeFilter, um wie hier gezeigt in das Array zu pushen{% set left_list = left_list|merge({ (key): value }) %}

Dies ist die Komplettlösung.

{% 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
quelle
0

Sie können auch die folgende Syntax verwenden:

{% set myArray = myArray + myArray2 %}
GarryOne
quelle