0

I am trying to override the default standard_layout.html.twig file from the SonataAdminBundle. I want the replacement template to extend my ::base.html.twig. Essentially, I have cut and pasted Sonata blocks into the appropriate blocks in my base template. This works fine on the main dashboard. But as soon as I click a link to list or add any entity, I get an error indicating that one of the variables declared at the top of standard_layout.html.twig is undefined in standard_layout.html.twig. If I move the {% set _breadcrumb = block('breadcrumb' %} declaration (for example) from the top of the file to the line before the variable is used, the error goes away and the next called variable causes the same error.

Here is my current standard_layout.html.twig file:

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

//HERE ARE THE PROBLEM VARIABLES   
{% set _preview      = block('preview') %}
{% set _form         = block('form') %}
{% set _show         = block('show') %}
{% set _list_table   = block('list_table') %}
{% set _list_filters = block('list_filters') %}
{% set _side_menu    = block('side_menu') %}
{% set _content      = block('content') %}
{% set _title        = block('title') %}
{% set _breadcrumb   = block('breadcrumb') %}
{% set _actions      = block('actions') %}

{% block stylesheets %}
        {%  stylesheets filter='cssrewrite'
            '@jqueryui_css'
            '@bootstrapeditable_css'
            '@main_css'
        %}
            <link rel="stylesheet" href="{{ asset_url }}" />
        {% endstylesheets %}

    {% if admin_pool is defined and admin_pool.getOption('use_select2') %}
        {% stylesheets  '@select2_css' filter='cssrewrite'%}
            <link rel="stylesheet" href="{{ asset_url }}" />
        {% endstylesheets %}
        <style>
            div.select2-container {
                margin-left: 0px !important;
            }
            div.select2-drop ul {
                margin: 0px !important;
            }
        </style>
    {% endif %}
{% endblock stylesheets %}

{% block title %}
    {{ 'ACC'|trans({}, 'SonataAdminBundle') }}
    {% if _title is not empty %}
        {{ _title|raw }}
    {% else %}
        {% if action is defined %}
            -
            {% for menu in admin.breadcrumbs(action) %}
                {% if not loop.first  %}
                    &gt;
                {% endif %}
                {{ menu.label }}
            {% endfor %}
        {% endif %}
    {% endif%}
{% endblock title %}

{% block body_attributes %}class="sonata-bc {% if _side_menu is empty %}sonata-ba-no-side-menu{% endif %}"{% endblock body_attributes%}

{% block logo %}
    <a href="{{ url('sonata_admin_dashboard') }}" id="navtitle">
        {{ admin_pool.title }}
    </a>
{% endblock %}

{% block navlinks %}
    {% block sonata_nav_menu_before %}{% endblock sonata_nav_menu_before%}
    {% block sonata_nav_menu %}
        {% block top_bar_before_nav %} {% endblock %}
        <ul>
            {% block sonata_top_bar_nav %}
                {% if app.security.token and is_granted('ROLE_SONATA_ADMIN') %}
                    {% for group in admin_pool.dashboardgroups %}
                        {% set display = (group.roles is empty or is_granted('ROLE_SUPER_ADMIN') ) %}
                        {% for role in group.roles if not display %}
                                    {% set display = is_granted(role) %}
                        {% endfor %}

                        {# Do not display the group label if no item in group is available #}
                        {% set item_count = 0 %}
                        {% if display %}
                            {% for admin in group.items if item_count == 0 %}
                                {% if admin.hasroute('list') and admin.isGranted('LIST') %}
                                    {% set item_count = item_count+1 %}
                                {% endif %}
                            {% endfor %}
                        {% endif %}

                        {% if display and (item_count > 0) %}
                            <li class="dropdown">
                                <a href="#" class="dropdown-toggle" data-toggle="dropdown">{{ group.label|trans({}, group.label_catalogue) }} <span class="caret"></span></a>
                                <ul class="dropdown-menu">
                                    {% for admin in group.items %}
                                        {% if admin.hasroute('list') and admin.isGranted('LIST') %}
                                            <li{% if app.request.get('_sonata_admin') == admin.code %} class="active"{% endif %}><a href="{{ admin.generateUrl('list')}}">{{ admin.label|trans({}, admin.translationdomain) }}</a></li>
                                        {% endif %}
                                    {% endfor %}
                                                    </ul>
                                                </li>
                                            {% endif %}
                    {% endfor %}
                {% endif %}
            {% endblock %}

        </ul>
        {% block top_bar_after_nav %}{% endblock %}
        {% block sonata_top_bar_search %}
            {% if app.security.token and is_granted('ROLE_SONATA_ADMIN') %}
                <form action="{{ url('sonata_admin_search') }}" method="GET"  class="navbar-form navbar-left" role='search'>
                            <div class="input-append">
                                <input type="text" name="q" value="{{ app.request.get('q') }}" class="form-control search-query" placeholder="{{ 'search_placeholder'|trans({}, 'SonataAdminBundle') }}">
                    </div>
                </form>
            {% endif %}
        {% endblock sonata_top_bar_search%}
        {% if admin_pool is defined %}
            <span class="navbar-right user_block">{% include admin_pool.getTemplate('user_block') %}</span>
        {% endif %}
    {% endblock sonata_nav_menu%}
    {% block sonata_nav_menu_after %}{% endblock %}
{% endblock navlinks %}


    {% block content %}
    {% block sonata_page_content %}
        {% block notice %}
            {% include 'SonataCoreBundle:FlashMessage:render.html.twig' %}
        {% endblock %}
        <div class="row-fluid">
            {% block sonata_breadcrumb %}
                {% if _breadcrumb is not empty or action is defined %}
                    <div class="span6">
                        <ul class="breadcrumb">
                            {% if _breadcrumb is empty %}
                                {% if action is defined %}
                                    {% for menu in admin.breadcrumbs(action) %}
                                        {% if not loop.last  %}
                                            <li>
                                                {% if menu.uri is not empty %}
                                                    <a href="{{ menu.uri }}">{{ menu.label }}</a>
                                                {% else %}
                                                    {{ menu.label }}
                                                {% endif %}
                                                <span class="divider">/</span>
                                            </li>
                                        {% else %}
                                            <li class="active">{{ menu.label }}</li>
                                        {% endif %}
                                    {% endfor %}
                                {% endif %}
                            {% else %}
                                {{ _breadcrumb|raw }}
                            {% endif %}
                        </ul>
                    </div>
                {% endif %}
            {% endblock sonata_breadcrumb %}

            {% if _actions is not empty %}
                <div class="span4 offset2">
                    {{ _actions|raw }}
                </div>
            {% endif %}
        </div>
        <div class="row-fluid">
            {% if _side_menu is not empty %}
                <div class="sidebar span2">
                    <div class="well sonata-ba-side-menu" style="padding: 8px 0;">{{ _side_menu|raw }}</div>
                </div>
            {% endif %}

            <div class="content {{ _side_menu is not empty ? ' span10' : 'span12' }}">
                {% block sonata_admin_content %}
                    {% if _preview is not empty %}
                        <div class="sonata-ba-preview">{{ _preview|raw }}</div>
                    {% endif %}
                    {% if _content is not empty %}
                        <div class="sonata-ba-content">{{ _content|raw }}</div>
                    {% endif %}
                    {% if _show is not empty %}
                        <div class="sonata-ba-show">{{ _show|raw }}</div>
                    {% endif %}
                    {% if _form is not empty %}
                        <div class="sonata-ba-form">{{ _form|raw }}</div>
                    {% endif %}
                    {% if _list_table is not empty or _list_filters is not empty %}
                        <div class="row-fluid">
                            <div class="sonata-ba-list {% if _list_filters|trim %}span10{% else %}span12{% endif %}">
                                {{ _list_table|raw }}
                            </div>
                            {% if _list_filters|trim %}
                                <div class="sonata-ba-filter span2">
                                    {{ _list_filters|raw }}
                                </div>
                            {% endif %}
                        </div>
                    {% endif %}
                {% endblock sonata_admin_content%}
            </div>
        </div>
        {% block footer %}
            <div class="row-fluid">
                <div class="span2 offset10 pull-right">
                    <span class="label"><a href="http://sonata-project.org" rel="noreferrer" style="text-decoration: none; color: black">Sonata Project</a></span>
                </div>
            </div>
        {% endblock %}
    {% endblock %}
{% endblock content %}
{% block javascripts %}
            <script>
                window.SONATA_CONFIG = {
                    CONFIRM_EXIT: {% if admin_pool is defined and admin_pool.getOption('confirm_exit') %}true{% else %}false{% endif %},
                    USE_SELECT2: {% if admin_pool is defined and admin_pool.getOption('use_select2') %}true{% else %}false{% endif %}
                };
                window.SONATA_TRANSLATIONS = {
                    CONFIRM_EXIT:  '{{ 'confirm_exit'|trans({}, 'SonataAdminBundle')|escape('js') }}'
               };
            </script>
            {% javascripts
                '@jquery_js'
                '@jqueryui_js'
                '@bootstrap_js'
                '@bootstrapeditable_js'
                '@jqueryform_js'
                filter='?yui_js'
            %}
                <script src="{{ asset_url }}"></script>
            {% endjavascripts %}


            {% if admin_pool is defined and admin_pool.getOption('use_select2') %}
                {% javascripts '@select2_js' %}<script src="{{ asset_url }}"></script>{% endjavascripts %}
            {% endif %}


            {% if admin_pool is defined and admin_pool.getOption('confirm_exit') %}
                {% javascripts '@confirmExit_js' %}<script src="{{ asset_url }}"></script>{% endjavascripts %}
            {% endif %}
            <script src="{{ asset('bundles/sonataadmin/base.js') }}"></script>
{% endblock %}

My conclusion is that the variables set at the top of the file are not in scope when called from a child template.

Possible clues:

  • when I look at the block profiler for the dashboard page it shows that the usual event blocks (sonata.admin.dashboard.top and sonata.admin.dashboard.bottom) and real block (sonata.admin.block.admin_list) are called twice each instead of once as happens when using the default template. I don't know if this is significant or not.
  • the sidebar on the dashboard does not render with my new template because _sidebar is empty even though it is not empty when using the default template.

What do I need to change?

dnagirl
  • 20,196
  • 13
  • 80
  • 123
  • May I ask you why you want to extend from your own `::base.html.twig`? Why not just extend from the `standard_layout.html.twig` and override the parts you want? What I would do is override the SonataAdminBundle with my own custom admin bundle, copy the `standard_layout.html.twig` and place it in the same folder structure but in your custom bundle. That way it will override it, now change the blocks you want to change. Pretty sure it will work alright then. – Geert Wille Feb 11 '14 at 18:34
  • @GeertWille: mainly because I'm trying to comply with DRY and a lot of the standard_layout.html.twig (basic structure, asset inclusion, etc.) is already present in my ::base.html.twig. I *can* just copy the file to app/SonataAdminBundle/views and edit it to suit without extending `::base.html.twig` and it *will* work. But it does mean that if I change the structure of my `::base.html.twig`, I'll also have to make those changes in my `standard_layout.html.twig`. – dnagirl Feb 11 '14 at 20:33
  • is your `base.html.twig` for front-end? Because I really don't get the point why you would use a complete new file for creating the back-end layout... Can you give a little bit more context about your project? – Geert Wille Feb 11 '14 at 20:37
  • @GeertWille: my application is for managing data so pretty much all logged in users have some kind of privileged role. So there isn't really a front and back end, *per se*. There's just existing code and SonataAdmin that needs to look like existing code. – dnagirl Feb 12 '14 at 02:53

0 Answers0