Extending Twig Templates in Drupal 8

Have you ever needed a variation of a template in a theme where each template has a lot in common? For example the main page template and frontpage template.

In Drupal 7, you’d have these two templates:

  • page.tpl.php
  • page--front.tpl.php

The changes you make for the frontpage version might be relatively minor, so there will be a lot in common with these two templates, with often only small variances. There will be a lot of duplicate code. If you make changes to that code, you need to change it in both templates.

You might find this with other templates you create as well and you end up with a lot of templates that duplicate code. This makes it harder to maintain over the long term.

Drupal 8

In Drupal 8, Twig allows you to eloquently extend a template and only change the part that you need. The rest of the code remains in the parent template. There is no code duplication!

You need two things to extend templates:

  1. Blocks
  2. Extends

Blocks

If you add a Twig block to a template, the code inside it will be swappable in the child template (the one that extends it).

There is some confusion with the name block, as Drupal also uses blocks as part of the core system. But in this context, they are entirely different things.

Twig’s documentation:

“Blocks are used for inheritance and act as placeholders and replacements at the same time. They are documented in detail in the documentation for the Extends tag.”

Extends

Twig’s Extends allows you to inherit all the code from a parent template without having to duplicate it AND replaces parts of it (the parts in Twig blocks).

You can only replace parts that are Twig Blocks. If you try and replace anything else in the parent template, you will get an error.

Quick Example

Let’s say you have a left side bar in your main page template and you decide that you don’t want to display that on the front page. One way to do that is to create a front page specific page template that extends the main page template and then hide the side bar.

Steps

In your page.html.twig file, turn your left sidebar into a Twig Block.

For example, if you currently have something like this:

{{ page.left }}

Turn it into:

{% block left %}
  {{ page.left }}
{% endblock %}

This makes it swappable in the child template as it is now a Twig block.

Create the child template by creating a file called page--front.html.twig. This will automatically be used by Drupal on the front page.

At the top of the file, add a line state that it extends page.html.twig:

{% extends "page.html.twig" %}

To hide the sidebar, all you need to do is declare the block without nothing inside it:

{% block left %}{% endblock %}

So the full page-front.html.twig is:

{% extends "page.html.twig" %}
{% block left %}{% endblock %}

And everything else is inherited from the parent template.

Comments

If a need new region in front-template, I need to duplicate the system page-template ... or I have another solution?
Thanks.

Blair Wadman's picture

One way would be to declare a Twig block for it in the page.html.twig template with nothing inside it, and then in the page--front.html.twig template, override it with the actual region.

Thank, and thanks for the new post about this subject :) I will try right now!

Your blogs are always a great source of leaning new thing about Drupal 8.
Thanks a lot..!!!

Blair Wadman's picture

You're most welcome!

New comments for this tutorial have been turned off.