Ustawienie elementu tablicy z Twig

126

Jak mogę ustawić składową już istniejącej tablicy z Twig?

Spróbowałem zrobić to w inny sposób:

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

ale otrzymałem następujący błąd:

Nieoczekiwany token „interpunkcja” wartości „[” (oczekiwano „końca bloku instrukcji”) w ...

falinsky
źródło

Odpowiedzi:

211

W Twig nie ma fajnego sposobu na zrobienie tego. Jest to jednak możliwe dzięki zastosowaniu filtru scalającego:

{% set arr = arr|merge({'element': 'value'}) %}
Paweł
źródło
„.” - stwierdzenie jest tym samym, co „[]”, więc nie jest to rozwiązanie
falinsky,
@falinsky Masz rację. .i []są bardzo podobne w Twig i myliłem się. Sprawdziłem to i zredagowałem odpowiedź.
Paul
17
Szukałem sposobu na zdefiniowanie dynamicznego klucza zmiennej w miejsce 'element'. Znalazłem odpowiedź @ LivaX poniżej. Tak więc byłoby {% set arr = arr|merge({(key): 'value'}) %}.
Sithu
To takie głupie. Dlaczego twig nie pozwala na ustawienie wartości tablic?
Matt Cavanagh
1
@MattCavanagh, ponieważ pliki widoków (takie jak Twig) nie powinny zawierać logiki biznesowej, ostatecznie powinno to być obsługiwane w modelu. Widok ma po prostu renderować to, co tam jest. Problem jednak w moim przypadku i dlaczego też się z tobą zgadzam, polega na tym, że tworzę makra twig do renderowania obiektów UI, np. {{ UI.button({'type':'submit'}) }}i wszystkie te makra używają | merge do ustawiania domyślnych parametrów, więc istnieje logiczna potrzeba ...
Prof83
80

Napotkałem ten problem, ale próbowałem utworzyć indeksy całkowite zamiast indeksu asocjacyjnego, takiego jak „element”.

Musisz również chronić swój klucz indeksu za ()pomocą filtru scalającego:

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

Możesz teraz dodać niestandardowy klucz indeksu, taki jak ('element'~loop.index0)

LivaX
źródło
To jest rzeczywiste rozwiązanie, gdy próbujesz wstawiać klucze dynamicznie, dzięki LivaX!
nicolallias
19

Jeśli potrzebujesz tylko inicjalizacji:

{% set items = { 'apple': 'fruit', 'orange': 'fruit', 'peugeot': 'unknown' } %}
pleerock
źródło
9
To nie było pytanie.
redreinard
2

Próbowałem odpowiedzi @LivaX, ale nie działa, łączenie tablicy, w której klucze są numeryczne, nie zadziała ( https://github.com/twigphp/Twig/issues/789 ).

To zadziała tylko wtedy, gdy klucze są łańcuchami

To, co zrobiłem, to odtworzenie innej tabeli ( temp) z początkowej tabeli ( t) i uczynienie kluczy ciągiem, na przykład:

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

t klawisze: 0, 1, 2 ..

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

zizoujab
źródło
Ten sam problem, na razie brak rozwiązania.
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'%}

Dzięki za ten wątek - udało mi się również stworzyć tablicę z (loop.index0) i wysłać do twig.

n8tron
źródło
1

Uważam, że ten problem jest bardzo irytujący, a moje rozwiązanie jest być może ortodoksyjne i nie jest zgodne z filozofią Twig, ale opracowałem następujące elementy:

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

które można wykorzystać w następujący sposób:

{% set arr = set_element (arr, 'element', 'wartość')%}

saveario
źródło
1

Po prostu użyj tego w ten sposób {% set arr={'key':'value'} %}(bez spacji po :), działa dobrze.

Ale kiedy używam go wewnątrz pętli for, aby uczynić go tablicą, nie działa poza zakresem 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
źródło
1
Jeśli chcesz użyć zmiennej poza pętlą for, musisz zdefiniować ją poza pętlą for, zobacz tutaj: twig.sensiolabs.org/doc/tags/set.html
user2019515
5
To wszelkiego rodzaju zło. Przestrzeń po dwukropku nie ma znaczenia. Tworzysz nowe tablice, a nie ustawiasz element tablicy, o który chodziło. Nie możesz wyprowadzić tablicy takiej jak {{tablica}}, co spowodowałoby błąd. Ta odpowiedź jest pełna niepowodzeń i niezwiązana z zadanym pytaniem.
redreinard
3
Nie rozumiem, dlaczego to ma głosy za, jak stwierdzono powyżej, prawie wszystko jest niepoprawne w tej „odpowiedzi” ...
MariusJP
0

Miałem tablicę wielowymiarową. Jedynym rozwiązaniem, jakie mogłem znaleźć, jest utworzenie nowej tymczasowej tablicy i zaktualizowanie / dodanie informacji, które zostały następnie przekazane do innej funkcji gałązki.

shobekhan
źródło
0

Miałem ten problem kiedyś temu. Wyobraź sobie, że masz tablicę taką jak ta:

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

Więc chcesz pokazać te dane w dwóch wierszach, ale usuń hasło z tej listy. W tym celu podzielenie na 2 tablice będzie łatwe dzięki slicefiltrowi. Musimy jednak usunąć hasło. Z tego powodu używam tego fragmentu. Chodzi o to, aby wszystkie elementy były mniejsze niż datarozmiar elementów podzielony przez 2. Aby to obliczyć, używamy filtra length. Teraz, aby uzyskać indeks bieżącego elementu, którego używamy loop.index. I na koniec * wypychamy element asocjacyjny w lewej lub prawej tablicy. Tablica asocjacyjna ma dwa komponenty keyi value. Aby odwołać się do klucza tablicy w twit, używamy operatora ()i używamy mergefiltru, aby wepchnąć go do tablicy, jak pokazano tutaj{% set left_list = left_list|merge({ (key): value }) %}

To jest kompletne rozwiązanie.

{% 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
źródło
0

Możesz również użyć następującej składni:

{% set myArray = myArray + myArray2 %}
GarryOne
źródło