<!DOCTYPE html>
<html lang="{{ app.request.locale }}">
<head>
<meta charset="UTF-8" />
<meta name="CSRF-Token" content="{{ csrf_token('rest') }}" />
<meta name="SiteAccess" content="{{ app.request.get('siteaccess').name }}" />
<meta name="UserId" content="{{ ibexa_admin_ui_config.user.user.id|default() }}" />
<script>
const userAgent = navigator.userAgent.toLowerCase();
if (userAgent.indexOf('chrome') < 0 && userAgent.indexOf('safari') >= 0) {
window.onpageshow = (event) => {
if (event.persisted) {
document.body.classList.remove('ibexa-prevent-click');
}
};
}
</script>
<script>
window.ibexa = window.eZ = {
addConfig: (path, value, shouldMerge = false) => {
const keys = path.split('.');
const lastIndex = keys.length - 1;
const objectConstructorName = 'Object';
const setValue = (newValue, oldValue) => {
const hasValue = newValue && !!newValue.constructor;
const oldHasValue = oldValue && !!oldValue.constructor;
if (!shouldMerge || !hasValue || !oldHasValue) {
return newValue;
}
if (Array.isArray(newValue)) {
return [...oldValue, ...newValue];
}
if (newValue.constructor.name === objectConstructorName) {
return Object.assign({}, oldValue, newValue);
}
};
keys.reduce((currentObj, nextKey, index) => {
const isLastIndex = index === lastIndex;
if (!currentObj[nextKey] && !isLastIndex) {
currentObj[nextKey] = {};
}
if (isLastIndex) {
currentObj[nextKey] = setValue(value, currentObj[nextKey]);
}
return currentObj[nextKey];
}, window.ibexa);
},
};
</script>
{% block meta %}
{% endblock %}
<script>
window.ibexa.addConfig('adminUiConfig', {{ ibexa_admin_ui_config|json_encode|raw }});
window.ibexa.addConfig('richText', {{ ibexa_richtext_config|json_encode|raw }});
window.ibexa.addConfig('errors', {
emailRegexp: /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,
urlRegexp: /^((https?:\/\/|ftps?:\/\/|sftp:\/\/|www\.|\/|ezlocation:\/\/)[^\s]+$)|(^([a-zA-Z0-9.-]+\.[a-zA-Z]{2,})(\/[^\s]*)?$)/,
emptyField: '{{ 'js.error.empty.field'|trans({}, 'validators')|desc('{fieldName} Field cannot be empty') }}',
invalidEmail: '{{ 'js.error.invalid_email'|trans({}, 'validators')|desc('A valid email address is required') }}',
invalidUrl: '{{ 'js.error.invalid_url'|trans({}, 'validators')|desc('A valid URL is required') }}',
tooLong: '{{ 'js.error.too_long'|trans({}, 'validators')|desc('{fieldName} value must be less than or equal to {maxLength} characters') }}',
tooShort: '{{ 'js.error.too_short'|trans({}, 'validators')|desc('{fieldName} value must be greater than or equal to {minLength} characters') }}',
isNotInteger: '{{ 'js.error.is_not_integer'|trans({}, 'validators')|desc('{fieldName} value must be an integer') }}',
isNotFloat: '{{ 'js.error.is_not_float'|trans({}, 'validators')|desc('{fieldName} value must be a float number') }}',
isLess: '{{ 'js.error.is_less'|trans({}, 'validators')|desc('{fieldName} value must be greater than or equal to {minValue}') }}',
isGreater: '{{ 'js.error.is_greater'|trans({}, 'validators')|desc('{fieldName} value must be less than or equal to {maxValue}') }}',
invalidFileSize: '{{ 'js.error.invalid_file_size'|trans({}, 'validators')|desc('{fieldName}: Cannot upload. File exceeds file size limit.') }}',
invalidFileType: '{{ 'js.error.invalid_file_type'|trans({}, 'validators')|desc('{fieldName}: Cannot upload. File has wrong type.') }}',
provideLatitudeValue: '{{ 'js.error.provide_latitude_value'|trans({}, 'validators')|desc('Provide latitude value in the Latitude field') }}',
provideLongitudeValue: '{{ 'js.error.provide_longitude_value'|trans({}, 'validators')|desc('Provide longitude value in the Longitude field') }}',
addressNotFound: '{{ 'js.error.address_not_found'|trans({}, 'validators')|desc('Provided address does not exist') }}',
notSamePasswords: '{{ 'js.error.not_same_passwords'|trans({}, 'validators')|desc('Passwords do not match') }}',
invalidValue: '{{ 'js.error.invalid_value'|trans({}, 'validators')|desc('{fieldName} Field has invalid values') }}',
outOfRangeValue: '{{ 'js.error.out_of_range_value'|trans({}, 'validators')|desc('{fieldName} value is out of range. The value must be between {min} and {max}') }}'
});
window.CKEDITOR_BASEPATH = window.ALLOYEDITOR_BASEPATH = "/bundles/ibexaadminuiassets/vendors/alloyeditor/dist/alloy-editor/";
</script>
<script src="/bundles/fosjsrouting/js/router.js"></script>
<script src="{{ path('fos_js_routing_js', { callback: 'fos.Router.setData' }) }}"></script>
{% if app.request.locale == 'ach-UG' %}
<script type="text/javascript">
var _jipt = [];
_jipt.push(['project', 'ibexa-dxp']);
</script>
<script type="text/javascript" src="//cdn.crowdin.com/jipt/jipt.js"></script>
{% endif %}
<title>{% block title %}Exponential Platform DXP{% endblock %}</title>
{{ encore_entry_link_tags('ibexa-admin-ui-layout-css', null, 'ibexa') }}
{% block stylesheets %}{% endblock %}
<link rel="icon" type="image/x-icon" href="{{ asset('bundles/ibexaadminui/img/favicon.ico') }}" />
<link rel="icon" type="image/png" sizes="16x16" href="{{ asset('bundles/ibexaadminui/img/favicon-16x16.png') }}" />
<link rel="icon" type="image/png" sizes="32x32" href="{{ asset('bundles/ibexaadminui/img/favicon-32x32.png') }}" />
{{ ibexa_twig_component_group('admin-ui-stylesheet-head') }}
{{ ibexa_twig_component_group('admin-ui-script-head') }}
<script src="{{ asset('bundles/ibexaadminuiassets/vendors/react/umd/react.production.min.js') }}"></script>
<script src="{{ asset('bundles/ibexaadminuiassets/vendors/react-dom/umd/react-dom.production.min.js') }}"></script>
<script src="{{ asset('bundles/ibexaadminuiassets/vendors/@popperjs/core/dist/umd/popper.min.js') }}"></script>
<script src="{{ asset('bundles/ibexaadminuiassets/vendors/bootstrap/dist/js/bootstrap.min.js') }}"></script>
<script src="{{ asset('bundles/ibexaadminuiassets/vendors/create-react-class/create-react-class.min.js') }}"></script>
<script src="{{ asset('bundles/ibexaadminuiassets/vendors/prop-types/prop-types.min.js') }}"></script>
<script src="{{ asset('bundles/ibexaadminuiassets/vendors/flatpickr/dist/flatpickr.min.js') }}"></script>
<script src="{{ asset('bundles/ibexaadminuiassets/vendors/moment/min/moment-with-locales.min.js') }}"></script>
<script src="{{ asset('bundles/ibexaadminuiassets/vendors/moment-timezone/builds/moment-timezone-with-data.min.js') }}"></script>
<script src="{{ asset('bundles/bazingajstranslation/js/translator.min.js') }}"></script>
<script src="{{ asset('assets/translations/config.js') }}"></script>
<script src="{{ asset('assets/translations/' ~ app.request.locale ~ '.js') }}"></script>
<script src="{{ asset('bundles/ibexaadminuiassets/vendors/chart-js/dist/chart.umd.js') }}"></script>
<script src="{{ asset('bundles/ibexaadminuiassets/vendors/chartjs-plugin-datalabels/dist/chartjs-plugin-datalabels.min.js') }}"></script>
<script src="{{ asset('bundles/ibexaadminuiassets/vendors/js-md5/build/md5.min.js') }}"></script>
</head>
<body class="{% block body_class %}ibexa-theme {% if ibexa_is_focus_mode_on() %}ibexa-theme--dark{% endif %}{% endblock %}">
<div id="react-udw" data-filter-subtree-udw-config="{{ ibexa_udw_config('single_container', {}) }}"></div>
{% block header_row %}
<header class="ibexa-main-header">
<div class="ibexa-main-header__brand-column">
{% block brand %}
<a class="ibexa-main-header__brand" href="{{ url('ibexa.dashboard') }}">
<img class="ibexa-main-header__brand-image" src="{{ asset('bundles/ibexaadminui/img/exponential-platform-dxp-logo.svg') }}" alt="Exponential Platform DXP" />
</a>
{% endblock %}
{% block user_mode %}
{{ include('@ibexadesign/ui/user_mode_badge.html.twig') }}
{% endblock %}
</div>
{% block global_search_wrapper %}
<div class="ibexa-main-header__search-column">
{% block global_search %}
{{ ibexa_twig_component_group('admin-ui-global-search') }}
{% endblock %}
</div>
{% endblock %}
{% block user_menu_wrapper %}
<div class="ibexa-main-header__user-menu-column">
{% block user_menu %}
{{ ibexa_twig_component_group('admin-ui-user-menu') }}
{% endblock %}
</div>
{% endblock %}
</header>
{% endblock %}
{% block main_container %}
<main class="ibexa-main-container {% block main_container_class %}{% endblock %}">
{% block side_column %}
<div class="ibexa-main-container__side-column {% block side_column_class %}{% endblock %}">
{% block left_sidebar %}
{% set main_menu_context = {
'location': location ?? null,
'content': content ?? null
} %}
{% set main_menu = knp_menu_get('ezplatform_admin_ui.menu.main', [], main_menu_context) %}
<nav class="ibexa-main-menu">
{{ knp_menu_render(main_menu, {
'depth': 1,
'template': '@ibexadesign/ui/menu/main.html.twig',
'currentClass': 'active',
'ancestorClass': 'active'
}) }}
{{ knp_menu_render(main_menu, {
'depth': 2,
'template': '@ibexadesign/ui/menu/main_2nd_level.html.twig',
'currentClass': 'active',
'ancestorClass': 'active'
}) }}
{% block content_tree %}{% endblock %}
</nav>
{% endblock %}
</div>
{% endblock %}
{% block content_column %}
<div
class="ibexa-main-container__content-column
{%- if not is_back_to_top_disabled|default(false) %} ibexa-back-to-top-scroll-container{% endif %}"
>
<div class="container ibexa-back-to-top-anchor">
{% block content_header %}
<div class="ibexa-page-header-wrapper">
<div class="ibexa-breadcrums-wrapper">
{% block breadcrumbs %}{% endblock %}
</div>
<div class="ibexa-content-menu-wrapper">
{% block context_menu %}{% endblock %}
</div>
<div class="ibexa-header-wrapper">
{% block header %}{% endblock %}
</div>
</div>
{% endblock %}
{% block content %}{% endblock %}
</div>
</div>
{% endblock %}
</main>
{% endblock %}
<div
class="ibexa-notifications-container"
data-notifications="{{ app.flashes|json_encode() }}"
data-template="{{ include('@ibexadesign/ui/notification.html.twig', {
label: '{{ label }}',
message: '{{ message }}',
})|e('html_attr') }}"></div>
<div class="ibexa-modal-wrapper"></div>
<div class="ibexa-quick-action-menu">
{% if not is_back_to_top_disabled|default(false) %}
{% block back_to_top %}
<div class="ibexa-back-to-top">
<button type="button" class="btn ibexa-btn ibexa-btn--tertiary ibexa-btn--no-text ibexa-back-to-top__btn">
<span class="ibexa-back-to-top__title">
{{ 'back.to.top'|trans|desc('Go to top') }}
</span>
<svg class="ibexa-icon ibexa-icon--medium ibexa-back-to-top__icon">
<use xlink:href="{{ ibexa_icon_path('back') }}"></use>
</svg>
</button>
</div>
{% endblock %}
{% endif %}
{{ ibexa_twig_component_group('admin-ui-quick-action-menu') }}
</div>
{{ ibexa_twig_component_group('admin-ui-layout-content-after') }}
{{ encore_entry_script_tags('ibexa-admin-ui-layout-js', null, 'ibexa') }}
{{ encore_entry_script_tags('ibexa-admin-ui-udw-tabs-js', null, 'ibexa') }}
{{ encore_entry_script_tags('ibexa-admin-ui-udw-extras-js', null, 'ibexa') }}
{{ encore_entry_script_tags('ibexa-admin-ui-udw-js', null, 'ibexa') }}
{% block react_modules %}{% endblock %}
{% block javascripts %}{% endblock %}
{{ ibexa_twig_component_group('admin-ui-stylesheet-body') }}
{{ ibexa_twig_component_group('admin-ui-script-body') }}
</body>
</html>