twig tutorial - Comparison of Include and Extends in Twig - twig php - twig template



Comparison of Include, Extends, Use, Macro, Embed

  • There are various types of inheritance and code reuse in Twig:

Include

  • The main goal is code reuse. Consider using header.html.twig & footer.html.twig inside base.html.twig as an example.

header.html.twig

<nav>
   <div>Homepage</div>
   <div>About</div>
</nav>

base.html.twig

{% include 'header.html.twig' %}
<main>{% block main %}{% endblock %}</main>

Extends

  • The main goal is vertical inheritance. Consider extending base.html.twig inside homepage.html.twig and about.html.twig as an example.

base.html.twig

{% include 'header.html.twig' %}
<main>{% block main %}{% endblock %}</main>

homepage.html.twig

{% extends 'base.html.twig' %}

{% block main %}
<p>You are at the homepage</p>
{% endblock %}

about.html.twig

{% extends 'base.html.twig' %}

{% block main %}
<p>You are at the about page</p>
{% endblock %}

Use

  • The main goal is horizontal reuse. Consider using sidebar.product.html.twig inside single.product.html.twig (extends product.layout.html.twig) and single.service.html.twig (extends 'service.layout.html.page') pages. (it's like macros, but for blocks)

sidebar.html.twig

<aside>{% block sidebar %}{% endblock %}</aside>

single.product.html.twig

{% extends 'product.layout.html.twig' %}

{% use 'sidebar.html.twig' %}
{% block main %}
<p>You are at the product page for product number 123</p>
{% endblock %}

single.service.html.twig

{% extends 'service.layout.html.twig' %}

{% use 'sidebar.html.twig' %}
{% block main %}
<p>You are at the service page for service number 456</p>
{% endblock %}

Macro

  • The main goal is having reusable markup across many templates with variables. Consider a function which gets some variables and outputs some markup.

profile.service.html.twig

{% import "forms.html.twig" as forms %}

<div>{{ forms.input('username') }}</div>

Embed

  • The main goal is block overriding. It has functionality of both Use & Include together. Consider embedding pagination.html.twig in product.table.html.twig & service.table.html.twig.

pagination.html.twig

<div>
    <div>{% block first %}{% endblock %}</div>
    {% for i in (min + 1)..(max - 1) %}
        <div>{{ i }}</div>
    {% endfor %}
    <div>{% block last %}{% endblock %}</div>
</div>

product.table.html.twig

{% set min, max = 1, products.itemPerPage %}

{% embed 'pagination.html.twig' %}
    {% block first %}First Product Page{% endblock %}
    {% block last %}Last Product Page{% endblock %}
{% endembed %}

service.table.html.twig

{% set min, max = 1, services.itemPerPage %}

{% embed 'pagination.html.twig' %}
    {% block first %}First Service Page{% endblock %}
    {% block last %}Last Service Page{% endblock %}
{% endembed %}

Please note that embedded file (pagination.html.twig here) has access to the current context (min, max variables here). Also you may pass extra variables to the embedded file:

pagination.html.twig

<p>{{ count }} items</p>
<div>
    <div>{% block first %}{% endblock %}</div>
    {% for i in (min + 1)..(max - 1) %}
        <div>{{ i }}</div>
    {% endfor %}
    <div>{% block last %}{% endblock %}</div>
</div>

product.table.html.twig

{% set min, max = 1, products|length %}

{% embed 'pagination.html.twig' with {'count': products|length } %}
    {% block first %}First Product Page{% endblock %}
    {% block last %}Last Product Page{% endblock %}
{% endembed %}

Related Searches to twig tutorial - Comparison of Include and Extends in Twig