Drupal 8 Twig cheatsheet

Tags:

## Drupal 8 Twig cheatsheet

### Getting Drupal 8 field values in Twig

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

Image title text: `{{ node.field_name.title }}`

Entity Reference path: `{{ content.field_tags[0]['#url'] }}`

@see https://blog.usejournal.com/getting-drupal-8-field-values-in-twig-22b80c...

### Check if field is filled

```
{% if content.field_image|length %}
{{ content.field_image[0] }}
{% endif %}
```

### Check for some content existence

Those solutions are not perfect.
@see https://www.drupal.org/project/drupal/issues/953034?page=1

- e.g. for a region or a field that contains text `content.field_fee|render|striptags|trim`
- e.g. for a field image using field value module `content.header.field_image|field_value`

### Custom date format

`{% set date = node.createdtime|format_date('long') %}`

@see http://agileadam.com/2017/08/drupal-8-formatting-a-date-field-in-twig/

Use Twig date filter + a defined Drupal date format

`{{ node.field_blog_date.value|date('U')|format_date('short_mdyyyy') }}`

Use Twig date filter

`{{ node.field_blog_date.value|date('n/j/Y') }}`

### Set variables in a translated twig variable

`{{ "Submitted by !author on @date"|t({ '!author': author, '@date': date }) }}`

or

```
{% set front_uri = path('') %}
{% set search_uri = path('view.solr_search_content.page_1') %}
{% trans %}Return to the homepage or search articles.{% endtrans %}
{{ 'Return to the homepage or search articles.'|t({'@front': front_uri, '@search': search_uri}) }}
```
or
```
{% set url_1 = path('entity.node.canonical', {'node': 1050}) %}
{% set url_2 = path('entity.node.canonical', {'node': 2010}) %}
{% trans %}I will have one link and a second link.{% endtrans %}
```
@see - more on twig translation https://getlevelten.com/blog/mark-carver/drupal-8-twig-templates-and-tra...

### Create a link

```
{{ 'Contact'|t }}
{{ 'Contact'|t }}
{{ link('Contact'|t, 'base:contact', { 'class':[] }) }}
```
@see - https://drupal.stackexchange.com/a/208107/30331

### Render a field to use it eg, in a translated string

`{% set number = "Duo @number"|t({ '@number': number|render|striptags }) %}`

@see https://www.drupal.org/project/drupal/issues/2728915#comment-11208967

### Loop through child elements in Twig like Element::children()

! First @see https://www.drupal.org/node/2776307
And https://www.drupal.org/project/twig_extender

```
{% for key, child in parent if key|first != '#' %}
{{ child }}
{% endfor %}
```

@see https://drupal.stackexchange.com/questions/174742/loop-through-child-ele...

or

```
{% for key, item in items %}
{% if key matches '/^\\d+$/' %}
{{ item }}
{% endif %}
{% endfor %}
```
Be carreful, this bypasses theme and will print without template and any html field wrappers
@see https://www.drupal.org/forum/support/theme-development/2015-12-16/entity...

### Merge arrays

That synthax avoid errors if `classes` is initialy empty.

```
{% set classes = { 'class' : 'teaser' }|merge({ (classes) : classes }) %}

```

### Override custom layout templates (eg for a specific node)

1. Be carreful to set

```
et_twocols_hero:
class: '\Drupal\ds\Plugin\DsLayout'
```

2. Also name the template as the machine name otherwise suggestions provided by DS will not follow the same convention bu the one from machine name then Entity, bundle, view mode
```
et_twocols_hero:
template: templates/et-twocols-hero
```

### Provide splited views More link and title vars

```
/**
* Implements template_preprocess_views_view()
* @param array $variables
*/
function hook_preprocess_views_view(&$variables){
$view = $variables['view'];

$variables['more_url'] = $variables['more']['#url'];
$variables['more_text'] = $variables['more']["#title"];

// @todo see usage of `title`, maybe combined with twig if on default template
$variables['custom_title'] = [
'#markup' => $view->getTitle(),
];
}
```

### Provide block classes from id

- plugin_id : unique identifier provided for all blocks (duplicated one, displayed by context module)
- elements['#id'] : unique identifier depending on block id defined via block layout UI, NULL is returned by context module

```
{%
set classes = [
'block-' ~ plugin_id|clean_class,
'block--' ~ (elements['#id'] ? elements['#id']|clean_class),
]
%}
```

### Provide Custom block bundle templates / or classes (block types from custom block library)

```
use \Drupal\block_content\BlockContentInterface;

/**
* Implements hook_theme_suggestions_block_alter().
*/
function hops_theme_suggestions_block_alter(array &$suggestions, array $variables) {
$content = $variables['elements']['content'];
if (isset($content['#block_content']) and $content['#block_content'] instanceof BlockContentInterface) {
$bundle = $content['#block_content']->bundle();
$view_mode = $content['#view_mode'];
$suggestions[] = 'block__' . $bundle;
$suggestions[] = 'block__' . $view_mode;
$suggestions[] = 'block__' . $bundle . '__' . $view_mode;
}
}
```

### Display a block entity reference field

```
{% block content %}
{% set node_1_teaser = content.field_node_reference.0|merge({'#view_mode': 'compact'}) %}
{% set node_2_teaser = content.field_node_reference.1|merge({'#view_mode': 'compact'}) %}
{{ node_1_teaser }}
{{ 'Learn more'|t }}
{{ node_2_teaser }}
{{ 'Learn more'|t }}
{% endblock %}
```