vendor/easycorp/easyadmin-bundle/src/Resources/views/layout.html.twig line 1

Open in your IDE?
  1. {# @var ea \EasyCorp\Bundle\EasyAdminBundle\Context\AdminContext #}
  2. {% trans_default_domain ea.i18n.translationDomain %}
  3. <!DOCTYPE html>
  4. <html lang="{{ ea.i18n.htmlLocale }}" dir="{{ ea.i18n.textDirection }}">
  5. <head>
  6. {% block head_metas %}
  7. <meta charset="utf-8">
  8. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  9. <meta name="robots" content="noindex, nofollow, noarchive, nosnippet, noodp, noimageindex, notranslate, nocache" />
  10. <meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
  11. <meta name="generator" content="EasyAdmin" />
  12. {% endblock head_metas %}
  13. {% set page_title_block_output %}{% block page_title %}{{ block('content_title') }}{% endblock %}{% endset %}
  14. <title>{{ page_title_block_output|striptags|raw }}</title>
  15. {% block head_stylesheets %}
  16. <link rel="stylesheet" href="{{ asset('bundles/easyadmin/app.css') }}">
  17. {% endblock %}
  18. {% block configured_stylesheets %}
  19. {{ include('@EasyAdmin/includes/_css_assets.html.twig', { assets: ea.assets.cssAssets ?? [] }, with_context = false) }}
  20. {{ include('@EasyAdmin/includes/_encore_link_tags.html.twig', { assets: ea.assets.webpackEncoreAssets ?? [] }, with_context = false) }}
  21. {% endblock %}
  22. {% block head_favicon %}
  23. <link rel="shortcut icon" href="{{ asset(ea.dashboardFaviconPath) }}">
  24. {% endblock %}
  25. {% block head_javascript %}
  26. <script src="{{ asset('bundles/easyadmin/app.js') }}"></script>
  27. {% endblock head_javascript %}
  28. {% block configured_javascripts %}
  29. {{ include('@EasyAdmin/includes/_js_assets.html.twig', { assets: ea.assets.jsAssets ?? [] }, with_context = false) }}
  30. {{ include('@EasyAdmin/includes/_encore_script_tags.html.twig', { assets: ea.assets.webpackEncoreAssets ?? [] }, with_context = false) }}
  31. {% endblock %}
  32. {% if 'rtl' == ea.i18n.textDirection %}
  33. <link rel="stylesheet" href="{{ asset('bundles/easyadmin/app.rtl.css') }}">
  34. {% endif %}
  35. {% block configured_head_contents %}
  36. {% for htmlContent in ea.assets.headContents ?? [] %}
  37. {{ htmlContent|raw }}
  38. {% endfor %}
  39. {% endblock %}
  40. </head>
  41. {% block body %}
  42. <body id="{% block body_id %}{% endblock %}" class="ea {% block body_class %}{% endblock %}">
  43. {% block javascript_page_layout %}
  44. <script>
  45. document.body.classList.add(
  46. 'ea-content-width-' + (localStorage.getItem('ea/content/width') || '{{ ea.crud.contentWidth ?? ea.dashboardContentWidth ?? 'normal' }}'),
  47. 'ea-sidebar-width-' + (localStorage.getItem('ea/sidebar/width') || '{{ ea.crud.sidebarWidth ?? ea.dashboardSidebarWidth ?? 'normal' }}')
  48. );
  49. </script>
  50. {% endblock javascript_page_layout %}
  51. {% block wrapper_wrapper %}
  52. {% block flash_messages %}
  53. {{ include(ea.templatePath('flash_messages')) }}
  54. {% endblock flash_messages %}
  55. {% set user_menu_avatar %}
  56. {% if null == ea.userMenu.avatarUrl %}
  57. <span class="user-avatar">
  58. <span class="fa-stack">
  59. <i class="user-avatar-icon-background fas fa-square fa-stack-2x"></i>
  60. <i class="user-avatar-icon-foreground {{ ea.user is not null ? 'fa fa-user' : 'fas fa-user-slash' }} fa-stack-1x fa-inverse"></i>
  61. </span>
  62. </span>
  63. {% else %}
  64. <img class="user-avatar" src="{{ ea.userMenu.avatarUrl }}" />
  65. {% endif %}
  66. {% endset %}
  67. {% set impersonator_permission = constant('Symfony\\Component\\Security\\Core\\Authorization\\Voter\\AuthenticatedVoter::IS_IMPERSONATOR') is defined ? 'IS_IMPERSONATOR' : 'ROLE_PREVIOUS_ADMIN' %}
  68. {% set user_menu_dropdown %}
  69. <ul class="dropdown-menu dropdown-menu-end">
  70. <li class="dropdown-user-details">
  71. <div>{{ user_menu_avatar }}</div>
  72. <div>
  73. <span class="user-label">{{ 'user.logged_in_as'|trans(domain = 'EasyAdminBundle') }}</span>
  74. <span class="user-name">{{ ea.user is null ? 'user.anonymous'|trans(domain = 'EasyAdminBundle') : ea.userMenu.name }}</span>
  75. </div>
  76. </li>
  77. <li><hr class="dropdown-divider"></li>
  78. {% block user_menu %}
  79. {% if ea.userMenu.items|length > 0 %}
  80. {% for item in ea.userMenu.items %}
  81. <li>
  82. {% if item.isMenuSection and not loop.first %}
  83. <hr class="dropdown-divider">
  84. {% elseif not item.isMenuSection %}
  85. <a href="{{ item.linkUrl }}" class="dropdown-item user-action {{ item.cssClass }}"
  86. target="{{ item.linkTarget }}" rel="{{ item.linkRel }}"
  87. referrerpolicy="origin-when-cross-origin">
  88. {% if item.icon is not empty %}<i class="fa fa-fw {{ item.icon }}"></i>{% endif %}
  89. <span>{{ item.label }}</span>
  90. </a>
  91. {% endif %}
  92. </li>
  93. {% endfor %}
  94. {% endif %}
  95. {% endblock user_menu %}
  96. </ul>
  97. {% endset %}
  98. <div class="wrapper">
  99. {% block wrapper %}
  100. <div class="responsive-header">
  101. {% block responsive_header %}
  102. <button id="navigation-toggler" type="button" aria-label="Toggle navigation">
  103. <i class="fa fa-fw fa-bars"></i>
  104. </button>
  105. <div id="responsive-header-logo" class="text-truncate">
  106. {% block responsive_header_logo %}
  107. <a class="responsive-logo" title="{{ ea.dashboardTitle|striptags }}" href="{{ path(ea.dashboardRouteName) }}">
  108. {{ ea.dashboardTitle|raw }}
  109. </a>
  110. {% endblock responsive_header_logo %}
  111. </div>
  112. <div class="dropdown user-menu-wrapper {{ is_granted(impersonator_permission) ? 'user-is-impersonated' }}">
  113. <a class="user-details" type="button" data-bs-toggle="dropdown" data-bs-offset="0,5" aria-expanded="false">
  114. {# to make the site design consistent, always display the user avatar in responsive header
  115. and hide the user name (because there's no space left) regardless of the user config #}
  116. {% if ea.userMenu.avatarDisplayed %}
  117. {{ user_menu_avatar }}
  118. {% else %}
  119. <i class="user-avatar fa fa-fw {{ ea.user is not null ? 'fa-user' : 'fa-user-times' }}"></i>
  120. {% endif %}
  121. </a>
  122. {{ user_menu_dropdown }}
  123. </div>
  124. {% endblock responsive_header %}
  125. </div>
  126. <div class="sidebar-wrapper">
  127. <aside class="sidebar">
  128. {% block sidebar %}
  129. <header class="main-header">
  130. {% block header %}
  131. <nav class="navbar" role="navigation">
  132. {% block header_navbar %}
  133. <div id="header-logo">
  134. {% block header_logo %}
  135. <a class="logo" title="{{ ea.dashboardTitle|striptags }}" href="{{ path(ea.dashboardRouteName) }}">
  136. <span class="logo-custom">{{ ea.dashboardTitle|raw }}</span>
  137. <span class="logo-compact"><i class="fas fa-home"></i></span>
  138. </a>
  139. {% endblock header_logo %}
  140. </div>
  141. {% endblock header_navbar %}
  142. </nav>
  143. {% endblock header %}
  144. </header>
  145. {% block main_menu_wrapper %}
  146. {{ include(ea.templatePath('main_menu')) }}
  147. {% endblock main_menu_wrapper %}
  148. {% endblock sidebar %}
  149. <div id="sidebar-resizer-handler" class="resizer-handler resizer-handler-left"></div>
  150. </aside>
  151. </div>
  152. <section class="main-content">
  153. {% set has_search = ea.crud is not null and ea.crud.isSearchEnabled %}
  154. <aside class="content-top {{ has_search ? 'ea-search-enabled' : 'ea-search-disabled' }}">
  155. {% block content_top_header %}
  156. <div class="content-search">
  157. {% if has_search %}
  158. {% block search %}
  159. <form class="form-action-search" method="get">
  160. {% block search_form %}
  161. {% block search_form_filters %}
  162. {% for field, array in ea.search.appliedFilters %}
  163. {% for key, value in array %}
  164. {# This code re-applies your filters on searches, an iterable check is needed in cases we have more than one object for a filter #}
  165. {% if value is iterable %}
  166. {% for index, iterValue in value %}
  167. <input type="hidden" name="filters[{{ field }}][{{ key }}][{{ index }}]" value="{{ iterValue }}">
  168. {% endfor %}
  169. {% else %}
  170. <input type="hidden" name="filters[{{ field }}][{{ key }}]" value="{{ value }}">
  171. {% endif %}
  172. {% endfor %}
  173. {% endfor %}
  174. {% endblock %}
  175. <input type="hidden" name="crudAction" value="index">
  176. <input type="hidden" name="crudControllerFqcn" value="{{ ea.request.query.get('crudControllerFqcn') }}">
  177. <input type="hidden" name="menuIndex" value="{{ ea.request.query.get('menuIndex') }}">
  178. <input type="hidden" name="submenuIndex" value="{{ ea.request.query.get('submenuIndex') }}">
  179. <input type="hidden" name="page" value="1">
  180. <input type="hidden" name="signature" value="{{ ea_url().unsetAll().setAction('index').setController(ea.request.query.get('crudControllerFqcn')).getSignature() }}">
  181. <div class="form-group">
  182. <div class="form-widget">
  183. <i class="fas fa-search content-search-icon"></i>
  184. <label class="content-search-label" data-value="{{ app.request.get('query') }}">
  185. <input class="form-control {{ app.request.get('query') is null ? 'is-blank' }}" type="search" name="query" value="{{ app.request.get('query') ?? '' }}" placeholder="{{ 'action.search'|trans(ea.i18n.translationParameters, 'EasyAdminBundle') }}" spellcheck="false" autocorrect="false" onInput="this.parentNode.dataset.value=this.value">
  186. </label>
  187. {% if app.request.get('query') %}
  188. <a href="{{ ea_url().unset('query') }}" class="content-search-reset">
  189. <i class="fas fa-fw fa-times"></i>
  190. </a>
  191. {% endif %}
  192. </div>
  193. </div>
  194. {% endblock %}
  195. </form>
  196. {% endblock search %}
  197. {% endif %}
  198. </div>
  199. <div class="navbar-custom-menu">
  200. {% block header_custom_menu %}
  201. <div class="dropdown user-menu-wrapper {{ is_granted(impersonator_permission) ? 'user-is-impersonated' }}">
  202. <a class="user-details" type="button" data-bs-toggle="dropdown" data-bs-offset="0,5" aria-expanded="false">
  203. {{ user_menu_avatar }}
  204. {% if ea.userMenu.isNameDisplayed %}
  205. <span class="user-name">{{ ea.userMenu.name }}</span>
  206. {% endif %}
  207. </a>
  208. {{ user_menu_dropdown }}
  209. </div>
  210. {% endblock header_custom_menu %}
  211. </div>
  212. {% endblock content_top_header %}
  213. </aside>
  214. <div class="content-wrapper">
  215. {% block content %}
  216. <article class="content">
  217. {% block content_header_wrapper %}
  218. {% set has_help_message = (ea.crud.helpMessage ?? '') is not empty %}
  219. <section class="content-header">
  220. {% block content_header %}
  221. <div class="content-header-title">
  222. <h1 class="title">
  223. {% block content_title %}{% endblock %}
  224. {% block content_help %}
  225. {% if has_help_message %}
  226. <span class="content-header-help">
  227. <i class="far fa-question-circle" data-bs-toggle="tooltip" title="{{ ea.crud.helpMessage|e('html_attr') }}"></i>
  228. </span>
  229. {% endif %}
  230. {% endblock %}
  231. </h1>
  232. </div>
  233. {% block page_actions_wrapper %}
  234. <div class="page-actions">{% block page_actions %}{% endblock %}</div>
  235. {% endblock %}
  236. {% endblock content_header %}
  237. </section>
  238. {% endblock content_header_wrapper %}
  239. <section id="main" class="content-body">
  240. {% block main %}{% endblock %}
  241. </section>
  242. {% block content_footer_wrapper %}
  243. {% set content_footer = block('content_footer') is defined ? block('content_footer') : '' %}
  244. {% if content_footer is not empty %}
  245. <section class="content-footer">
  246. {{ content_footer }}
  247. </section>
  248. {% endif %}
  249. {% endblock %}
  250. </article>
  251. {% endblock content %}
  252. <div id="content-resizer-handler" class="resizer-handler resizer-handler-right"></div>
  253. </div>
  254. </section>
  255. {% endblock wrapper %}
  256. </div>
  257. {% endblock wrapper_wrapper %}
  258. {% block body_javascript %}{% endblock body_javascript %}
  259. {% block configured_body_contents %}
  260. {% for htmlContent in ea.assets.bodyContents ?? [] %}
  261. {{ htmlContent|raw }}
  262. {% endfor %}
  263. {% endblock %}
  264. </body>
  265. {% endblock body %}
  266. </html>