New in Symfony 3.4: Improved the overriding of templates
Contributed by
Yonel Ceruto
in #24179,
#24264
and #24064.
In Symfony 3.4 we've deprecated bundle inheritance and in Symfony 4.0 we no longer recommend to use bundles for your own code, but overriding templates from third-party bundles is still a common need. That's why in Symfony 3.4 we've improved the overriding of templates in preparation for Symfony 4.
New overriding directory¶
In Symfony 2 and 3 applications, third-party bundle templates were overridden in
the app/Resources/<BundleName>/views/
directory. In Symfony 4 this directory
would have been moved to src/
, which doesn't look nice to store templates
now that we have a templates/
directory at the project root.
Therefore, in Symfony 3.4 we've created a new directory to override bundle
templates: templates/bundles/<BundleName>/
. For example, if you want to
customize error pages in a Symfony application:
1 2 3 4 5 6 7 | {# Symfony 3.3 #}
{# app/Resources/TwigBundle/views/Exception/error404.html.twig #}
Page Not Found!
{# Symfony 3.4 #}
{# templates/bundles/TwigBundle/Exception/error404.html.twig #}
Page Not Found!
|
Overriding and extending templates¶
Sometimes you want to override a third-party bundle template but reuse most of
its contents, to avoid code duplication. Imagine that you want to override and
extend the layout.html.twig
template from FOSUserBundle:
1 2 3 | {# templates/bundles/FOSUserBundle/layout.html.twig #}
{% extends '@FOSUser/layout.html.twig' %}
{# ... this doesn't work ... #}
|
If you try this example, you'll see "reached nested level" error because the simultaneous overriding and extending is similar to an infinite loop. In Symfony 3.4 we solved this problem creating a new and exclusive Twig namespace for each bundle.
The new namespace is the same as before but adding !
before the bundle name.
In this case, @FOSUser
refers to the normal Twig namespace which can include
third-party templates and your own overridden templates and @!FOSUser
refers
exclusively to the templates defined by the third-party bundle (no matter if
they have been overridden, you always get the original templates).
Using this new namespace, it's trivial to solve the previous problem:
1 2 3 | {# templates/bundles/FOSUserBundle/layout.html.twig #}
{% extends '@!FOSUser/layout.html.twig' %}
{# ... this works as expected ... #}
|
Better debug:twig
command¶
Finally, to make these changes easier to debug, the debug:twig
command now
displays the full list of Twig namespaces and their associated file paths in the
same prioritized order used by Symfony.
As with any Open-Source project, contributing code or documentation is the most common way to help, but we also have a wide range of sponsoring opportunities.
New in Symfony 3.4: Improved the overriding of templates symfony.com/index.php/blog/new-in-symfony-3-4-improved-the-overriding-of-templates
Tweet thisComments
These features will allow alot of bundles to be overridable in a much better way! Defining standard blocks has never become so easy :)
Comments are closed.
To ensure that comments stay relevant, they are closed for old posts.
Pierre-Charles Bertineau said on Oct 9, 2017 at 11:49 #1