Using Drupal 10’s new Twig filters to set attributes on images

By mherchel, 1 July, 2023

Drupal 10 comes with a number of brand new Twig filters. In this article, I’ll walk you through using two of these to set the fetchpriority attribute on an image.

About the fetchpriority attribute

New to Chromium version 101 (released April 2022) is support for the new fetchpriority attribute. This attribute allows the markup to indicate the relative download priority of the resource it’s attached to. A typical use case of this attribute is setting fetchpriority="high" on an image that loads within the initial viewport. Doing so tells the browser to download the image as soon as possible, and can dramatically improve the largest contentful paint metric for the webpage.

Step 1: Create a new field template for your image field

The first step to set this attribute is to create a field template for the image field. However, when I enable Twig debug, I see Olivero already has a specific template for this field, field--node--field-image.html.twig. In most cases this won’t be there, and you’ll have to create one. However, in our case we'll be able to make use of it.

Image
Screenshot of Twig debug output showing field template suggestion

Furthermore, down the chain, we can see that Drupal is calling image-formatter.html.twig to render the image. We’ll be working with that file in the next step.

We need to modify this field template to use the new twig add_suggestion filter. The current field--node--field-image.html.twig simply extends the field.html.twig template. So we copy the values from that template into it, so we can modify it. The important part here is that we’re adding the filter: {{ item.content|add_suggestion('fetchpriorityhigh') }}

{% set attributes = attributes.addClass('primary-image') %}
{%
  set classes = [
    'field',
    'field--name-' ~ field_name|clean_class,
    'field--type-' ~ field_type|clean_class,
    'field--label-' ~ label_display,
    label_display == 'inline' ? 'clearfix',
  ]
%}

{% for item in items %}
  <div{{ attributes.addClass(classes, 'field__item') }}>{{ item.content|add_suggestion('fetchpriorityhigh') }}</div>
{% endfor %}

Note the |add_suggestion filter. This is new to Drupal 10.0, and super useful. In this case we’re using it to add a 'fetchpriorityhigh' template suggestion to the image formatter. This will tell Drupal to look for a image-formatter--fetchpriorityhigh.html.twig template.

Step 2: Create and modify a new image formatter template

In the image above you can see that Drupal is loading the markup for the image from core/modules/image/templates/image-formatter.html.twig. With the previous |add_suggestion filter, Drupal is looking for image-formatter--fetchpriorityhigh.html.twig. So we copy the original file into core/themes/olivero/templates/misc/ and rename it to the filename that Drupal is looking for.

Within this file, we make use of the new |set_attribute Twig filter that was introduced in Drupal 10.1.

{% if url %}
  {{ link(image|set_attribute('fetchpriority', 'high'), url) }}
{% else %}
  {{ image|set_attribute('fetchpriority', 'high') }}
{% endif %}

This filter does what you expect, and sets the attribute! Since we created a new template (and this is Drupal), we need to clear the cache before we check the results.

Image
Screenshot of Twig debug showing new image formatter template and fetchpriority attribute set to high

Woohoo! The fetchpriority is set!

Wrapping up

Setting the fetchpriority attribute will hopefully be able to be configured through the core image field formatter soon. However, the filters here are useful for all types of cool and useful things.

Hey you! Leave a comment!3

Seriously... I really like it when people let me know their thoughts and that they've read this.

The content of this field is kept private and will not be shown publicly.

Mario (not verified)

1 year 4 months ago

Nice tip.

Emmons Patzer (not verified)

1 year 3 months ago

Any suggestions on where to find the full list of available options you can use for the "set_attributes"?
image|set_attribute