An extension for Twig that allows to defer block rendering.
composer require rybakit/twig-deferred-extension
Note that this extension requires Twig 3 or above. If you need support for older versions of Twig, please refer to the legacy repository.
use Twig\DeferredExtension\DeferredExtension;
use Twig\Environment;
...
$twig = new Environment($loader);
$twig->addExtension(new DeferredExtension());
{% block foo deferred %}
{{ bar }}
{% endblock %}
{% set bar = 'bar' %}
The foo
block will output "bar".
Just for example purposes, first create a global twig variable:
use Twig\Environment;
...
$twig = new Environment($loader);
$twig->addGlobal('assets', new \ArrayObject());
Then build the following set of templates:
{# layout.html.twig #}
<!DOCTYPE html>
<html>
<head>
...
</head>
<body>
{% block content '' %}
{{ assets.append('/js/layout-header.js') }}
{% block javascripts deferred %}
{% for asset in assets %}
<script src="{{ asset }}"></script>
{% endfor %}
{% endblock %}
{{ assets.append('/js/layout-footer.js') }}
</body>
</html>
{# page.html.twig #}
{% extends "layout.html.twig" %}
{% block content %}
{{ assets.append('/js/page-header.js') }}
{% if foo is defined %}
{{ include("subpage1.html.twig") }}
{% else %}
{{ include("subpage2.html.twig") }}
{% endif %}
{{ assets.append('/js/page-footer.js') }}
{% endblock %}
{# subpage1.html.twig #}
{{ assets.append('/js/subpage1.js') }}
{# subpage2.html.twig #}
{{ assets.append('/js/subpage2.js') }}
The resulting html will be the following:
<!DOCTYPE html>
<html>
<head>
...
</head>
<body>
<script src="/js/layout-header.js"></script>
<script src="/js/page-header.js"></script>
<script src="/js/subpage2.js"></script>
<script src="/js/page-footer.js"></script>
<script src="/js/layout-footer.js"></script>
</body>
</html>
{# index.twig #}
{% extends "base.twig" %}
{% block foo %}foo is not deferred anymore{% endblock %}
{% block bar deferred %}bar is deferred now{% endblock %}
{# base.twig #}
{% block foo deferred %}foo is deferred{% endblock %}
{% block bar %}bar is not deferred{% endblock %}
The library is released under the MIT License. See the bundled LICENSE file for details.