{#** * Copyright since 2007 PrestaShop SA and Contributors * PrestaShop is an International Registered Trademark & Property of PrestaShop SA * * NOTICE OF LICENSE * * This source file is subject to the Open Software License (OSL 3.0) * that is bundled with this package in the file LICENSE.md. * It is also available through the world-wide-web at this URL: * https://opensource.org/licenses/OSL-3.0 * If you did not receive a copy of the license and are unable to * obtain it through the world-wide-web, please send an email * to license@prestashop.com so we can send you a copy immediately. * * DISCLAIMER * * Do not edit or add to this file if you wish to upgrade PrestaShop to newer * versions in the future. If you wish to customize PrestaShop for your * needs please refer to https://devdocs.prestashop.com/ for more information. * * @author PrestaShop SA and Contributors * @copyright Since 2007 PrestaShop SA and Contributors * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) *#} {# # This form theme is an implementation of PrestaShop UI kit, it based on the bootstrap4 layout and overrides a few # blocks to match our expected integration of the UI kit. # # This theme uses/extends the basic bootstrap_4_layout meaning the form labels/inputs are displayed one under the other. # Unlike our prestashop_ui_kit.html.twig theme which extends this base kit but uses bootstrap_4_horizontal_layout as a # base, where labels/inputs are displayed horizontally in a column way. #} {# # We need to radio_widget and checkbox_widget from the original bootstrap 4 layout because we need to add form-check-radio # on the last wrapping div which is not possible with the attributes, so we basically copied the content, but then we cannot # use parent() to render the internal widget because it would reuse the one from bootstrap_4_layout and duplicate content. # # So we extract the initial widget from the bootstrap_base_layout to inject them as the internal widget, it is important # to do it before we use bootstrap_4_layout or the base layout will override the blocks from bootstrap_4_layout. # # See https://symfony.com/doc/3.4/form/form_customization.html#referencing-blocks-from-inside-the-same-template-as-the-form #} {% use 'bootstrap_base_layout.html.twig' with radio_widget as base_radio_widget, checkbox_widget as base_checkbox_widget %} {# Use bootstrap4 theme (from the Symfony framework) as default base #} {% use 'bootstrap_4_layout.html.twig' %} {% use '@PrestaShop/Admin/TwigTemplateForm/typeahead.html.twig' %} {% use '@PrestaShop/Admin/TwigTemplateForm/material.html.twig' %} {# overrides from bootstrap_4_layout #} {# Widgets #} {%- block form_widget -%} {% if columns_number is defined %} {% set attr = attr|merge({class: (attr.class|default('') ~ ' form-columns-' ~ columns_number)|trim}) %} {% endif %} {{ parent() }} {{- block('form_help') -}} {%- endblock form_widget -%} {%- block form_widget_simple -%} {{ parent() }} {% include '@PrestaShop/Admin/TwigTemplateForm/form_max_length.html.twig' with {'attr': attr} %} {%- endblock form_widget_simple -%} {% block text_with_unit_widget %}
{{- block('form_widget_simple') -}} {% if form.vars.unit is defined %}
{{ form.vars.unit }}
{% endif %}
{{ block('form_help') }} {% endblock text_with_unit_widget %} {% block ip_address_text_widget %}
{{- block('form_widget_simple') -}}
{{ block('form_help') }} {% endblock ip_address_text_widget %} {# Rows #} {% block form_row -%}
{{- form_label(form) -}} {{- block('form_prepend_alert') -}} {{- form_widget(form) -}} {{- form_errors(form) -}} {{- block('form_external_link') -}} {{- block('form_append_alert') -}}
{% if column_breaker %}
{% endif %} {%- endblock form_row %} {% block widget_type_class %} {% if not compound and form.vars.block_prefixes|length > 2 %} {% spaceless %} {% set index = form.vars.block_prefixes|length - 2 %} {% set widgetType = form.vars.block_prefixes[index] %} {% if widgetType == 'choice' %} {% if not expanded %} {% set widgetType = 'select' %} {% elseif multiple %} {% set widgetType = 'checboxes' %} {% else %} {% set widgetType = 'radio' %} {% endif %} {% endif %} {{ widgetType }}-widget {% endspaceless %} {% endif %} {% endblock %} {# Labels #} {%- block form_label -%} {% if label is not same as(false) -%} {% if not compound -%} {% set label_attr = label_attr|merge({'for': id}) %} {%- endif %} {% if required -%} {% set label_attr = label_attr|merge({'class': (label_attr.class|default('') ~ ' required')|trim}) %} {%- endif %} {% if label is empty -%} {%- if label_format is not empty -%} {% set label = label_format|replace({ '%name%': name, '%id%': id, }) %} {%- else -%} {% set label = name|humanize %} {%- endif -%} {%- endif -%} {% set labelTag = label_tag_name|default('label') %} <{{ labelTag }}{% for attrname, attrvalue in label_attr %} {{ attrname }}="{{ attrvalue }}"{% endfor %}> {% if required %} * {% endif %} {{ translation_domain is same as(false) ? label|raw : label|raw }} {% if label_attr['tooltip'] is defined %} {% set placement = label_attr['tooltip_placement'] is defined ? label_attr['tooltip_placement'] : 'top' %} {% endif %} {% if label_help_box is defined or label_attr['popover'] is defined %} {% set content = label_help_box is defined ? label_help_box : label_attr['popover'] %} {% set placement = label_attr['popover_placement'] is defined ? label_attr['popover_placement'] : 'top' %} {% include '@Common/HelpBox/helpbox.html.twig' with { "placement" : placement, "content": content } %} {% endif %} {% if label_subtitle is defined %}

{{ label_subtitle }}

{% endif %} {%- endif -%} {%- endblock form_label -%} {# Widgets #} {% block textarea_widget -%} {% set attr = attr|merge({class: (attr.class|default('') ~ ' form-control')|trim}) %} {{- parent() -}} {% include '@PrestaShop/Admin/TwigTemplateForm/form_max_length.html.twig' with {'attr': attr} %} {{ block('form_help') }} {%- endblock textarea_widget %} {% block money_widget -%}
{% set prepend = '{{' == money_pattern[0:2] %} {% if not prepend %}
{{ money_pattern|replace({ '{{ widget }}':''}) }}
{% endif %} {{- block('form_widget_simple') -}} {% if prepend %}
{{ money_pattern|replace({ '{{ widget }}':''}) }}
{% endif %}
{{ block('form_help') }} {%- endblock money_widget %} {% block percent_widget -%}
{{- block('form_widget_simple') -}}
%
{%- endblock percent_widget %} {% block datetime_widget -%} {% if widget == 'single_text' %} {{- block('form_widget_simple') -}} {% else -%} {% set attr = attr|merge({class: (attr.class|default('') ~ ' form-inline')|trim}) -%}
{{- form_errors(form.date) -}} {{- form_errors(form.time) -}} {{- form_widget(form.date, { datetime: true } ) -}} {{- form_widget(form.time, { datetime: true } ) -}}
{%- endif %} {%- endblock datetime_widget %} {%- block url_widget -%} {%- set type = type|default('url') -%} {{ block('form_widget_simple') }} {{ block('form_help') }} {%- endblock url_widget -%} {% block date_widget -%} {% if widget == 'single_text' %} {{- block('form_widget_simple') -}} {% else -%} {% set attr = attr|merge({class: (attr.class|default('') ~ ' form-inline')|trim}) -%} {% if datetime is not defined or not datetime -%}
{%- endif %} {{- date_pattern|replace({ '{{ year }}': form_widget(form.year), '{{ month }}': form_widget(form.month), '{{ day }}': form_widget(form.day), })|raw -}} {% if datetime is not defined or not datetime -%}
{%- endif -%} {% endif %} {%- endblock date_widget %} {% block time_widget -%} {% if widget == 'single_text' %} {{- block('form_widget_simple') -}} {% else -%} {% set attr = attr|merge({class: (attr.class|default('') ~ ' form-inline')|trim}) -%} {% if datetime is not defined or false == datetime -%}
{%- endif -%} {{- form_widget(form.hour) }}:{{ form_widget(form.minute) }}{% if with_seconds %}:{{ form_widget(form.second) }}{% endif %} {% if datetime is not defined or false == datetime -%}
{%- endif -%} {% endif %} {%- endblock time_widget %} {%- block email_widget -%} {%- set type = type|default('email') -%} {{ block('form_widget_simple') }} {{ block('form_help') }} {%- endblock email_widget -%} {% block button_widget -%} {% set attr = attr|merge({class: (attr.class|default('btn-default') ~ ' btn')|trim}) %} {{- parent() -}} {%- endblock %} {% block icon_button_widget -%} {% set attr = attr|merge({class: (attr.class|default('btn-default') ~ ' btn')|trim}) %} {% if button_type == 'link' %} {% set buttonTag = 'a' %} {# Link tags need extra class for disabled, the attribute itself is not enough #} {% if attr.disabled|default(false) %} {% set attr = attr|merge({class: (attr.class ~ ' disabled')|trim}) %} {% endif %} {% else %} {% set buttonTag = 'button' %} {% set attr = attr|merge({type: 'button'}) %} {% endif %} <{{ buttonTag }} {{ block('button_attributes') }}> {{ button_icon }} {{ label }} {%- endblock %} {% block choice_widget %} {{- parent() -}} {{ block('form_help') }} {% endblock choice_widget %} {% block choice_widget_collapsed -%} {% set attr = attr|merge({class: (attr.class|default('') ~ ' custom-select')|trim}) %} {{- parent() -}} {%- endblock %} {% block choice_widget_expanded -%} {% if '-inline' in label_attr.class|default('') -%}
{%- for child in form %} {{- form_widget(child, { parent_label_class: label_attr.class|default(''), translation_domain: choice_translation_domain, valid: valid, }) -}} {% endfor -%}
{%- else -%}
{%- for child in form %} {{- form_widget(child, { parent_label_class: label_attr.class|default(''), translation_domain: choice_translation_domain, valid: valid, }) -}} {% endfor -%}
{%- endif %} {%- endblock choice_widget_expanded %} {% block choice_tree_widget -%}
{%- endblock choice_tree_widget %} {% block choice_tree_item_widget -%}
  • {% set checked = (form.vars.submitted_values is defined and submitted_values[child.id_category] is defined) ? 'checked="checked"' : '' %} {% if multiple -%}
    {%- else -%}
    {%- endif %} {% if child.children is defined %} {% endif %}
  • {%- endblock choice_tree_item_widget %} {% block translatefields_widget %} {{ form_errors(form) }}
    {% if hideTabs == false and form|length > 1 %} {% endif %}
    {% for translationsFields in form %}
    {{ form_errors(translationsFields) }} {{ form_widget(translationsFields) }}
    {% endfor %}
    {% endblock %} {% block translate_fields_widget -%} {% if type is not defined or 'file' != type %} {%- set attr = attr|merge({class: (attr.class|default('') ~ ' form-control')|trim}) -%} {% endif %} {{- parent() -}} {%- endblock translate_fields_widget %} {% block translate_text_widget -%} {{ form_errors(form) }}
    {% for translateField in form %} {% set classes = translateField.vars.attr.class|default('') ~ ' js-locale-input'%} {% set classes = classes ~ ' js-locale-' ~ translateField.vars.label %} {% if default_locale.id_lang != translateField.vars.name %} {% set classes = classes ~ ' d-none' %} {% endif %} {%- set attr = attr|merge({class: classes|trim}) -%} {{ block('form_widget') }} {% endfor %} {% if not hide_locales %} {% endif %}
    {%- endblock translate_text_widget %} {% block translate_textarea_widget -%} {{ form_errors(form) }}
    {% for textarea in form %} {% set classes = textarea.vars.attr.class|default('') ~ ' js-locale-input'%} {% set classes = classes ~ ' js-locale-' ~ textarea.vars.label %} {% if default_locale.id_lang != textarea.vars.name %} {% set classes = classes ~ ' d-none' %} {% endif %}
    {{ form_widget(textarea, {attr: {'class': classes|trim}}) }}
    {% endfor %} {% if show_locale_select %} {% endif %}
    {%- endblock translate_textarea_widget %} {% block date_picker_widget %} {% spaceless %} {% set attr = attr|merge({'class': ((attr.class|default('') ~ ' datepicker')|trim)}) %}
    date_range
    {{ block('form_help') }} {% endspaceless %} {% endblock date_picker_widget %} {% block date_range_widget %} {% spaceless %} {{ form_widget(form.from) }} {{ form_widget(form.to) }} {% endspaceless %} {% endblock date_range_widget %} {% block search_and_reset_widget %} {% spaceless %} {% if show_reset_button %}
    {% endif %} {% endspaceless %} {% endblock search_and_reset_widget %} {% block switch_widget %} {% spaceless %}
    {% for choice in choices %} {% set inputId = id ~'_' ~ choice.value %} {% endfor %}
    {% endspaceless %} {{- block('form_help') -}} {% endblock switch_widget %} {% block _form_step6_attachments_widget %}
    {{ 'There is no attachment yet.'|trans({}, 'Admin.Catalog.Notification') }}
    {%- for child in form %} {% endfor -%}
    {{ 'Title'|trans({}, 'Admin.Global') }} {{ 'File name'|trans({}, 'Admin.Global') }} {{ 'Type'|trans({}, 'Admin.Catalog.Feature') }}
    {{ form_widget(child) }} {{ form.vars.attr.data[loop.index0]['file_name'] }} {{ form.vars.attr.data[loop.index0]['mime'] }}
    {% endblock %} {# Labels #} {% block choice_label -%} {# remove the checkbox-inline and radio-inline class, it's only useful for embed labels #} {%- set label_attr = label_attr|merge({class: label_attr.class|default('')|replace({'checkbox-inline': '', 'radio-inline': ''})|trim}) -%} {{- block('form_label') -}} {% endblock %} {% block checkbox_label -%} {{- block('checkbox_radio_label') -}} {%- endblock checkbox_label %} {% block radio_label -%} {{- block('checkbox_radio_label') -}} {%- endblock radio_label %} {% block checkbox_radio_label %} {# Do not display the label if widget is not defined in order to prevent double label rendering #} {% if widget is defined %} {% if required %} {% set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' required')|trim}) %} {% endif %} {% if parent_label_class is defined %} {% set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' ' ~ parent_label_class)|trim}) %} {% endif %} {% if label is not same as(false) and label is empty %} {% set label = name|humanize %} {% endif %} {% if block_prefixes[2] == 'radio' %} {% else %}
    {{- widget|raw -}} {{- label is not same as(false) ? (translation_domain is same as(false) ? label|raw : label|raw) -}}
    {% endif %} {% endif %} {% endblock checkbox_radio_label %} {% block radio_widget -%} {%- set parent_label_class = parent_label_class|default(label_attr.class|default('')) -%} {%- if 'radio-custom' in parent_label_class -%} {%- set attr = attr|merge({class: (attr.class|default('') ~ ' custom-control-input')|trim}) -%}
    {{- form_label(form, null, { widget: block('base_radio_widget') }) -}}
    {%- else -%} {%- set attr = attr|merge({class: (attr.class|default('') ~ ' form-check-input')|trim}) -%}
    {{- form_label(form, null, { widget: block('base_radio_widget') }) -}}
    {%- endif -%} {%- endblock radio_widget %} {% block checkbox_widget -%} {%- set parent_label_class = parent_label_class|default(label_attr.class|default('')) -%} {%- set attr = attr|merge({class: (attr.class|default('') ~ ' form-check-input')|trim}) -%}
    {{- form_label(form, null, { widget: block('base_checkbox_widget') }) -}}
    {%- endblock checkbox_widget %} {# Errors #} {% block form_errors -%} {% if attr['fieldError'] is defined and attr['fieldError'] == true %} {{ block('form_errors_field') }} {% else %} {{ block('form_errors_other') }} {% endif %} {%- endblock form_errors %} {% block form_errors_field %} {% if errors|length > 0 -%} {# If we got more then one error then we need to display popover instead of errors list #} {%- if errors|length > 1 -%} {% set popoverContainer = 'popover-error-container-'~form.vars.id %}
    {% set popoverErrorContent %}
    {% endset %} {% set errorPopover %} error_outline {{ '%count% errors'|transchoice(errors|length, {}, 'Admin.Global') }} {% endset %}
    {{ errorPopover }}
    {# If there is only one error then display it without popover #} {%- else -%}
    error_outline
    {% for error in errors %}

    {{ error.messagePluralization is null ? error.messageTemplate|trans(error.messageParameters, 'form_error') : error.messageTemplate|transchoice(error.messagePluralization, error.messageParameters, 'form_error') }}

    {%- endfor -%}
    {%- endif -%} {%- endif %} {% endblock %} {% block form_errors_other %} {% if errors|length > 0 -%} {% endif %} {% endblock %} {# Material design widgets #} {% block material_choice_table_widget %} {% spaceless %}
    {% for child in form %} {% endfor %}
    {{ form_widget(child, {'material_design': true}) }}
    {% endspaceless %} {% endblock material_choice_table_widget %} {% block material_multiple_choice_table_widget %} {% spaceless %}
    {% for child_choice in form %} {% endfor %} {% for choice_name, choice_value in choices %} {% for child_choice_name, child_choice in form %} {% endfor %} {% endfor %}
    {{ table_label }} {% if child_choice.vars.multiple and child_choice.vars.name not in headers_to_disable %} {{ child_choice.vars.label }} {% else %} {{ child_choice.vars.label }} {% endif %}
    {{ choice_name }} {% if child_choice_entry_index_mapping[choice_value][child_choice_name] is defined %} {% set entry_index = child_choice_entry_index_mapping[choice_value][child_choice_name] %} {% if child_choice.vars.multiple %} {{ form_widget(child_choice[entry_index], {'material_design': true}) }} {% else %} {{ form_widget(child_choice[entry_index]) }} {% endif %} {% else %} -- {% endif %}
    {% endspaceless %} {% endblock material_multiple_choice_table_widget %} {# Copied translatablefields_widget made to be compatible with TranslatableType.php and to be used in translatable widget#} {% block translatable_fields_with_tabs %}
    {% if hide_locales == false and form|length > 1 %} {% endif %}
    {% for translationsFields in form %}
    {{ form_widget(translationsFields) }}
    {% endfor %}
    {% endblock %} {% block translatable_fields_with_dropdown -%} {% set formClass = (form.vars.attr.class|default('') ~ ' input-group locale-input-group js-locale-input-group d-flex')|trim %}
    {% for translateField in form %} {% set classes = translateField.vars.attr.class|default('') ~ ' js-locale-input'%} {% set classes = classes ~ ' js-locale-' ~ translateField.vars.label %} {% if default_locale.id_lang != translateField.vars.name %} {% set classes = classes ~ ' d-none' %} {% endif %}
    {{ form_widget(translateField) }}
    {% endfor %} {% if not hide_locales %} {% endif %}
    {%- endblock %} {% block translatable_widget -%} {% if use_tabs %} {{ block('translatable_fields_with_tabs') }} {% else %} {{ block('translatable_fields_with_dropdown') }} {% endif %} {{ block('form_help') }} {%- endblock translatable_widget %} {% block birthday_widget %} {% if widget == 'single_text' %} {{- block('form_widget_simple') -}} {% else -%} {% set attr = attr|merge({class: (attr.class|default('') ~ ' form-inline')|trim}) -%} {% if datetime is not defined or not datetime -%}
    {%- endif %} {% set yearWidget = '
    ' ~ form_widget(form.year) ~ '
    '|raw %} {% set monthWidget = '
    ' ~ form_widget(form.month) ~ '
    '|raw %} {% set dayWidget = '
    ' ~ form_widget(form.day) ~ '
    '|raw %} {{- date_pattern|replace({ '{{ year }}': yearWidget, '{{ month }}': monthWidget, '{{ day }}': dayWidget, })|raw -}} {% if datetime is not defined or not datetime -%}
    {%- endif -%} {% endif %} {% endblock birthday_widget %} {% block file_widget %}
    {% set attr = attr|merge({ class: (attr.class|default('') ~ ' custom-file-input')|trim, 'data-multiple-files-text': '%count% file(s)'|trans({}, 'Admin.Global'), 'data-locale': get_context_iso_code() }) -%} {% if attr.disabled is defined and attr.disabled %} {% set attr = attr|merge({ class: attr.class ~ ' disabled' }) %} {% endif %} {{- block('form_widget_simple') -}}
    {{- block('form_help') -}} {% if form.vars.download_url %} {{ 'Download file'|trans({}, 'Admin.Actions') }} {% endif %} {% endblock file_widget %} {% block shop_restriction_checkbox_widget %} {% if form.vars.attr.is_allowed_to_display %}
    {% endif %} {% endblock %} {% block generatable_text_widget %}
    {% if compound %} {{- block('form_widget_compound') -}} {% else %} {{- block('form_widget_simple') -}} {% endif %}
    {{ block('form_help') }} {% endblock generatable_text_widget %} {% block text_with_recommended_length_widget %} {% set attr = attr|merge({ 'data-recommended-length-counter': '#' ~ id ~ '_recommended_length_counter', 'class': 'js-recommended-length-input' }) -%} {% if input_type == 'textarea' %} {{- block('textarea_widget') -}} {% else %} {{- block('form_widget_simple') -}} {% endif %} {{ '[1][/1] of [2][/2] characters used (recommended)'|trans({}, 'Admin.Catalog.Feature')|replace({ '[1]': '' ~ value|length, '[/1]': '', '[2]': '' ~ recommended_length, '[/2]': '', })|raw }} {% endblock %} {% block text_with_length_counter_widget %}
    {% set current_length = form.vars.max_length - form.vars.value|length %} {% if form.vars.position == 'before' %}
    {{ current_length }}
    {% endif %} {% set attr = attr|merge({'data-max-length': form.vars.max_length, 'maxlength': form.vars.max_length, 'class': 'js-countable-input'}) -%} {% set attr = attr|merge(input_attr) -%} {% if form.vars.input == 'input' %} {{- block('form_widget_simple') -}} {% elseif form.vars.input == 'textarea' %} {{- block('textarea_widget') -}} {% else %} {{- block('form_widget') -}} {% endif %} {% if form.vars.position == 'after' %}
    {{ current_length }}
    {% endif %}
    {% endblock %} {% block integer_min_max_filter_widget %} {{ form_widget(form['min_field'], { attr: {class: 'min-field'}}) }} {{ form_widget(form['max_field'], { attr: {class: 'max-field'}}) }} {% endblock %} {% block number_min_max_filter_widget %} {{ form_widget(form['min_field'], { attr: {class: 'min-field'}}) }} {{ form_widget(form['max_field'], { attr: {class: 'max-field'}}) }} {% endblock %} {%- block number_widget -%} {%- set type = type|default('text') -%} {{ block('form_widget_simple') }} {{- block('form_help') -}} {%- endblock number_widget -%} {%- block integer_widget -%} {%- set type = type|default('number') -%} {{ block('form_widget_simple') }} {{- block('form_help') -}} {%- endblock integer_widget -%} {% block form_help %} {% if help %} {{ help|raw }} {% endif %} {% if warning is defined %} {{ warning }} {% endif %} {% endblock form_help %} {% block form_external_link %} {% if external_link is defined %} {%- set openingTag -%} open_in_new {%- endset -%}
    {{ external_link.text|replace({'[1]': openingTag, '[/1]': ''})|raw }}
    {% endif %} {% endblock form_external_link %} {%- block form_external_link_attributes -%} {% set external_link_attr = external_link.attr|merge({class: (external_link.attr.class|default('') ~ ' btn btn-link px-0 align-right')|trim}) %} {% for attrname, attrvalue in external_link_attr %} {% if attrname not in ['href', 'class'] %} {{ attrname }}="{{ attrvalue }}" {% endif %} {% endfor %} target="_blank" href="{{ external_link.href }}" class="{{ external_link_attr.class }}" {%- endblock -%} {% block custom_content_widget %} {% include template with data %} {% endblock %} {% block text_widget %} {%- set attr = attr|merge({'aria-label': '%inputId% input'|trans({'%inputId%': form.vars.id}, 'Admin.Global')}) -%} {% if data_list is not null %} {%- set attr = attr|merge({'list': id ~ '_datalist'}) -%} {% endif %} {{ form_widget(form, {'attr': attr}) }} {% if data_list is not null %} {% for item in data_list %} {% endfor%} {% endif %} {% endblock text_widget %} {%- block form_prepend_alert -%} {% if alert_position is defined and alert_position == 'prepend' %} {{- block('form_alert') -}} {% endif %} {% endblock %} {%- block form_append_alert -%} {% if alert_position is defined and alert_position == 'append' %} {{- block('form_alert') -}} {% endif %} {% endblock %} {%- block form_alert -%} {% if alert_message is defined %} {% endif %} {%- endblock -%} {% block unavailable_widget %} {% endblock %}