Parcourez les éléments enfants dans Twig comme Element :: children ()


9

Lorsque j'ai affaire à un tableau de rendu en PHP, je peux utiliser Element :: children () pour accéder aux éléments qui ne sont pas des #propriétés mais des éléments de rendu subordonnés (éléments de formulaire à l'intérieur d'un fieldset, éléments à l'intérieur d'un widget de champ, etc.). Par exemple, cet extrait de fichier.module:

<?php
if ($element['#multiple']) {
  foreach (Element::children($element) as $name) {
    // ...
  }
}
?>

Comment puis-je faire de même dans un modèle Twig? Si je le fais {% for child in element %}, cela comprendra également #type, #cacheetc.


Réponses:


21
{% for key, child in element if key|first != '#' %}
  <div>{{ child }}</div>
{% endfor %}

2
Veuillez éviter les réponses contenant uniquement du code.
Mołot

2

J'ai créé un filtre Twig qui revient avec les enfants en tant que ArrayIterator.

mymodule/mymodule.services.yml

services:
  mymodule.twig_extension:
    arguments: ['@renderer']
    class: Drupal\mymodule\TwigExtension\Children
    tags:
      - { name: twig.extension }


mymodule/src/TwigExtension/Children.php

<?php

namespace Drupal\mymodule\TwigExtension;


class Children extends \Twig_Extension
{

  /**
   * Generates a list of all Twig filters that this extension defines.
   */
  public function getFilters()
  {
    return [
      new \Twig_SimpleFilter('children', array($this, 'children')),
    ];
  }


  /**
   * Gets a unique identifier for this Twig extension.
   */
  public function getName()
  {
    return 'mymodule.twig_extension';
  }


  /**
   * Get the children of a field (FieldItemList)
   */
  public static function Children($variable)
  {
    if (!empty($variable['#items'])
      && $variable['#items']->count() > 0
    ) {
      return $variable['#items']->getIterator();
    }

    return null;
  }

}


dans le modèle Twig:

{% for headline in entity.field_headline|children %}
  {{ headline.get('value').getValue() }}
{% endfor %}

2

Utilisez le module Twig Tweak , qui, entre autres fonctionnalités merveilleuses, possède un filtre "enfants":

{% for item in content.field_name | children(true) %}
  {# loop.length, loop.revindex, loop.revindex0, and loop.last are now available #}
{% endfor %}

1

Voici une modification de https://drupal.stackexchange.com/a/236408/67965 qui parcourt les enfants de rendu au lieu du champ #items.

L'extension des rameaux:

/**
 * Generates a list of all Twig filters that this extension defines.
 */
public function getFilters() {
  return [
    new \Twig_SimpleFilter('children', array($this, 'children')),
  ];
}

/**
 * Get the render children of a field
 */
public static function children($variable) {
  return array_filter(
    $variable, 
    function($k) { return (is_numeric($k) || (strpos($k, '#') !== 0)); },
    ARRAY_FILTER_USE_KEY
  );
}

Dans twig, vous pouvez ensuite passer directement par les enfants rendus, ce qui aide aux modèles de conception atomique. Définissez un modèle d'entité, par exemple:

{% include '@molecules/grid.html.twig' with { 
   head : content.field_title,
   grid_columns: content.field_collection_items|children
} %}

où grid.html.twig est quelque chose comme:

{% if head %}
<div class="slab__wrapper">
  {{ head }}
</div>
{% endif %}
<div class="grid">          
  {% for col in grid_columns %}
  <div class="grid__column">
    {{ col }}
  </div>
  {% endfor %}
</div>

Cela est généralement plus utile que d'avoir à rendre un modèle de champ {{ content.field_collection_items }}car la disposition des enfants peut être contrôlée dans le contexte de l'élément de conception parent.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.