Senthil
Senthil

Reputation: 444

Displaying sub menu tree in Drupal 8

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

Answers (3)

Nik Ral
Nik Ral

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

johirpro
johirpro

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

Razeem Ahmad
Razeem Ahmad

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

Related Questions