Edit on GitHub
Jump to docs navigation

Templating / Template inheritance

Note: You are currently reading the documentation for Bolt 3.7. Looking for the documentation for Bolt 5.2 instead?

To quote the Twig documentation "The most powerful part of Twig is template inheritance", and "[it] sounds complicated but it is very basic"

By harnessing this power, Twig allows you to build a base "master", or "skeleton", template for your Bolt site, that contains all the common elements for your site. You can also define "blocks" that child templates can override.

For example you might want your pages ContentType to display an image at the top of the sidebar, but still use the same layout as the rest of the site.

Easy!

Let's take a closer look at this example in the sections below.

Parent templates

A parent template is just a Twig template file that contains block tags. All the block tag itself does is to tell Twig that a child template may override that portion of the template contained inside the block.

Let's call our master template _master.twig, and assume it is located in the root of your site's theme directory, e.g. public/theme/your-theme/.

Inside our _master.twig file, you will see a cut-down version of your HTML <body>, you'll also notice that there are two block tags; "content" & "sidebar". These would normally contain your beautifully designed layout, but for the sake of simplicity we've just shown a template comment in the example below.

    <body>
        <div id="content">
        {% block content %}
            {# Twig logic to display your content goes here #}
        {% endblock %}
        </div>

        <div id="sidebar">
        {% block sidebar %}
            {# Twig logic to display your sidebar goes here #}
        {% endblock %}
        </div>
    </body>

Any child template that extends this one can override the content of these blocks by defining their own block of the same name.

Child templates

A child template inherits a parent template's layout by using the extends tag followed by the template file name of the parent. If your child template was to contain only the extends tag, it would just render the extended parent template.

Overriding sections of the parent template is done with a block tag name after a matching tag name in the parent template.

Using our example above, now in your pages.twig file that you've specified in your ContentType, you would simply extend the master template, to inherit your beautifully designed layout, and add a block called "sidebar".

So you entire pages.twig file would look like:

{% extends '_master.twig' %}

{% block sidebar %}
    <img src="{{ record.sidebar_image|thumbnail(250, 250) }}">

    {{ parent() }}
{% endblock %}

Notice at the end of the sidebar block in your new pages.twig template a Twig parent() function, this optional addition to a child block tells Twig "Put the parent block's HTML here!".

In other words you can meticulously create your beautifully designed layout, yet quickly & easily extend it for a specific purpose, with just a few lines of Twig.

How awesome is that!

Reusing blocks

Another flexible feature of Twig blocks is when it comes to reusing them, as you can create them in other templates. A factory of sorts.

Let's say that you want one consistent HTML layout for any images displayed. You could add another block to your pages.twig file.

But wait, I want my kittens ContentType to use my new sidebar_image block too!

Good news friendly Bolt template designer, you can create special template files that contain only Twig blocks that you access via the special Twig function, block().

Let's assume we've created _blocks.twig, and moved the sidebar_image block there. It would look like:

{% block sidebar_image %}
    <div class="image">
        <img src="{{ record.sidebar_image|thumbnail(250, 250) }}">
    </div>
{% endblock %}

Now we just tell Twig that we're going to "use" your _blocks.twig template by adding {% use '_blocks.twig' %} to pages.twig.

Your pages.twig file would then look like this:

{% extends '_master.twig' %}
{% use '_blocks.twig' %}

{% block sidebar %}
    {{ block('sidebar_image') }}

    {{ parent() }}
{% endblock %}

Blocks & variables

Another common use-case that you might encounter, is that you want to define a block used by several different ContentTypes, but with completely different field names.

This is where Twig's with tag comes to the rescue, to wrap around a block and tell Twig what variables to use.

In our example _blocks.twig file, we change the block to expect a variable called image.

{% block sidebar_image %}
    <div class="image">
        <img src="{{ image|thumbnail(250, 250) }}">
    </div>
{% endblock %}

Then in your pages.twig file, put your sidebar_image block inside a with control structure.

{% extends '_master.twig' %}
{% use '_blocks.twig' %}

{% block sidebar %}
    {% with {'image': record.sidebar_image} %}
    {{ block('sidebar_image') }}
    {% endwith %}

    {{ parent() }}
{% endblock %}

… and in your kittens.twig template, the same thing except with the value of the record's cutest_kitten field:

{% extends '_master.twig' %}
{% use '_blocks.twig' %}

{% block sidebar %}
    {% with {'image': record.cutest_kitten} %}
    {{ block('sidebar_image') }}
    {% endwith %}

    {{ parent() }}
{% endblock %}


Edit this page on GitHub
Couldn't find what you were looking for? We are happy to help you in the forum, on Slack or on Github.