Getting Drupal 8/9 Field Values in Twig

Sarah Carney
6 min readJul 23, 2018

--

Master list (in progress) of how to get parts of fields for use in Twig templates. I’m always having to look these up, so I thought I’d hash them out and write them down.

UPDATED: March 28, 2018 to add more fields, fix errors, and re-organize the content.

UPDATED: Jan 16, 2020 to add Link field type.

NOTE: These techniques are only tested in node.html.twig templates.

NOTE: Oct 16, 2012 — these have not been thoroughly tested in Drupal 10 so may be out of date.

Contents

  1. Body
  2. Text
  3. List
  4. Link
  5. Image
  6. File
  7. Boolean
  8. Number
  9. Email
  10. Phone
  11. Date
  12. Taxonomy/Entity Reference
  13. Labels for any field type
  14. Multi-value for any field type
  15. Examples
  16. Concepts/Background

Briefly, how to use this guide:

The Manage Display admin UI can change how a field’s label and content are displayed. When I want to show how to output just the Manage Display version of the content, I use the word ‘display’. When I’m talking about the more raw version of the content, I use ‘value’.

I have used field_name for a placeholder machine name for each field. Replace it with your field’s machine name. You can find the machine name of fields in the Manage Fields of your content type.

To only show labels: scroll down to item #12.

01. Body

The default body field on a content type is essentially a Text (formatted, long, with summary) field type.

Content (display): {{ content.body.0 }} This will display whatever is set up in Manage Display. If the body field is set to Summary or Trimmed, this will show that.

Content (value, formatted): {{ node.body.value|raw }} This shows the content of the text field itself, regardless of what is set in Manage Display. This will parse any HTML. Note: it is my understanding that the Twig filter raw can present security problems, but I haven’t found another way to do this. More on the Twig raw filter.

Content (value, unparsed HTML): {{ node.body.0.value }} Show the very raw value of the field, including unparsed HTML.

Content (value, plain text): {{ node.body.0.value|striptags }} As above, but will remove HTML, as if it were plain text.

Summary: {{ node.body.summary }}

Want to read this story later? Save it in Journal.

02. Text

Very similar to Body, but why not just put it here so it’s easier for you to find?

Text (plain) and Text (plain, long)

Content (display): {{ content.field_name }}

Content (value): {{content.field_name.0 }}

Text (formatted), Text (formatted, long), Text (formatted, long, with summary)

Content (display): {{ content.field_name.0 }} Again, this shows whatever is set up in Manage Display, which could be Default or Trimmed.

Content (value, formatted): {{ node.field_name.0.value|raw }}

Content (value, unparsed): {{ node.field_name.0.value }} Show the very raw value of the field, including unparsed HTML.

Content (value, plain text): {{ node.field_name.0.value|striptags }}

Summary: {{ node.field_name.summary }}

03. List

List (float), List (integer), List (text)

These are fields with a key and label. The key is what is stored as the value. Remember label here doesn’t mean the field label, but the key’s label.

Content (display): {{ content.field_name.0 }} If the Display is set to Key, it will show key. If it’s set to Label, it will show label.

Content (label): I haven’t figured out how to pull the label in the same way I can pull key. So you might want to do this by changing the Manage Display to Label.

Content (key): {{ node.field_name.0.value }}

These will show the first item in the field. For multi-value fields you can show a different item by changing the 0 to another number. Remember start counting at 0; the second item would be 1.

To show all items see the Multi-Value section #13.

04. Link

Content (display): {{ content.field_name }}

If it’s a multi-value field, the above example will output all of them, exactly as configured in the Manage display. To pull just one value in this way, add an index like this: {{ content.field_name.0 }}

Link only: {{ content.field_name.0.url }}

Link text only: {{ content.field_name.0.title }}

These will show the first item in the field. For multi-value fields you can show a different item by changing the 0 to another number. Remember start counting at 0; the second item would be 1.

05. Image

Content (display — the image): {{ content.field_name.0 }}

Content (image path):
{{ file_url(content.field_name['#items'].entity.uri.value) }}

Alt text: {{ node.field_name.alt }}

Title text: {{ node.field_name.title }}

Height/Width:
{{ node.field_name.height }} or {{ node.field_name.width }}

