What is the difference between use
and include
in Twig?
Documentation:
include
The include
statement includes a template and returns the rendered content of that template into the current one:
{% include 'header.html' %}
Body here...
{% include 'footer.html' %}
use
The use
statement tells Twig to import the blocks defined in blocks.html
into the current template (it's like macros, but for blocks):
blocks.html
{% block sidebar %}{% endblock %}
main.html
{% extends "base.html" %}
{% use "blocks.html" %}
{% block title %}{% endblock %}
{% block content %}{% endblock %}
Possible answer:
I think this should explain the difference:
include
is to get all the code from an external file and import it
into your actual file at the right location of the call.
use
is completely different as it parses the linked file to find a
particular section of code and then overwrites the blocks with the
same name, in your current file, with the one found in this external
file.
include
is like "go find this file and render it with my page here".
use
is "parse this other file to find block definitions to use instead
of my owns defined here".
If use
command finds nothing matching the task, nothing is displayed
at all from this file.
Question
is the explanation correct? are there any other explanations to this difference?
thanks
After months, I am posting an answer for any further reference to this question. I also added some description for extends
& import
& macro
& embed
for more clearance:
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.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.
form.html.twig
{% macro input(name, value, type) %}
<input type="{{ type|default('text') }}" name="{{ name }}" value="{{ value|e }}" }}" />
{% endmacro %}
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 %}