Налаштування елемента масиву від Twig


126

Як я можу встановити член вже наявного масиву від Twig?

Я спробував це зробити наступним чином:

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

але я отримав таку помилку:

Несподіваний маркер "пунктуація" значення "[" ("очікується" кінець блоку заяви ") у ...

Відповіді:


211

В Twig немає жодного приємного способу зробити це. Однак це можливо за допомогою фільтра злиття:

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

"." - заява така ж, як "[]", тому це не рішення
falinsky

@falinsky Ви маєте рацію. .і []дуже схожі в Twig, і я помилився. Я подивився на це і відредагував свою відповідь.
Поль

17
Я шукав спосіб визначити динамічний ключ змінної при заміні 'element'. Нижче я знайшов відповідь @ LivaX. Отже, було б {% set arr = arr|merge({(key): 'value'}) %}.
Сіту

Це так нерозумно. Чому гілочка не дозволяє встановлювати значення масиву?
Метт Кавана

1
@MattCavanagh, оскільки файли перегляду (наприклад, Twig) не повинні містити ділової логіки, в кінцевому підсумку це слід обробляти в моделі. Погляд дійсно повинен просто відобразити те, що там є. Проблема, хоча в моєму випадку, і чому я також згоден з вами, полягає в тому, що я створюю макроси гілочок для візуалізації об’єктів інтерфейсу, наприклад. {{ UI.button({'type':'submit'}) }}і всі ці макроси використовують | злиття для встановлення параметрів за замовчуванням, тому в цьому є логічна потреба ...
Prof83

80

Я зіткнувся з цією проблемою, але намагався створити цілі індекси замість асоціативного індексу, як 'елемент'.

Вам потрібно захистити свій індексний ключ, ()використовуючи також фільтр злиття:

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

Тепер ви можете додати спеціальний індексний ключ, наприклад ('element'~loop.index0)


Це власне рішення, коли ви намагаєтеся вставити клавіші динамічно, завдяки LivaX!
nicolallias

19

Якщо потрібна лише ініціалізація:

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

9
Про це не було питання.
redreinard

2

Я спробував відповідь @LivaX, але це не працює, об'єднавши масив, де працюють ключі з числовим звичаєм ( https://github.com/twigphp/Twig/isissue/789 ).

Це буде працювати лише тоді, коли ключі є рядками

Що я зробив, це відтворити іншу таблицю ( temp) з початкової таблиці ( t) і зробити ключі рядком, наприклад:

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

t клавіші: 0, 1, 2..

temp клавіші: 0_, 1_, 2_ ....


Те саме питання, поки що немає рішення.
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'%}

Дякую за цю тему - я також зміг створити масив з (loop.index0) та надіслати twig.


1

Я вважаю це питання дуже дратівливим, і моє рішення, можливо, ортодоксальне і не відповідає філософії Twig, але я розробив наступне:

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

які можна використовувати наступним чином:

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


1

Просто використовуйте подібне {% set arr={'key':'value'} %}(без порожнього місця після: ), воно добре працює.

Але коли я використовую його всередині циклу 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
Якщо ви хочете використовувати змінну за межами циклу for, вам потрібно визначити її поза межами циклу for, дивіться тут: twig.sensiolabs.org/doc/tags/set.html
user2019515

5
Це всілякі неправильні. Простір після товстої кишки не має значення. Ви створюєте нові масиви, не встановлюючи елемент у масиві, який був питанням. Ви не можете вивести масив на зразок {{array}}, що призведе до помилки. Ця відповідь повна невдач і не пов'язана з поставленим запитанням.
redreinard

3
Я не розумію, чому це спричинило, як сказано вище, майже все невірно в цій "відповіді" ...
MariusJP

0

У мене був багатовимірний масив. Єдине рішення, яке я міг дізнатися, - це створити новий тимчасовий масив та оновити / додати інформацію, яка надалі була передана іншій функції гілочки.


0

Я мав цю проблему десь тому. Уявіть, у вас є такий масив:

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

Отже, ви хочете показати ці дані в два ряди, але видаліть пароль із цього списку. З цією метою розділити на 2 масиви буде легко з sliceфільтром. Однак нам доведеться видалити пароль. З цієї причини я використовую цей фрагмент. Ідея полягає в тому, щоб розмістити всі елементи менше dataрозміру елементів, розділених на 2. Для обчислення цього ми використовуємо фільтр length. Тепер, щоб отримати індекс поточного елемента, який ми користуємося loop.index. І, нарешті, ми * натискаємо асоціативний елемент у лівому чи правому масиві. Асоціативний масив має дві складові keyта value. Для посилання на ключ масиву в twit ми використовуємо оператор, ()і ми використовуємо mergeфільтр, щоб натиснути на масив, як показано тут{% set left_list = left_list|merge({ (key): value }) %}

Це повне рішення.

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

Ви також можете використовувати такий синтаксис:

{% set myArray = myArray + myArray2 %}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.