Skip to content

Instantly share code, notes, and snippets.

@AnneTee
Last active April 26, 2024 06:22
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save AnneTee/30e9de4f9fcb9eff603c7c3d90e75fb7 to your computer and use it in GitHub Desktop.
Save AnneTee/30e9de4f9fcb9eff603c7c3d90e75fb7 to your computer and use it in GitHub Desktop.
Drupal 8 Twig cheat sheet

D8 Twig cheat sheet

Conditionals

To check if a field has a value, check to see if the 0 array item is populated. Simply checking if content.field_name is truthy will not work since that variable will be defined even if the field is empty.

{% if content.field_name.0 %}
  {{ field_name }}
{% endif %}

Accessing entity info in Twig templates in D8

First off, there are a number of variables available to you in templates by default, and these are documented in the doc comment of templates that you pull from the base theme. For example, in a node template, label is the node title, url is the path to the node, and view_mode is the current view mode.

Entity ID

Get node ID in a node template:

{% set node_id = node.id() %}

You can do this for other entity types as well (e.g. you can use paragraph.id() inside a paragraph template).

Entity type

Get content type in a node template:

{% set content_type = node.bundle() %}

You can do this for other entity types as well (e.g. you can use paragraph.bundle() inside a paragraph template).

Published status

Figure out if node/paragraph is published:

{# Variables will be set to a boolean value. #}
{% set is_published = node.isPublished() %}
{% set is_published = paragraph.isPublished() %}

Accessing paragraphs within a node template

In this scenario, the hero media field is a paragraph field with several different types of paragraphs available. I needed to figure out what type of hero media paragraph was used for each node. This is how I got the paragraph type within the node template. The #paragraph item is the actual paragraph entity of the first value (0) in this field (this particular field can only have 1 value though). Note that you must use brackets to access variables that start with # in twig.

{% set paragraph_type = content.field_hero_media.0['#paragraph'].bundle() %}

Accessing paragraphs within a field template

Similarly, you can access paragraph info within field templates. In this template, I accessed paragraph data to set up a class and unique ID for each field item.

{% for item in items %}
  {% set p_type = 'paragraph--' ~ item.content['#paragraph'].bundle() %}
  {% set p_type_formatted = p_type|replace({'_': '-'}) %}
  {% set p_id = 'paragraph-' ~ item.content['#paragraph'].id() %}
  <div{{ item.attributes.addClass('field__item', p_type).setAttribute('id', p_id) }}>{{ item.content }}</div>
{% endfor %}

Accessing taxonomy terms within a node template

Similar to paragraphs, you can access a taxonomy term entity for a field within a node template.

Get a taxonomy term name:

{% set taxonomy_term_name = content.field_program_format.0['#taxonomy_term'].name.value %}

Translations

All text strings should be run through the t filter, which is the same thing as the t() function in Drupal 7:

  {{ 'Here is some text'|t }}

You should also do this when using with when including a template:

{% include '@theme_name/components/component.html.twig' with {
  'heading': 'This is a heading'|t,
} %}

If you need to include variables in a translated string, you can use the {% trans %} tag:

{% set year = 'now'|date('Y') %}
{% trans %}
  &copy; {{ year }} All rights reserved.
{% endtrans %}

Note that the following will not work – you have to set the year variable outside the {% trans %} tag.

{# Don't do this. #}
{% trans %}
  &copy; {{ 'now'|date('Y') }} All rights reserved.
{% endtrans %}

Miscellaneous

Get the absolute site URL:

{% set site_url = url('<front>')|render %}

Get a boolean field value:

{% set is_featured = content.field_featured_program.0['#markup'] %}

Get just the text from a plain text field (not usually recommended; it's better to add a field template to customize the field output if possible, and to keep wrapper divs with Drupal-generated attributes whenever possible):

{% set just_text = content.field_plain_text.0['#context'].value %}

Print a link URL and title separately:

<a class="font-medium text-14" href="{{ item.content['#url'] }}">
  {{ item.content['#title'] }}
</a>

Create a comma-delimited list of field values:

{% for item in items %}
  {{ item.content }}{% if _key < items|length - 1 %}{{ ', ' }}{% endif %}
{% endfor %}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment