web-dev-qa-db-fra.com

Itérer dans le champ de contenu à valeurs multiples dans le modèle Twig

Je dois prendre le contrôle du rendu d'un field_admin_tags champ dans un node.html.twig modèle.

Cela marche:

  • {{ content.field_admin_tags }} - Rend tout (étiquette + toutes les valeurs de champ)
  • {{ content.field_admin_tags.0 }} - N'affiche que la première valeur du champ et aucune étiquette

PROBLÈME: je n'ai aucun contrôle sur le balisage entourant les balises, par ex. <ul><li>...</li></ul>.

Donc, mon idée était de itérer sur le tableau de rend.

Mais cela ne fonctionne PAS:

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

Je reçois: Exception: Object of type Drupal\node\Entity\Node cannot be printed.

Je pense j'itère sur les clés/valeurs du tableau de rend vs les éléments à l'intérieur du champ (si j'imprime un "X" dans chaque boucle, j'obtiens 20 X alors que je n'en ai que deux ou trois valeurs dans ce champ).

Je voudrais parcourir content.field_admin_tags.0, content.field_admin_tags.1, etc.

Une idée de comment résoudre ce problème? Merci.

24
AngularChef

Vous pouvez résoudre ce problème dans une branche de champ. Là, vous pouvez utiliser la boucle existante pour parcourir les éléments de champ:

node.html.twig

{{ content.field_admin_tags }}

champ - field-admin-tags.html.twig

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

Cet exemple remplace <div> avec <ul>. Ne supprimez pas {{ attributes }} ou contourner le modèle de champ, voir Qu'est-ce qui peut casser quickedit, et comment puis-je le réparer?

16
4k4

D'accord avec 4k4, le modèle de champ est le meilleur endroit, si vous le voulez vraiment dans le modèle d'entité (par exemple, le nœud), vous pouvez faire quelque chose comme ceci:

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

Mais honnêtement, je pense que c'est un peu moche, le modèle de champ est le bon endroit.

24
Jeff Burnz

Si vous, comme moi, cherchez un moyen d'itérer à travers les paragraphes du modèle twig twig $, voici comment procéder:

Supposons que vous ayez un nœud avec un champ de paragraphe à plusieurs valeurs, afin qu'un éditeur de contenu puisse créer plusieurs paragraphes et que vous souhaitiez parcourir chaque paragraphe sur les nœuds twig modèle (par exemple pour ajouter un wrapper autour de chaque paragraphe):

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

MISE À JOUR: Je devais trouver une autre façon d'imprimer tous les paragraphes sans utiliser de contenu. La variable de contenu contient tout ce que vous avez configuré dans la section "Gérer l'affichage" du nœud, mais ma méthode de travail actuelle consiste à ne jamais utiliser "Gérer l'affichage" ni les dispositions car vous pouvez réellement accéder à toutes les données du nœud twig fichier, et presque tous les paramètres que vous feriez sur "Gérer l'affichage", comme appliquer un style d'image, ou définir un format de date, ... vous pouvez le faire directement dans twig.

Pour moi, c'est un avantage car je sais que tout ce que je vois provient du fichier twig, et je n'ai pas besoin de rechercher des paramètres de champ obscurs qui peuvent ajouter des classes quelque part. Donc tout ce que je vois provient d'un seul endroit (les nœuds twig) et non d'une combinaison du fichier twig et de l'écran d'affichage de gestion).

Quoi qu'il en soit, en utilisant le module génial Twig Tweak, voici comment imprimer un champ de paragraphe à valeurs multiples dans le fichier twig twig $ sans avoir à utiliser la variable de contenu:

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

J'ai trouvé une méthode qui est similaire à la réponse de @ chris-ruppel, mais un peu plus élégante à mon humble avis. Il utilise le filtre keys pour obtenir un tableau d'index disponibles. Je l'utilise pour construire une liste HTML.

<ul>
  {% for i in content.field_foo['#items']|keys %}
    <li>{{ content.field_foo[i] }}</li>
  {% endfor %}
</ul>
2
marcvangend

J'ai trouvé le #items propriété utile lors de la construction de boucles de longueur inconnue dans 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 %}
1
Chris Ruppel

Si vous souhaitez placer des wrappers supplémentaires autour des champs à l'intérieur du champ de paragraphe ou si vous avez besoin, pour une raison quelconque, d'une valeur de champ de référence de paragraphe particulière, vous pouvez effectuer les opérations suivantes:

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

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

{% endfor %}

En faisant {{kint(content.paragraph_field_name[key])}}, vous verrez que les champs sont accessibles à l'intérieur de la partie ['# paragraph'] du tableau.

0
Brent Schuddinck