Mengatur elemen array dari Twig

125

Bagaimana saya bisa mengatur anggota array yang sudah ada dari Twig?

Saya mencoba melakukannya dengan cara berikut:

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

tapi saya mendapat kesalahan berikut:

"Tanda baca" tak terduga dari nilai "[" ("akhir blok pernyataan" diharapkan) di ...

Falinsky
sumber

Jawaban:

210

Tidak ada cara yang baik untuk melakukan ini di Ranting. Namun demikian, dimungkinkan dengan menggunakan filter gabungan:

{% set arr = arr|merge({'element': 'value'}) %}
Paul
sumber
"." - pernyataan sama dengan "[]" jadi bukan solusinya
falinsky
@falinsky Anda benar. .dan []sangat mirip di Twig dan saya salah. Saya mencarinya dan mengedit jawaban saya.
Paul
17
Saya sedang mencari cara untuk mendefinisikan kunci variabel dinamis sebagai pengganti 'element'. Saya menemukan jawaban @ LivaX di bawah ini. Jadi itu akan terjadi {% set arr = arr|merge({(key): 'value'}) %}.
Sithu
Ini sangat konyol. Mengapa ranting tidak memungkinkan kemampuan untuk mengatur nilai array?
Matt Cavanagh
1
@MattCavanagh karena file tampilan (seperti Ranting) tidak seharusnya mengandung logika bisnis, ini pada akhirnya harus ditangani dalam model. Pandangan ini seharusnya hanya membuat apa yang ada di sana. Masalahnya dalam kasus saya, dan mengapa saya juga setuju dengan Anda, adalah bahwa saya membuat ranting makro untuk membuat objek UI, misalnya. {{ UI.button({'type':'submit'}) }}dan semua macro ini menggunakan | merge untuk mengatur params default, jadi ada kebutuhan logis untuk ini ...
Prof83
79

Saya mengalami masalah ini tetapi mencoba membuat indeks integer alih-alih indeks asosiatif seperti 'elemen'.

Anda perlu melindungi kunci indeks Anda dengan ()menggunakan filter gabungan juga:

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

Anda sekarang dapat menambahkan seperti kunci indeks kustom ('element'~loop.index0)

LivaX
sumber
Itulah solusi aktual ketika Anda mencoba memasukkan kunci secara dinamis, terima kasih LivaX!
nicolallias
19

Jika inisialisasi hanya perlu:

{% set items = { 'apple': 'fruit', 'orange': 'fruit', 'peugeot': 'unknown' } %}
pleerock
sumber
9
Ini bukan pertanyaannya.
redreinard
2

Saya telah mencoba jawaban @LivaX tetapi tidak berhasil, menggabungkan sebuah array di mana kunci numerik tidak berfungsi ( https://github.com/twigphp/Twig/issues/789 ).

Itu hanya akan berfungsi ketika kunci adalah string

Apa yang saya lakukan adalah membuat ulang tabel lain ( temp) dari tabel awal ( t) dan membuat kunci string, misalnya:

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

t kunci: 0, 1, 2 ..

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

zizoujab
sumber
Masalah yang sama, tidak ada solusi sejauh ini.
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'%}

Terima kasih atas utas ini - Saya juga dapat membuat array dengan (loop.index0) dan mengirim ke ranting.

n8tron
sumber
1

Saya menemukan masalah ini sangat menjengkelkan, dan solusi saya mungkin ortodoks dan tidak sejalan dengan filosofi Twig, tetapi saya mengembangkan yang berikut:

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

yang bisa digunakan sebagai berikut:

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

Savedario
sumber
1

Cukup gunakan ini seperti {% set arr={'key':'value'} %}(tanpa ruang kosong setelah :), itu berfungsi dengan baik.

Tetapi ketika saya menggunakannya di dalam for loop, untuk membuatnya menjadi array, itu tidak berfungsi di luar untuk lingkup.

{% 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
pengguna1321109
sumber
1
Jika Anda ingin menggunakan variabel di luar loop for Anda perlu mendefinisikannya di luar for loop, lihat di sini: twig.sensiolabs.org/doc/tags/set.html
user2019515
5
Ini semua salah. Ruang setelah usus besar tidak masalah. Anda membuat array baru, bukan mengatur elemen dalam array yang menjadi pertanyaan. Anda tidak dapat menampilkan array seperti {{array}}, yang akan menghasilkan kesalahan. Jawaban ini penuh dengan kegagalan dan tidak terkait dengan pertanyaan yang diajukan.
redreinard
3
Saya tidak mengerti mengapa ini memiliki upvotes, seperti yang dinyatakan di atas, hampir semuanya salah dalam "jawaban" ini ...
MariusJP
0

Saya memiliki array multi dimensi. Satu-satunya solusi yang bisa saya temukan adalah membuat array sementara baru dan memperbarui / menambahkan informasi, yang selanjutnya diteruskan ke fungsi ranting lain.

shobekhan
sumber
0

Saya punya masalah ini beberapa waktu yang lalu. Bayangkan Anda memiliki array seperti ini:

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

Jadi, Anda ingin menampilkan data ini dalam dua baris, tetapi hapus kata sandi dari daftar itu. Untuk tujuan ini, membagi dalam 2 array akan mudah dengan slicefilter. Namun, kami harus menghapus kata sandi. Karena alasan itu, saya menggunakan cuplikan ini. Idenya adalah untuk menempatkan semua elemen lebih kecil dari dataukuran elemen dibagi dengan 2. Untuk menghitung ini kita menggunakan filter length. Sekarang untuk mendapatkan indeks dari elemen kita pengguna saat ini loop.index. Dan akhirnya kita * mendorong elemen asosiatif di array kiri atau kanan. Array asosiatif memiliki dua komponen keydan value. Untuk referensi kunci array di twit kami operator ()dan kami menggunakan mergefilter untuk mendorong ke array seperti yang ditunjukkan di sini{% set left_list = left_list|merge({ (key): value }) %}

Ini adalah solusi lengkap.

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

Anda juga dapat menggunakan sintaks berikut:

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