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 }}
.