Elemento di impostazione dell'array da Twig


125

Come posso impostare un membro di un array già esistente da Twig?

Ho provato a farlo nel modo seguente:

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

ma ho ricevuto il seguente errore:

Token inatteso "punteggiatura" del valore "[" ("fine blocco istruzioni" previsto) in ...

Risposte:


210

Non esiste un modo carino per farlo in Twig. Tuttavia, è possibile utilizzando il filtro unione:

{% set arr = arr|merge({'element': 'value'}) %}

"." - L'istruzione è la stessa di "[]" quindi non è la soluzione
falinsky

@falinsky Hai ragione. .e []sono molto simili in Twig e ho sbagliato. Ho cercato e modificato la mia risposta.
Paul,

17
Stavo cercando un modo per definire la chiave variabile dinamica in sostituzione di 'element'. Di seguito ho trovato la risposta di @LivaX. Quindi sarebbe {% set arr = arr|merge({(key): 'value'}) %}.
Sithu,

È così sciocco. Perché il ramoscello non consente di impostare valori di array?
Matt Cavanagh,

1
@MattCavanagh perché i file di visualizzazione (come Twig) non dovrebbero contenere la logica aziendale, questo dovrebbe essere gestito nel modello. La vista dovrebbe davvero rendere semplicemente ciò che è lì. Il problema però nel mio caso, e perché sono anche d'accordo con te, è che creo macro ramoscello per rendere gli oggetti dell'interfaccia utente, ad es. {{ UI.button({'type':'submit'}) }}e tutte queste macro usano | merge per impostare i parametri predefiniti, quindi c'è una logica necessità per questo ...
Prof83

79

Ho riscontrato questo problema ma stavo cercando di creare indici interi anziché indici associativi come 'element'.

Devi proteggere la tua chiave di indice anche ()usando il filtro di unione:

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

Ora puoi aggiungere una chiave di indice personalizzata come ('element'~loop.index0)


Questa è la vera soluzione quando si tenta di inserire le chiavi in ​​modo dinamico, grazie a LivaX!
nicolallias,

19

Se l'inizializzazione richiede solo:

{% set items = { 'apple': 'fruit', 'orange': 'fruit', 'peugeot': 'unknown' } %}

9
Questa non era la domanda.
Redreinard dal

2

Ho provato la risposta di @LivaX ma non funziona, unendo un array in cui le chiavi sono numeriche non funzionerà ( https://github.com/twigphp/Twig/issues/789 ).

Funzionerà solo quando le chiavi sono stringhe

Quello che ho fatto è ricreare un'altra tabella ( temp) dalla tabella iniziale ( t) e rendere le chiavi una stringa, ad esempio:

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

t tasti: 0, 1, 2 ..

temp chiavi: 0_, 1_, 2_ ....


Stesso problema, nessuna soluzione finora.
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'%}

Grazie per questo thread - Sono stato anche in grado di creare un array con (loop.index0) e inviarlo a ramoscello.


1

Ho trovato questo problema molto fastidioso e la mia soluzione è forse ortodossa e non in linea con la filosofia di Twig, ma ho sviluppato quanto segue:

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

che può essere utilizzato come segue:

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


1

Basta usare questo tipo {% set arr={'key':'value'} %}(senza spazio dopo il :), funziona bene.

Ma quando lo uso all'interno di un ciclo for, per renderlo un array, non funziona al di fuori dell'ambito 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

1
Se si desidera utilizzare la variabile al di fuori del ciclo for, è necessario definirla al di fuori del ciclo for, vedere qui: twig.sensiolabs.org/doc/tags/set.html
user2019515

5
Questo è tutto sbagliato. Lo spazio dopo i due punti non ha importanza. Stai creando nuovi array, non impostando un elemento nell'array che era la domanda. Non è possibile generare un array come {{array}}, che genererebbe un errore. Questa risposta è piena di fallimenti e non correlata alla domanda posta.
Redreinard dal

3
Non capisco perché questo abbia voti positivi, come detto sopra, quasi tutto è errato in questa "risposta" ...
MariusJP

0

Avevo un array multidimensionale. L'unica soluzione che ho potuto scoprire è creare un nuovo array temporaneo e aggiornare / aggiungere le informazioni, che sono state ulteriormente trasferite a un'altra funzione ramoscello.


0

Ho avuto questo problema qualche tempo fa. Immagina di avere un array come questo:

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

Quindi, vuoi mostrare questi dati in due righe, ma rimuovi la password da quell'elenco. A tal fine, dividere in 2 matrici sarà facile con il slicefiltro. Tuttavia, dobbiamo rimuovere la password. Per questo motivo, sto usando questo frammento. L'idea è di mettere tutti gli elementi in meno della datadimensione degli elementi divisa per 2. Per calcolare questo, usiamo il filtro length. Ora per ottenere l'indice dell'elemento corrente che utilizziamo loop.index. E infine * spingiamo un elemento associativo nella matrice sinistra o destra. Un array associativo ha due componenti keye value. Per fare riferimento a una chiave di array in twit, utilizziamo l'operatore ()e utilizziamo il mergefiltro per inserire l'array come mostrato qui{% set left_list = left_list|merge({ (key): value }) %}

Questa è la soluzione completa

{% 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 %}

0

È inoltre possibile utilizzare la sintassi seguente:

{% set myArray = myArray + myArray2 %}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.