Rendering fields in Drupal 9 (the right way)
James Williams
Many of us at ComputerMinds have always taken pride on doing Drupally things the right way whenever possible, and then helping the community do so too. One of these things is displaying values from fields on content entities. We wrote before about how to do this in Drupal 7 and Drupal 8. It's now the turn of Drupal 9! Thankfully, this updated version is basically the same as the last one, as D9 is very similar to D8 on the surface, but with old cruft ripped out to allow it to continue improving. So the short answer to "How can I show a field programmatically?" is still:
$entity->field_whatever->view();
Isn't that great? Your existing code for Drupal 8 already works with Drupal 9! That was the aim of the update; to make the upgrade incredibly easy. Whereas upgrading from Drupal 7 can be a mammoth task (you might want to get in touch with us to help!), the jump to D9 is much simpler.
So is anything different? Most changes are buried well within Drupal's innards. The most relevant difference for displaying fields in Drupal 8 as opposed to Drupal 9 is that if you were originally loading the entity object ($entity
) using the entity.manager
service (e.g. from \Drupal::entityManager()
), you now need to use the entity_type.manager
service (e.g. \Drupal::entityTypeManager()
).
Our previous article on rendering fields in D8 contains much more detail, which is still totally valid for Drupal 9. That will help you tweak the formatter settings to view a field with, or how to get raw values out of the field. For example:
// Render an image field with a specific image style.
$entity->field_my_image->view([
'type' => 'image',
'label' => 'hidden',
'settings' => array(
'image_link' => 'content',
'image_style' => 'square_icon',
),
]);
// Get the raw value out of a single-value link field.
$link = $entity->field_web_address->uri;
A comment on that article did point out that you can get fatal errors if you use this code too naïvely. That's because magic methods are used here, with the assumption that you are sure the field exists on the entity. If you don't, then just break the chaining down:
// The $field variable will just be null if the entity doesn't have this field.
if ($field = $entity->field_whatever) {
$to_show = $field->view();
}
Alternatively, you can use get()
methods instead of the magic methods. But if you do, you'll probably want to surround your code with Exception handling to catch InvalidArgumentException
exceptions, as the magic method getters are more lenient in more scenarios.
Photo by Belle Hunt on Unsplash