Fork me on GitHub

embed

embed

The embed tag allows you to insert the rendered output of another template directly into the current template, while overriding some of its blocks. It effectively combines the behavior of include with that of extends for creating reusable, yet flexible, template fragments, or for composing micro-layouts.

For example, imagine building a template card.peb as a reusable component in your layout. All cards should have the same markup, but the content can change drastically throughout your site. card.peb might then look like:

// card.peb
<div class="card">
    {% block cardContent %}
    {% endblock %}
</div>

Now, you can include that template elsewhere in your layout, and override the cardContent block to "inject" rich content into that template at the call-side. For example, you may want to display a grid of your store's most popular products as cards, with the last card linking to the full catalog. Embedding card.peb and overriding the cardContent block ensures that the markup for both types of cards are always the same, even though what's displayed on each card is quite different.

// layout.peb

{% for product in popularProducts %}
    {% embed 'card.peb' %}
        {% block cardContent %}
            <h1>{{ product.name }}</h1>
            <p>{{ product.description }}</p>
        {% endblock %}
    {% endembed %}
{% endfor %}

{% embed 'card.peb' %}
    {% block cardContent %}
        <a href="...">See all 100+ products</a>
    {% endblock %}
{% endembed %}

Embeds can be used multiple times in the same template, and may also be used in a template that itself extends another. Each template will then maintain its own block hierarchy. In other words, block overridden within the body of the embed tag will not accidentally override those defined in the main template, and likewise blocks defined in the main template or its parent templates will not get mixed with those in the embedded template or its parent templates.

// main.peb
{% extends 'base.peb' %}

{% block mainContent %}
    {{ parent() }} {# renders mainContent block from base.peb #}
    {{ block('footer') }} {# renders footer block from base.peb, the global page footer #}
    
    {% embed 'card.peb' %}
        {% block mainContent %}
            {{ parent() }} {# renders mainContent block from card.peb #}
            {{ block('footer') }} {# renders footer block from card.peb, the card footer (not the global page footer) #}
        {% endblock %}
    {% endembed %}
{% endblock %}

Scope

Embedded templates will have access to the same variables that the current template does.

Top Content
{% embed "advertisement" %}{% endembed %}
Bottom Content
{% embed "footer" %}{% endembed %}

You can add additional variables to the context of the embedded template by passing a map after the with keyword. The embedded template will have access to the same variables that the current template does plus the additional ones defined in the map passed after the with keyword:

{% embed "advertisement" with {"foo":"bar"} %}
    {% block title %}
        Ad with title
    {% endblock %}
    {% block content %}
        Ad with title
    {% endblock %}
{% endembed %}

Dynamic embed

The embed tag will accept an expression to determine the template to embed at runtime. For example:

{% embed admin ? 'adminFooter' : 'defaultFooter' %}
{% endembed %}