Skip to content
This repository has been archived by the owner on Dec 1, 2021. It is now read-only.

Latest commit

 

History

History
173 lines (148 loc) · 6.07 KB

3.4-twig-templates.md

File metadata and controls

173 lines (148 loc) · 6.07 KB

Overriding Twig Templates

From Working With Twig Templates:

Drupal allows you to override all of the templates that are used to produce HTML markup so that you can fully control the markup that is being output within a custom theme. There are templates for each page element ranging from the high level HTML to small fields.

Twig Debug Mode

To enable Twig Debug Mode:

  • If sites/default/services.yml exists proceed to next step. Otherwise copy sites/default/default.services.yml to sites/default/services.yml.
  • Edit sites/default/services.yml.
  • Under twig.config section, set debug: true.
  • Clear cache either by clicking Clear all caches on /admin/config/development/performance or running drush cr on the command line.

Once enabled you can use dump() to output all available variables or output contents of a particular variables:

All variables:
{{ dump() }}

Contents of `foo`:
{{ dump(foo) }}

Theme Hook Suggestions

When Twig debug mode is enabled, Drupal will suggest a few possible ways to override the markup and preprocessor for particular content blocks. This will be shown in the page HTML as comments.

For example:

<!-- THEME DEBUG -->
<!-- THEME HOOK: 'block' -->
<!-- FILE NAME SUGGESTIONS:
   * block--substable-content.html.twig
   * block--system-main-block.html.twig
   * block--system.html.twig
   x block.html.twig
-->

If you wish you make your own recommendations, you hook into the preprocessor for this particular element and make your own additional suggestions.

<?php
/**
 * Implements hook_theme_suggestions_block_alter() for block templates.
 */
function substable_theme_suggestions_block_alter(array &$suggestions, array $variables) {
  $suggestions[] = 'block__substable';
  $suggestions[] = 'block__substable__' . $variables['elements']['#id'];
}
?>

If you clear your cache and look again at the comments you should see the new suggestion in the list.

<!-- THEME DEBUG -->
<!-- THEME HOOK: 'block' -->
<!-- FILE NAME SUGGESTIONS:
   * block--substable--substable-content.html.twig
   * block--substable.html.twig
   * block--substable-content.html.twig
   * block--system-main-block.html.twig
   * block--system.html.twig
   x block.html.twig
-->

Now you can create templates/block--substable.html.twig or block--substable--substable-content.html.twig, to override core block behavior.

The earlier a file name is in the file name suggestions above, the higher priority it will have. So by pushing to the end of the suggestions array, we are setting our template suggestions to have the highest possible priority.

Make sure you clear your cache after creating any new template files.

Including Twig Templates

From twig.symfony.com - include:

The include statement includes a template and returns the rendered content of that file into the current namespace:

{% include 'header.html' %}
    Body
{% include 'footer.html' %}

Included templates have access to the variables of the active context.

You can add additional variables by passing them after the with keyword:

{# template.html will have access to the variables from the current context and the additional ones provided #}
{% include 'template.html' with {'foo': 'bar'} %}

{% set vars = {'foo': 'bar'} %}
{% include 'template.html' with vars %}

You can disable access to the context by appending the only keyword:

{# only the foo variable will be accessible #}
{% include 'template.html' with {'foo': 'bar'} only %}
{# no variables will be accessible #}
{% include 'template.html' only %}

Extending Twig Templates

From twig.symfony.com - extends:

The extends tag can be used to extend a template from another one. Let's define a base template, base.html, which defines a simple HTML skeleton document:

<!DOCTYPE html>
<html>
    <head>
        {% block head %}
            <link rel="stylesheet" href="style.css" />
            <title>{% block title %}{% endblock %} - My Webpage</title>
        {% endblock %}
    </head>
    <body>
        <div id="content">{% block content %}{% endblock %}</div>
        <div id="footer">
            {% block footer %}
                &copy; Copyright 2011 by <a href="http://domain.invalid/">you</a>.
            {% endblock %}
        </div>
    </body>
</html>

In this example, the block tags define four blocks that child templates can fill in.

All the block tag does is to tell the template engine that a child template may override those portions of the template.

A child template might look like this:

{% extends "base.html" %}

{% block title %}Index{% endblock %}
{% block head %}
    {{ parent() }}
    <style type="text/css">
        .important { color: #336699; }
    </style>
{% endblock %}
{% block content %}
    <h1>Index</h1>
    <p class="important">
        Welcome on my awesome homepage.
    </p>
{% endblock %}

The extends tag is the key here. It tells the template engine that this template "extends" another template. When the template system evaluates this template, first it locates the parent. The extends tag should be the first tag in the template.

Note that since the child template doesn't define the footer block, the value from the parent template is used instead.

Additional Resources