7

I have an array of entities that i would like to render in a list.

$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;

The twig template then creates the unordered list of URLs using the array of {{ chemicals.label }} and {{ chemicals.id }}. However, I should be able to just pass $entities to the template instead of extracting the id and label and building a new array, shouldn't I?

If I replace '#chemicals' => $chemicals with '#chemicals' => $entities I receive an error:

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,   
6
  • You can, but you are probably trying to print the field item instead of the value. Can you add the twig that you tried to apply onto the entities array?
    – Eyal
    Jun 13, 2016 at 21:11
  • I kept it the same. The twig documentation says that foo.id should access 'methods or properties of Objects'. I assume this means foo->id or foo->id(). Jun 13, 2016 at 21:38
  • 1
    The id property of taxonomy terms is tid and the label property is name. And to access their values you will need to use either {{ entity.tid.value }} or {( entity.id() }}. I'm writing this from a phone so syntax errors are possible.
    – Eyal
    Jun 13, 2016 at 21:44
  • This is not a taxonomy term, but a custom entity which contains an entity_reference to a taxonomy term. I am trying to print the label and id of the custom entity, not the taxonomy term. However, this might still be the right answer. I'll have to try it out tomorrow. Jun 13, 2016 at 22:17
  • The tid confused me a bit.
    – Eyal
    Jun 13, 2016 at 22:19

4 Answers 4

19

As the exception explains, you tried to print an object that is not renderable and cannot be converted to a string. In this case it was Drupal\Core\Field\FieldItemList which is the object returned by drupal entities when you ask for a field ({{ entity.id }} / {{ entity.label }}).

To get the actual value you need to call to methods of your entity (the actual value of the fields is protected from outside access).

The long way:

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

The above is the actual path you need to take to get from the entity object to the value of the id field.

However drupal supplies shortcuts through what is known as magic properties. The short way

{{ entity.id.value }}
1
  • In addition to "the long way", you can also use: {{ node.field_from_node.field_from_inner_entity[0].get('value').getValue() }} If you are trying to obtain one url link: {{ node.field_from_node.field_from_inner_entity[0].get('uri').getValue() }}
    – DarkteK
    Sep 2, 2021 at 7:59
2

To get the full objects in your twig file, you could have done this:

$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;

Then, in your twig file just do:

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

You have to implement function template_preprocess_chemical_taxonomy(&$variables) where you prepare you variables for your template.

As an example have a look in core regarding function template_preprocess_item_list(&$variables) for item-list.html.twig.

0

You have to render the entity before passing it to twig.

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

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

Of course, this means creating a custom viewbuilder for your entity, if you haven't already, which may be more work, but would a nicer solution than creating a custom array each time you want to render your entity.

You could copy another view builder, such as core/modules/node/src/NodeViewBuilder.php

move it into your project and alter it to work with your custom entity.

1
  • To render something before passing it into a view (template) should not be allowed anymore since almost 10 years. Thats very very bad practice. de.wikipedia.org/wiki/Model_View_Controller And it causes an unlimited amount of problems inside of Drupalprojects.
    – Slowwie
    May 28, 2020 at 10:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.