Twig-blocks
Twig-blocks are native to the Twig-language. Twig’s documentation defines them as:
“Blocks are used for inheritance and act as placeholders and replacements at the same time.”
Overwriting content #
Let’s have a look at how node.html.twig
looks like from core. (simplified for readability sake)
{%
set classes = [
'node',
'node--type-' ~ node.bundle|clean_class,
]
%}
<article{{ attributes.addClass(classes) }}>
<div{{ content_attributes }}>
{{ content }}
</div>
</article>
Say, we want to add a label "blieblabloo" and position it above the{{ content }}
. We want this change for all the full view modes of nodes.
Then that means that we first create a node--full.html.twig
that extends from the node.html.twig
:
{%
set classes = [
'node',
'node--type-' ~ node.bundle|clean_class,
]
%}
<article{{ attributes.addClass(classes) }}>
<div{{ content_attributes }}>
{{ content }}
</div>
</article>
{% extends 'node.html.twig' %}
Secondly, we investigate what part of the base-template we want to overwrite, in this case it is the {{ content }}
part. So inside the node.html.twig
, we wrap the part that we want to to overwrite in a block tag.
We should name block tags to the variables they hold, in this case we are using the name “content”.
Our example now looks as follows:
{%
set classes = [
'node',
'node--type-' ~ node.bundle|clean_class,
]
%}
<article{{ attributes.addClass(classes) }}>
<div{{ content_attributes }}>
{% block content %}
{{ content }}
{% endblock %}
</div>
</article>
{% extends 'node.html.twig' %}
{% block content %}
<span>blieblabloo</span>
{{ content }}
{% endblock %}
And that’s it! You are now overwriting the parts of the original template that you want to overwrite. And you keep all the rest intact.
The placeholder-principle #
Creating new Twig block tags has no impact on the original template. When Drupal encounters a block tag in a template that is not extending, it will do the nothing different as if that block tag wasn’t there. Drupal will render the markup inside the tag, because it functions as a placeholder until it's overwritten.
The replacement-principle #
When you are working inside a template that uses {% extends %}
, you can only influence the base template by using block tags. Each line you write inside a template that extends, should be wrapped in blocks.
Overwriting attributes #
Overwriting attributes is quite advanced, and there is a good chance you will have no need for it. But in case you do, let's use the same above example.
If we want to add a class to the attributes of node--full.html.twig
, we should also use Twig blocks. We can do that by using a Twig block in node.html.twig
that is defined before the attributes
are printed.
{%
set classes = [
'node',
'node--type-' ~ node.bundle|clean_class,
]
%}
{% block before %}{% endblock %}
<article{{ attributes.addClass(classes) }}>
<div{{ content_attributes }}>
{% block content %}
{{ content }}
{% endblock %}
</div>
</article>
{% extends 'node.html.twig' %}
{% block before %}
{{ attach_library(‘my-theme/node--full') }}
{% set attributes = attributes.addClass('my-shiny-class') %}
{% endblock %}
The above would result in only node--full items having the my-shiny-class
.