Iterar através do campo de conteúdo com múltiplos valores no modelo Twig

23

Eu preciso assumir o controle sobre a renderização de um field_admin_tagscampo em um node.html.twigmodelo.

Isso funciona:

  • {{ content.field_admin_tags }} - Renderiza tudo (rótulo + todos os valores do campo)
  • {{ content.field_admin_tags.0 }} - Renderiza apenas o primeiro valor no campo e nenhum rótulo

PROBLEMA: Não tenho controle sobre a marcação em torno das tags, por exemplo <ul><li>...</li></ul>.

Então, minha idéia foi iterar sobre a matriz de renderização .

Mas isso NÃO funciona:

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

Eu recebo: Exception: Object of type Drupal\node\Entity\Node cannot be printed.

Eu acho que estou iterando sobre as chaves / valores da matriz de renderização versus os itens dentro do campo (se eu imprimir um "X" em cada loop, recebo 20 Xs enquanto tenho apenas dois ou três valores nesse campo) .

Eu gostaria de iterar content.field_admin_tags.0, content.field_admin_tags.1etc.

Alguma idéia de como consertar isso? Obrigado.

AngularChef
fonte
1
A questão em fazer drupal.org/node/2776307
Gagarine

Respostas:

15

Você pode corrigir isso em um galho de campo. Lá você pode usar o loop existente para iterar sobre os itens de campo:

node.html.twig

{{ content.field_admin_tags }}

campo - campo-admin-tags.html.twig

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

Este exemplo substitui <div>por <ul>. Não remova {{ attributes }}ou ignore o modelo de campo, consulte O que pode interromper o quickedit e como corrigi-lo?

4k4
fonte
Isso é chamado do modelo pai com{{ content.field_admin_tags }}
aydow
23

Concorde com 4k4, o modelo de campo é o melhor local; se você realmente deseja no modelo de entidade (por exemplo, nó), pode fazer algo assim:

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

Mas, honestamente, acho um pouco feio, o modelo de campo é o lugar certo.

Jeff Burnz
fonte
1
Concordo, é um pouco feio. ;) Obrigado pelo snippet de código.
AngularChef 29/07
Funciona perfeitamente com diferentes tipos de entidades
Christophe CARON
11

Se você, como eu, está procurando uma maneira de percorrer parágrafos no modelo de galho de um nó, eis como fazê-lo:

Suponha que você tenha um nó com um campo de vários valores, para que um editor de conteúdo possa criar vários parágrafos e deseje percorrer cada parágrafo no modelo de ramificação dos nós (por exemplo, para adicionar um wrapper a cada parágrafo):

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

ATUALIZAÇÃO: Eu precisava encontrar outra maneira de imprimir todos os parágrafos sem usar o conteúdo. A variável content contém tudo o que você configurou na seção 'Gerenciar exibição' do nó, mas meu método de trabalho atual é nunca usar 'Gerenciar exibição' nem layouts, pois é possível acessar todos os dados no arquivo ramificado do nó e quase todos configurações que você faria em 'Gerenciar exibição', como aplicar um estilo de imagem ou definir um formato de data, ... você pode fazer diretamente no galho.

Para mim, isso é uma vantagem, porque sei que tudo o que vejo vem do arquivo twig e não preciso procurar por algumas configurações de campo obscuras que podem adicionar classes em algum lugar. Então, tudo o que vejo vem de apenas um lugar (o arquivo de nós de galho) e não uma combinação do arquivo de galho e da tela de exibição de gerenciamento.

De qualquer forma, usando o incrível módulo Twig Tweak, eis como imprimir um campo de parágrafo com vários valores no arquivo twig de um nó sem precisar usar a variável content:

{% for item in node.field_paragraphs %}
    {{ drupal_entity('paragraph', item.target_id) }}
{% endfor %}
user33560
fonte
1

Eu achei a #itemspropriedade útil ao criar loops de comprimento desconhecido no 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 %}
Chris Ruppel
fonte
0

Se você deseja colocar wrappers adicionais ao redor dos campos dentro do campo de parágrafo ou precisar, por algum motivo, de um valor específico do campo de referência de parágrafo, faça o seguinte:

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

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

{% endfor %}

Ao fazer isso {{kint(content.paragraph_field_name[key])}}, você verá que os campos estão acessíveis dentro da parte ['#paragraph'] da matriz.

Brent Schuddinck
fonte