Getting Drupal 8/9 Field Values in Twig
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
- Body
- Text
- List
- Link
- Image
- File
- Boolean
- Number
- Phone
- Date
- Taxonomy/Entity Reference
- Labels for any field type
- Multi-value for any field type
- Examples
- 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 %}
- 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] %}
. - To get a single key I’d use
{{ node.field_name.0.value }}
, so I’ll usenode.field_name
as where I pullitem
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 %}
- 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] %}
- To get a single tag title I’d use
{{ content.field_name[0]['#title'] }}
, so I use the first part in thefor
section:content.field_
name. - The
0
represents whichever item in the list, so I can replace that and everything before it withitem
, 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.
- A user adds information to the form.
- This adds lots of little pieces of discrete data to where the node is stored.
- Then Drupal 8 and Manage Display combine that data and show it in a nice little preformatted chunk. That’s
content
, ya’ll. - But! With
node
or sometimeselement['#object']
or other things we can bypass Manage Display and display things more granularly.
More from Journal
There are many Black creators doing incredible work in Tech. This collection of resources shines a light on some of us: