Reputation: 444
I have a menu tree like, Continent as parent and it has sub menu of Asia, Australia, Europe. etc and each continent has sub men tree of countries.
In a node page and in a block I would like to list all the menus and sub menu trees of 'Continent'.
In Drupl 7 we should use menu_tree_all_data, in Drupal 8 it should be done through 'MenuLinkTreeElement' but I am not very clear about it and how to use it.
Please comment.
Upvotes: 4
Views: 8388
Reputation: 122
$tree = \Drupal::menuTree()->load('main', new \Drupal\Core\Menu\MenuTreeParameters());
function loadMenu($tree) {
$menu = [];
foreach ($tree as $item) {
if($item->link->isEnabled()) {
$menu[] = [
'weight' => $item->link->getWeight(),
'title' => $item->link->getTitle(),
'url' => $item->link->getUrlObject(),
'has_children' => $item->hasChildren,
'children' => loadMenu($item->subtree),
];
}
}
return $menu;
}
For mor information: https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Menu%21MenuLinkBase.php/class/MenuLinkBase/8.9.x
Upvotes: 0
Reputation: 507
If you use Simplify Menu then use following code in your .html.twig
file:
<div class="menu-container">
{% set items = simplify_menu('main') %}
<ul class="list-container">
{% for menu_item in items.menu_tree %}
<li class="{{ item_class }} navigation__item">
<a href="{{ menu_item.url }}" class="{{ menu_item.text }}">{{ menu_item.text }}</a>
{% if menu_item.submenu %}
<ul>
{% for sub_menu_item in menu_item.submenu %}
<li>
<a href="{{ sub_menu_item.url }}">{{ sub_menu_item.text }}</a>
</li>
{% endfor %}
</ul>
{% endif %}
</li>
{% endfor %}
</ul>
</div>
NOTE: This code has been checked in Drupal Core 8.6 and Simplify Menu 8.x-2.0
Upvotes: 4
Reputation: 391
You can either use Simplify Menu Module and then you can render menu tree as an array in twig template like this
{% set items = simplify_menu('main') %}
{% for menu_item in items.menu_tree %}
<li>
<a href="{{ menu_item.url }}">{{ menu_item.text }}</a>
{% if submenuLevel1Item.description %}
<ul>
{% for sub_menu_item in menu_item.submenu %}
<li>
<a href="{{ sub_menu_item.url }}">{{ sub_menu_item.text }}</a>
</li>
{% endfor %}
</ul>
{% endif %}
</li>
{% endfor %}
For more parameters kint(items)
OR (If you don't wish to install the module) you will need to preprocess menu items and pass it to the twig as Below
$menu_parameters = new \Drupal\Core\Menu\MenuTreeParameters();
// If you need to set depth of the tree
$menu_parameters->setMaxDepth(2);
// If you need only enabled links
$menu_parameters->onlyEnabledLinks();
$menus = \Drupal::menuTree()->load('Your Menu name', $menu_parameters);
$menuItems = [];
foreach ($menus as $key => $value) {
$menuUUIDArray = explode(':', $key);
$uuid = $menuUUIDArray[1];
$menuItem = [];
// If its a multi lingual site
$languageCode = \Drupal::languageManager()->getCurrentLanguage()->getId();
$menu_content = current(\Drupal::entityManager()->getStorage('menu_link_content')->loadByProperties(array('uuid' => $uuid)));
if ($menu_content->hasTranslation($languageCode)) {
$menu_content = $menu_content->getTranslation($languageCode);
}
$url = $menu_content->getUrlObject();
$menuItem['title'] = $menu_content->get('title')->value;
$menuItem['link'] = ($url->toString() == '') ? '#' : $url->toString();
$menuItem['weight'] = $menu_content->get('weight')->value;
if ($value->hasChildren) {
$subTreeArray = $value->subtree;
foreach ($subTreeArray as $key => $child) {
}
// use foreach OR recursion to get the values
$menuItem['children'] = ......
}
$menuItems = $menuItem;
}
Upvotes: 1