06. File

Content (display): {{ content.field_name.0 }}

Content (file path):
{{ file_url(content.field_name['#items'].entity.uri.value) }}

Description: {{ node.field_name.description }}

07. Boolean

This works very much like List, but the key works a little differently. For boolean fields, the key are either 0 (not selected) or 1 (selected).

Content (display): {{ content.field_name.0 }}

Content (key): {{ node.field_name.0.value }}

To show all items see the Multi-Value section #13.

08. Number

Number (decimal) and Number (float)

Content (display): {{ content.field_name.0 }}

Content (value): {{ node.field_name.0.value }} This would remove any prefix/suffix.

To show all items see the Multi-Value section #13.

09. Email

Content (display): {{ content.field_name.0 }}

Content (value): {{ node.field_name.0.value }} This shows the plain text email.

To show all items see the Multi-Value section #13.

10. Phone

Content (display): {{ content.field_name.0 }}

Content (value): {{ node.field_name.0.value }}

To show all items see the Multi-Value section #13.

11. Date

Content (display): {{ content.field_name.0 }}

Content (value): {{ node.field_name.0.value }} This is going to out put all the date information usually something this: Mon, 03/25/2019–02:57

To show all items see the Multi-Value section #13.

12. Taxonomy/Entity Reference

I haven’t done a lot of digging into this field type, but here’s the Taxonomy term reference, at least.

Content (display): {{ content.field_name.0 }}

Content (value): {{ node.field_name.0.target_id }} This shows the tag id, which is a number.

Content (term title): {{ content.field_name[0]['#title'] }}

Content (term path): {{ content.field_name[0]['#url'] }}

13. Label for any field type

{{ node.field_name.fieldDefinition.label }}

14. Multi-Value for any field type

When a field allows multiple values, here’s how to print them out in the node template with a lot of control over HTML.

Here, {{ item }} displays the full field content as configured in the Manage Display. Here is how it works for a <ul>.

{% if content.field_name[0] %}
<ul>
{% for key, item in content.field_name if key|first != '#' %}
<li>{{ item }}</li>
{% endfor %}
</ul>
{% endif %}

You can combine this multi-value technique with the techniques above.

15. Examples

Example 1: make a ul of List field keys

{% if content.field_name[0] %}
<ul>
{% for key, item in node.field_name if key|first != '#' %}
<li>{{ item.value }}</li>
{% endfor %}
</ul>
{% endif %}
  1. To get the entire field I’d use {{ content.field_name }} so I want to check if there is at least one value with {% if content.field_name[0] %}.
  2. To get a single key I’d use {{ node.field_name.0.value }}, so I’ll use node.field_name as where I pull item from.

Example 2: get the names of tags in a ul.

{% if content.field_name[0] %}
<ul>
{% for key, item in content.field_name if key|first != '#' %}
<li>{{ item['#title'] }}</li>
{% endfor %}
</ul>
{% endif %}
  1. To get the whole field I’d use {{ content.field_name }}, so I check to see if there is a value with {% content.field_name[0] %}
  2. To get a single tag title I’d use {{ content.field_name[0]['#title'] }}, so I use the first part in the for section: content.field_name.
  3. The 0 represents whichever item in the list, so I can replace that and everything before it with item, and look for ['#title'].

16. Concepts

Pay attention to when content and node are used above. In a node template like node--page.html.twig the content variable is looking at the options chosen in Manage Display for that content type. I love doing as much in the UI as I can, but sometimes we need to get parts of the field before they get changed by those settings.

That’s when we go into the node to get what we want. More ‘raw’ information is stored above or before the Display.

Here is a silly chart to demonstrate that flow.

  1. A user adds information to the form.
  2. This adds lots of little pieces of discrete data to where the node is stored.
  3. Then Drupal 8 and Manage Display combine that data and show it in a nice little preformatted chunk. That’s content, ya’ll.
  4. But! With node or sometimes element['#object'] or other things we can bypass Manage Display and display things more granularly.
A chart demonstration the Wonka Boat Scene journey of something being entered into a node form, how Drupal uses it, and how you can bypass.

More from Journal

There are many Black creators doing incredible work in Tech. This collection of resources shines a light on some of us:

--

--