Categories
Software Development Web Development

Symfony 5+ Twig templates don’t forget to call the parent

Twig templates use inheritance and allows you to create named sections like this.


<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <link rel='icon' href="{{ asset('images/favicon.ico') }}" type='image/x-icon' >
    {% block head_extra %}{% endblock %}
    <title>{% block title %}{{ title }}{% endblock %}</title>
    {% block stylesheets %}
        {# 'app' must match the first argument to addEntry() in webpack.config.js #}
        {{ encore_entry_link_tags('app') }}
    {% endblock %}
</head>
<body>

<main>
    <div class="container">
       {% block navbar %}{{ include('_nav_bar.html.twig') }}{% endblock %}
        {% block body %}{% endblock %}
        {% block javascripts %}
            {# these files are needed for getting url routes in javascript  #}
            <script src="{{ asset('bundles/fosjsrouting/js/router.js') }}"></script>
            <script src="{{ path('fos_js_routing_js', { callback: 'fos.Router.setData' }) }}"></script>
            {# 'app' must match the first argument to addEntry() in webpack.config.js #}
            {{ encore_entry_script_tags('app') }}
        {% endblock %}

        {% block javascript_extra %}{% endblock %}
    </div>
</main>
</body>
</html>

And then you can reuse/inherit this template in another template like this.

{% extends 'base.html.twig' %}
{% block title %}Register{% endblock %}

{% block stylesheets %}
{{ parent() }}

{% endblock %}
{% block body %}

{{ form_start(registrationForm) }}
{{ form_errors(registrationForm) }}
{{ form_row(registrationForm.email) }}
{{ form_row(registrationForm.emailMatch) }}
{{ form_row(registrationForm.plainPassword) }}
{{ form_row(registrationForm.passwordMatch) }}
{{ form_row(registrationForm.userAlias) }}
{{ form_row(registrationForm.agreeTerms) }}

{{ form_end(registrationForm) }}

{% endblock %}
{% block javascript_extra %}

{{ encore_entry_script_tags('registration') }}

{% endblock %}

Notice the extends keyword and notice this section

{% block stylesheets %}
{{ parent() }}

{% endblock %}

Notice the use of the “parent” keyword here.

{% block stylesheets %} {{ parent() }} {% endblock %}

Any other css code you want included must come after the parent call like this.


{% block stylesheets %}
    {# 'app' must match the first argument to addEntry() in webpack.config.js #}
    {{ parent() }}
    {{ encore_entry_link_tags('editAboutUser') }}
    {{ encore_entry_link_tags('sogiDraw') }}
{% endblock %}

If I didn’t call “parent()” above then only the CSs for editAboutUser and sogiDraw would be included app would not be included. The CSS for app which is called in the base template in the stylesheets section would not be included without the call to parent().

So if some of your CSS is not working, then the reason is you probably forgot to call parent. This call to parent is saying “Include what was in the parent stylesheet section”. Otherwise without the call you will be missing Styles and be saying WTF?

Don’t forget to call parent