web-dev-qa-db-fra.com

Comment accéder correctement aux éléments d'entité dans un modèle twig

J'ai un tableau d'entités que je voudrais rendre dans une liste.

$ids = \Drupal::entityQuery('chemical')
  ->condition('tid', $tid)
  ->execute();
$controller = \Drupal::entityManager()->getStorage('chemical');
$entities = $controller->loadMultiple($ids);

$chemicals = [];
foreach ($entities as $entity){
  $chemicals[] = ['id' => $entity->id(), 'label' => $entity->label()];
}

$output[] = [
  '#theme' => 'chemical_taxonomy',
  '#chemicals' => $chemicals,
];
return $output;

Le modèle twig crée ensuite la liste non ordonnée des URL à l'aide du tableau de {{ chemicals.label }} et {{ chemicals.id }}. Cependant, je devrais pouvoir simplement passer $entities au modèle au lieu d'extraire l'ID et l'étiquette et de créer un nouveau tableau, n'est-ce pas?

Si je remplace '#chemicals' => $chemicals avec '#chemicals' => $entities Je reçois une erreur:

Uncaught PHP Exception Exception: "Object of type Drupal\\Core\\Field\\FieldItemList cannot be printed." at /var/www/Drupal_Sites/console/core/lib/Drupal/Core/Template/TwigExtension.php line 443,   
5
Kevin Nowaczyk

Comme l'explique l'exception, vous avez essayé d'imprimer un objet qui n'est pas rendu et qui ne peut pas être converti en chaîne. Dans ce cas, c'était Drupal\Core\Field\FieldItemList qui est l'objet renvoyé par drupal entités lorsque vous demandez un champ ({{ entity.id }}/{{ entity.label }}).

Pour obtenir la valeur réelle, vous devez appeler les méthodes de votre entité (la valeur réelle des champs est protégée contre les accès extérieurs).

Le long chemin:

{{ entity.get('id').get(0).get('value').getValue() }}

Ce qui précède est le chemin réel que vous devez prendre pour passer de l'objet entité à la valeur du champ id.

Cependant drupal fournit des raccourcis à travers ce que l'on appelle les propriétés magiques.

{{ entity.id.value }}
15
Eyal

Pour obtenir les objets complets dans votre fichier twig, vous auriez pu faire ceci:

$ids = \Drupal::entityQuery('chemical')
  ->condition('tid', $tid)
  ->execute();
$controller = \Drupal::entityManager()->getStorage('chemical');
$entities = $controller->loadMultiple($ids);

$output[] = [
  '#theme' => 'chemical_taxonomy',
  '#chemicals' => $entities,
];
return $output;

Ensuite, dans votre fichier twig, faites simplement:

<ul>
{% for chemical in chemicals %}
  <li data-id="{{ chemical.id() }}">{{ chemical.label() }}</li>
{% endfor %}
</ul>
1
Stef Van Looveren

Vous devez implémenter function template_preprocess_chemical_taxonomy(&$variables) où vous préparez vos variables pour votre modèle.

Par exemple, jetez un œil au noyau concernant la fonction template_preprocess_item_list(&$variables) pour item-list.html.twig.

0
Maouna

Vous devez rendre l'entité avant de la passer à un rameau.

$render_controller = \Drupal::entityManager()->getViewBuilder('chemical');

foreach ($entities as $entity){
  $chemicals[] = $render_controller->view($entity);
}

Bien sûr, cela signifie créer un visualiseur personnalisé pour votre entité, si vous ne l'avez pas déjà fait, ce qui peut être plus de travail, mais serait une meilleure solution que de créer un tableau personnalisé chaque fois que vous souhaitez rendre votre entité.

Vous pouvez copier un autre générateur de vue, tel que core/modules/node/src/NodeViewBuilder.php

déplacez-le dans votre projet et modifiez-le pour qu'il fonctionne avec votre entité personnalisée.

0
oknate