Итерация по полю с несколькими значениями в шаблоне Twig

23

Мне нужно взять под контроль рендеринг field_admin_tagsполя в node.html.twigшаблоне.

Это работает:

  • {{ content.field_admin_tags }} - Отрисовывает все (метка + все значения полей)
  • {{ content.field_admin_tags.0 }} - Отображает только первое значение в поле, а не метку

ПРОБЛЕМА: я не контролирую разметку вокруг тегов, например <ul><li>...</li></ul>.

Поэтому моя идея заключалась в том, чтобы перебрать массив рендера .

Но это НЕ работает

{% for tag in content.field_admin_tags %}
  {{ tag }}
{% endfor %}

Я получаю: Exception: Object of type Drupal\node\Entity\Node cannot be printed.

Я думаю, что я перебираю ключи / значения массива рендеринга против элементов внутри поля (если я печатаю «X» в каждом цикле, я получаю 20 X, в то время как у меня есть только два или три значения в этом поле) ,

Я хотел бы перебрать content.field_admin_tags.0, content.field_admin_tags.1и т.д.

Есть идеи как это исправить? Спасибо.

AngularChef
источник
1
Вопрос по do drupal.org/node/2776307
gagarine

Ответы:

15

Вы можете исправить это в ветке поля. Там вы можете использовать существующий цикл для перебора элементов поля:

node.html.twig

{{ content.field_admin_tags }}

поле - поле-админ-tags.html.twig

<ul{{ attributes }}>
  {% for item in items %}
    <li>{{ item.content }}</li>
  {% endfor %}
</ul>

Этот пример заменяется <div>на <ul>. Не удаляйте {{ attributes }}и не пропускайте шаблон поля, посмотрите, что может сломать quickedit, и как я могу это исправить?

4k4
источник
Это вызывается из родительского шаблона с{{ content.field_admin_tags }}
aydow
23

Согласитесь с 4k4, шаблон поля - лучшее место, если вы действительно хотите его в шаблоне сущности (например, в узле), вы можете сделать что-то вроде этого:

{% for key, item in content.field_tags if key|first != '#' %}
  <div class="item-{{ key + 1 }}">{{ item }}</div>
{% endfor %}

Но, честно говоря, я думаю, что это немного уродливо, шаблон поля - правильное место.

Джефф Бернц
источник
1
Согласен, это немного некрасиво. ;) Спасибо за фрагмент кода, хотя.
AngularChef
Прекрасно работает с разными типами энтузиастов
Кристоф Кэрон
11

Если вы, как и я, ищете способ перебирать абзацы в шаблоне ветки узла, вот как это сделать:

Предположим, у вас есть узел с многозначным полем абзаца, поэтому редактор содержимого может создать несколько абзацев, и вы хотите перебирать каждый абзац в шаблоне ветки узла (например, чтобы добавить обертку вокруг каждого абзаца):

{% for key,value in node.my_paragraph_field.value %}
    {{ content.my_paragraph_field[key] }}
{% endfor %}

ОБНОВЛЕНИЕ: мне нужно было найти другой способ напечатать все параграфы без использования контента. Переменная содержимого содержит все, что вы настроили в разделе «Управление отображением» узла, но мой текущий метод работы - никогда не использовать ни «Управление отображением», ни макеты, поскольку вы можете фактически получить доступ ко всем данным в файле ветки узла и почти ко всем настройки, которые вы можете сделать в «Управлении отображением», такие как применение стиля изображения или установка формата даты, ... вы можете сделать это прямо в ветке.

Для меня это преимущество, потому что я знаю, что все, что я вижу, происходит из файла ветки, и мне не нужно искать какие-то непонятные настройки полей, которые могут где-то добавлять классы. Таким образом, все, что я вижу, происходит из одного места (файл ветки узла), а не из комбинации файла ветки и экрана управления отображением.

В любом случае, используя удивительный модуль Twig Tweak, вы узнаете, как напечатать многозначное поле абзаца в файле ветки узла, не используя переменную содержимого:

{% for item in node.field_paragraphs %}
    {{ drupal_entity('paragraph', item.target_id) }}
{% endfor %}
user33560
источник
1

Я обнаружил, что это #itemsсвойство полезно при создании циклов неизвестной длины в Twig:

print number of values within field:
{{ content.field_admin_tags['#items']|length }}

---

{# remember length in variable (minus 1 because it starts from 0): #}
{% set numTagsIndex = content.field_admin_tags['#items']|length - 1 %}

{# loop until the max value is reached: #}
{% for i in 0..numTagsIndex %}
  {{ content.field_admin_tags[i] }}
{% endfor %}
Крис Руппел
источник
0

Если вы хотите разместить дополнительные оболочки вокруг полей внутри поля абзаца или по каким-то причинам вам нужно конкретное значение поля ссылки на абзац, вы можете сделать следующее:

{% for key,value in node.paragraph_field_name.value %}

<div class="example-wrapper">
{{ content.paragraph_field_name[key]['#paragraph'].field_content.value }}
</div>

{% endfor %}

Сделав это {{kint(content.paragraph_field_name[key])}}, вы увидите, что поля доступны внутри части ['#paragraph'] массива.

Брент Шуддинк
источник