navigation-menu.html.twig
{% import _self as menus %}
<div class="admin-toolbar__item">
<h4 class="visually-hidden focusable">{{ title }}</h4>
<ul class="toolbar-block__list">
{{ menus.menu_items(items, attributes, 0) }}
</ul>
</div>
{% macro menu_items(items, attributes, menu_level) %}
{% for item in items %}
{% set item_link_tag = 'a' %}
{% if item.url.isRouted %}
{% if item.url.routeName == '<nolink>' %}
{% set item_link_tag = constant('\\Drupal\\Core\\GeneratedNoLink::TAG') %}
{% elseif item.url.routeName == '<button>' %}
{% set item_link_tag = constant('\\Drupal\\Core\\GeneratedButton::TAG') %}
{% endif %}
{% endif %}
{% if item.url.options.attributes is empty %}
{% set item_link_attributes = create_attribute() %}
{% else %}
{% set item_link_attributes = create_attribute(item.url.options.attributes) %}
{% endif %}
{% set item_id = ('navigation-link--' ~ item.original_link.pluginId)|clean_unique_id %}
{% if menu_level == 0 %}
{% if item.below is empty %}
<li id="{{ item_id }}" class="toolbar-block__list-item">
{% include 'navigation:toolbar-button' with {
attributes: item_link_attributes.setAttribute('href', item.url|render|default(null)).setAttribute('data-drupal-tooltip', item.title).setAttribute('data-drupal-tooltip-class', 'admin-toolbar__tooltip'),
icon: item.icon,
html_tag: item_link_tag,
text: item.title,
modifiers: [
'collapsible',
item_link_tag == 'span' ? 'non-interactive' : null
]|filter(v => v is not null),
} only %}
</li>
{% else %}
<li id="{{ item_id }}" class="toolbar-block__list-item toolbar-popover" data-toolbar-popover>
{% include 'navigation:toolbar-button' with {
action: 'Extend'|t,
attributes: create_attribute({
'aria-expanded': 'false',
'aria-controls': item_id,
'data-toolbar-popover-control': true,
'data-has-safe-triangle': true,
}),
icon: item.icon,
text: item.title,
modifiers: [
'expand--side',
'collapsible',
],
extra_classes: [
'toolbar-popover__control',
],
} only %}
<div class="toolbar-popover__wrapper" data-toolbar-popover-wrapper inert>
{% if item.url %}
{% include 'navigation:toolbar-button' with {
attributes: item_link_attributes.setAttribute('href', item.url|render),
html_tag: item_link_tag,
text: item.title,
modifiers: [
'large',
'dark',
],
extra_classes: [
'toolbar-popover__header',
],
} only %}
{% else %}
{% include 'navigation:toolbar-button' with {
attributes: create_attribute(),
modifiers: [
'large',
'dark',
'non-interactive',
],
extra_classes: [
'toolbar-popover__header',
],
html_tag: 'span',
text: item.title,
} only %}
{% endif %}
<ul class="toolbar-menu toolbar-popover__menu">
{{ menus.menu_items(item.below, attributes, 1) }}
</ul>
</div>
</li>
{% endif %}
{% elseif menu_level == 1 %}
<li class="toolbar-menu__item toolbar-menu__item--level-{{ menu_level }}">
{% if item.below is empty %}
{% include 'navigation:toolbar-button' with {
attributes: item_link_attributes.setAttribute('href', item.url|render|default(null)),
text: item.title,
html_tag: item_link_tag,
extra_classes: [
item_link_tag == 'span' ? 'toolbar-button--non-interactive'
],
} only %}
{% else %}
{% include 'navigation:toolbar-button' with {
attributes: create_attribute({
'aria-expanded': 'false',
'data-toolbar-menu-trigger': menu_level,
}),
text: item.title,
modifiers: ['expand--down'],
} only %}
<ul class="toolbar-menu toolbar-menu--level-{{ menu_level + 1 }}" inert>
{{ menus.menu_items(item.below, attributes, menu_level + 1) }}
</ul>
{% endif %}
</li>
{% else %}
<li class="toolbar-menu__item toolbar-menu__item--level-{{ menu_level }}">
{% if item.below is empty %}
{{ link(item.title, item.url, {
'class': [
'toolbar-menu__link',
'toolbar-menu__link--' ~ menu_level,
],
'data-index-text': item.title|first|lower
}) }}
{% else %}
<button
class="toolbar-menu__link toolbar-menu__link--{{ menu_level }}"
data-toolbar-menu-trigger="{{ menu_level }}"
aria-expanded="false"
data-index-text="{{ item.title|first|lower }}"
>
<span data-toolbar-action class="toolbar-menu__link-action visually-hidden">{{ 'Extend'|t }}</span>
<span class="toolbar-menu__link-title">{{ item.title }}</span>
{{ icon('navigation', 'chevron', { class: 'toolbar-menu__chevron', size: 16 }) }}
</button>
<ul class="toolbar-menu toolbar-menu--level-{{ menu_level + 1 }}" inert>
{{ menus.menu_items(item.below, attributes, menu_level + 1) }}
</ul>
{% endif %}
</li>
{% endif %}
{% endfor %}
{% endmacro %}
5 theme calls to navigation-menu.html.twig
- NavigationLinkBlock::build in core/
modules/ navigation/ src/ Plugin/ Block/ NavigationLinkBlock.php - Builds and returns the renderable array for this block plugin.
- NavigationShortcutsBlock::build in core/
modules/ navigation/ src/ Plugin/ Block/ NavigationShortcutsBlock.php - Builds and returns the renderable array for this block plugin.
- NavigationTestBlock::build in core/
modules/ navigation/ tests/ navigation_test_block/ src/ Plugin/ Block/ NavigationTestBlock.php - Builds and returns the renderable array for this block plugin.
- ShortcutLazyBuilder::lazyLinks in core/
modules/ navigation/ src/ ShortcutLazyBuilder.php - The #lazy_builder callback; builds shortcut navigation links.
- WorkspacesLazyBuilder::renderNavigationLinks in core/
modules/ navigation/ src/ WorkspacesLazyBuilder.php - Lazy builder callback for rendering navigation links.
File
-
core/
modules/ navigation/ templates/ navigation-menu.html.twig
View source
- {% import _self as menus %}
- <div class="admin-toolbar__item">
- <h4 class="visually-hidden focusable">{{ title }}</h4>
- <ul class="toolbar-block__list">
- {{ menus.menu_items(items, attributes, 0) }}
- </ul>
- </div>
-
- {% macro menu_items(items, attributes, menu_level) %}
- {% for item in items %}
-
- {% set item_link_tag = 'a' %}
-
- {% if item.url.isRouted %}
- {% if item.url.routeName == '<nolink>' %}
- {% set item_link_tag = constant('\\Drupal\\Core\\GeneratedNoLink::TAG') %}
- {% elseif item.url.routeName == '<button>' %}
- {% set item_link_tag = constant('\\Drupal\\Core\\GeneratedButton::TAG') %}
- {% endif %}
- {% endif %}
-
- {% if item.url.options.attributes is empty %}
- {% set item_link_attributes = create_attribute() %}
- {% else %}
- {% set item_link_attributes = create_attribute(item.url.options.attributes) %}
- {% endif %}
-
- {% set item_id = ('navigation-link--' ~ item.original_link.pluginId)|clean_unique_id %}
- {% if menu_level == 0 %}
- {% if item.below is empty %}
- <li id="{{ item_id }}" class="toolbar-block__list-item">
- {% include 'navigation:toolbar-button' with {
- attributes: item_link_attributes.setAttribute('href', item.url|render|default(null)).setAttribute('data-drupal-tooltip', item.title).setAttribute('data-drupal-tooltip-class', 'admin-toolbar__tooltip'),
- icon: item.icon,
- html_tag: item_link_tag,
- text: item.title,
- modifiers: [
- 'collapsible',
- item_link_tag == 'span' ? 'non-interactive' : null
- ]|filter(v => v is not null),
- } only %}
- </li>
- {% else %}
- <li id="{{ item_id }}" class="toolbar-block__list-item toolbar-popover" data-toolbar-popover>
- {% include 'navigation:toolbar-button' with {
- action: 'Extend'|t,
- attributes: create_attribute({
- 'aria-expanded': 'false',
- 'aria-controls': item_id,
- 'data-toolbar-popover-control': true,
- 'data-has-safe-triangle': true,
- }),
- icon: item.icon,
- text: item.title,
- modifiers: [
- 'expand--side',
- 'collapsible',
- ],
- extra_classes: [
- 'toolbar-popover__control',
- ],
- } only %}
- <div class="toolbar-popover__wrapper" data-toolbar-popover-wrapper inert>
- {% if item.url %}
- {% include 'navigation:toolbar-button' with {
- attributes: item_link_attributes.setAttribute('href', item.url|render),
- html_tag: item_link_tag,
- text: item.title,
- modifiers: [
- 'large',
- 'dark',
- ],
- extra_classes: [
- 'toolbar-popover__header',
- ],
- } only %}
- {% else %}
- {% include 'navigation:toolbar-button' with {
- attributes: create_attribute(),
- modifiers: [
- 'large',
- 'dark',
- 'non-interactive',
- ],
- extra_classes: [
- 'toolbar-popover__header',
- ],
- html_tag: 'span',
- text: item.title,
- } only %}
- {% endif %}
- <ul class="toolbar-menu toolbar-popover__menu">
- {{ menus.menu_items(item.below, attributes, 1) }}
- </ul>
- </div>
- </li>
- {% endif %}
-
- {% elseif menu_level == 1 %}
- <li class="toolbar-menu__item toolbar-menu__item--level-{{ menu_level }}">
- {% if item.below is empty %}
- {% include 'navigation:toolbar-button' with {
- attributes: item_link_attributes.setAttribute('href', item.url|render|default(null)),
- text: item.title,
- html_tag: item_link_tag,
- extra_classes: [
- item_link_tag == 'span' ? 'toolbar-button--non-interactive'
- ],
- } only %}
- {% else %}
- {% include 'navigation:toolbar-button' with {
- attributes: create_attribute({
- 'aria-expanded': 'false',
- 'data-toolbar-menu-trigger': menu_level,
- }),
- text: item.title,
- modifiers: ['expand--down'],
- } only %}
- <ul class="toolbar-menu toolbar-menu--level-{{ menu_level + 1 }}" inert>
- {{ menus.menu_items(item.below, attributes, menu_level + 1) }}
- </ul>
- {% endif %}
- </li>
- {% else %}
- <li class="toolbar-menu__item toolbar-menu__item--level-{{ menu_level }}">
- {% if item.below is empty %}
- {{ link(item.title, item.url, {
- 'class': [
- 'toolbar-menu__link',
- 'toolbar-menu__link--' ~ menu_level,
- ],
- 'data-index-text': item.title|first|lower
- }) }}
- {% else %}
- <button
- class="toolbar-menu__link toolbar-menu__link--{{ menu_level }}"
- data-toolbar-menu-trigger="{{ menu_level }}"
- aria-expanded="false"
- data-index-text="{{ item.title|first|lower }}"
- >
- <span data-toolbar-action class="toolbar-menu__link-action visually-hidden">{{ 'Extend'|t }}</span>
- <span class="toolbar-menu__link-title">{{ item.title }}</span>
- {{ icon('navigation', 'chevron', { class: 'toolbar-menu__chevron', size: 16 }) }}
- </button>
- <ul class="toolbar-menu toolbar-menu--level-{{ menu_level + 1 }}" inert>
- {{ menus.menu_items(item.below, attributes, menu_level + 1) }}
- </ul>
- {% endif %}
- </li>
- {% endif %}
- {% endfor %}
- {% endmacro %}
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.