0

Hi I have 3 menus on my site and for display on mobile/tablet I would like to merge these menus to only 1 menu. Do you know how to do it. I tried to use menu_tree_all_data

and then merge them but I get Call to undefined function menu_tree_all_data. I'am confused that the function doesn't exist.

1

1 Answer 1

1

As I'm also looking for a solution to this issue I've come a bit further and maybe it will get you in the right direction.

To load a menu in Drupal 8 you can put this in a theme_preprocess_page in your .theme-file.

  $menu_tree = \Drupal::menuTree();
  $menu_name = 'main';

  // Build the typical default set of menu tree parameters.
  $parameters = $menu_tree->getCurrentRouteMenuTreeParameters($menu_name);

  // Load the tree based on this set of parameters.
  $tree = $menu_tree->load($menu_name, $parameters);

  // Transform the tree using the manipulators you want.
  $manipulators = array(
    // Only show links that are accessible for the current user.
    array('callable' => 'menu.default_tree_manipulators:checkAccess'),
    // Use the default sorting of menu links.
    array('callable' => 'menu.default_tree_manipulators:generateIndexAndSort'),
  );
  $tree = $menu_tree->transform($tree, $manipulators);

  // Finally, build a renderable array from the transformed tree.
  $menu = $menu_tree->build($tree);
  $menu_html = \Drupal::service('renderer')->renderPlain($menu);

I have not yet worked out how to merge different menus into one big menu but I will let you know if I come up with a solution. You can find out more about the code above at Drupal 8.2.x » menu.api.php which is where I found it.

Ok, I now have found the solution which I found in the module Responsive and off-canvas menu

  $menus = array("main-menu","footer-menu","utility-menu");

  $combined_tree = array();
  $menu_tree = \Drupal::menuTree();
  $parameters = $menu_tree->getCurrentRouteMenuTreeParameters(trim($menus[0]));
  $manipulators = array(
    // Show links to nodes that are accessible for the current user.
    array('callable' => 'menu.default_tree_manipulators:checkNodeAccess'),
    // Only show links that are accessible for the current user.
    array('callable' => 'menu.default_tree_manipulators:checkAccess'),
    // Use the default sorting of menu links.
    array('callable' => 'menu.default_tree_manipulators:generateIndexAndSort'),
  );
  // Force the entire tree to be build by setting expandParents to an
  // empty array.
  $parameters->expandedParents = array();
  // Iterate over the menus and merge them together.
  foreach($menus as $menu_name) {
    $tree_items = $menu_tree->load(trim($menu_name), $parameters);
    $tree_manipulated = $menu_tree->transform($tree_items, $manipulators);
    $combined_tree = array_merge($combined_tree, $tree_manipulated);
  }

  $menu = $menu_tree->build($combined_tree);

  $vars['mobile_menu'] = array(
    '#prefix' => '<div class="off-canvas-wrapper"><div id="off-canvas">',
    '#suffix' => '</div></div>',
    '#markup' => \Drupal::service("renderer")->renderRoot($menu),
  );

If you put this in your theme_preprocess_page in your .theme-file you could then in your page.html.twig print the twig variable {{ mobile_menu }}.

2
  • Make sure $vars corresponds to the function parameter: MYTHEME_preprocess_page(&$vars){ } Commented Nov 15, 2016 at 13:02
  • Also '#prefix' and '#suffix' seem to break things for me... Not had time to look into this... :) Commented Nov 15, 2016 at 13:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.