Inheritance

After setting up aD8 site and going into the theme folders for Bartik and Classy you'll notice that there are lot of templates in D8. This is because Drupal 8 really takes advantage of Twig’s template inheritance capabilities. Twig allows templates to be extended, included and embedded into other templates which allows for a very atomic approach to site building. Extends, Include, and Embed are quite similar, but there are some key points to be aware of.

Use Extends to inherit a parent twig template

Extends brings in the parent template (the one being extended) into the child template. No content outside of blocks defined in the parent template will be allowed in the child template. In a parent paragraphs template (paragraph.html.twig) there are some default classes and html structure you'll want to set that will be used in every paragraph bundle you create:

In a child text paragraph bundle (paragraph--text.html.twig) you would extend the parent template (paragraph.html.twig) and switch out the block content so the child gets the classes you want from the parent but uses its own content.

Since the parent template is being inherited with extends, all content in the child template must be inside a block defined in the parent. Content outside of parent blocks (as shown below) will not be allowed and will throw a Twig error on your site.

Use include to insert one template into another

Include also inherits content of a file, but also allows variables from the current template to replace those from the parent template. Include also differs from extends in that template you are including is included directly where the call is placed in the child. Think of it this way—extends is like bringing a parent template into a child template and changing some of the content of the parent in the child. Include brings a child template into a parent by inserting the entire child template into the parent a specific point. You could also insert an entire parent into a child and replace variables but not content.

The biggest advantage of this in my opinion is including templates from outside a Drupal site into a Drupal site or from one entity type to another. We use Pattern Lab as part of our approach to theming but while our Pattern Lab instance lives inside our Drupal theme it is technically outside of the Drupal site structure so it cannot use variables like {{ content.field_long_text }}. It even has a different suffix for files: paragraph.twig instead of paragraph.html.twig.

To get around that we use include instead of extends and use the ‘with’ function to replace variables from Pattern Lab in Drupal. The parent template paragraph--text.twig in Pattern Lab extends the Pattern Lab paragraphs.twig template to get the html structure then adds example {{ text }} variable content defined in a yml file. To get the final Pattern Lab example output.

Then in Drupal, the paragraph--text.html.twig file uses include to bring in the entire content of the Pattern Lab paragraph-text.twig file and replaces the {{ text }} variable with the Drupal output of the long text field in my text paragraph bundle {{ content.field_long_text }}.

The Drupal template uses the Component Libraries module to find the Pattern Lab Twig template and includes all the Pattern Lab structure but uses the Drupal text field for content.

Embed a twig template to replace variables and override parent blocks

Embed combines include and extends. You can embed a template in another template and replace the variables using 'with' and switch out block content from the child template you are embedding into the parent (or vice versa).

An example of this would be creating paragraphs demo content in Pattern Lab and bringing it into Drupal. Since Pattern lLb doesn’t have modules, we have to hand build the paragraph's HTML structure then exclude it in Drupal (since we don’t want the hand-built paragraphs html structure and Drupal’s).

In Pattern Lab the text.twig template gives basically the same HTML structure that the final Drupal paragraph bundle does but uses some dummy text from a yml file.

The Drupal template paragraph--text.html.twig both extends and embeds templates. It extends the Drupal paragraph.html.twig to add bring global classes and html structure into the text bundle template and it embeds the Pattern Lab text.twig template in place of the parent paragraph.html.twig content block while replacing the {{ text }} variable with the Drupal {{ content.field_long_text }} variable. Adding comments to the plwidgetopen and plwidgetclose blocks prevents them from printing the paragraph structure created in Pattern Lab.

With the setup above, you can theme the Drupal text bundle directly in Pattern Lab and have whatever structure is built around the text variable be reflected both there and around the Drupal long text field as well.