All steps described here work for me with some minor modifications.
GOAL: show main menu in both header and footer region, but use a different template file for both (based on their region).
PREMISE: your theme has regions (like header and footer) and you have used the drupal block system to place the main menu in both your header as in your footer.
I did this in mytheme.theme file:
Dont forget to add the Block use statement in the beginning of your .theme file:
use Drupal\block\Entity\Block;
Now here's the magic for region based menu templates. Also inside your .theme file:
/**
* Implements hook_preprocess_HOOK().
*
* Pass block region value to content so this can be used in
* MYTHEME_theme_suggestions_menu_alter.
*/
function MYTHEME_preprocess_block(&$variables) {
if (isset($variables['elements']['#id'])) {
$region = Block::load($variables['elements']['#id'])->getRegion();
$variables['content']['#attributes']['region'] = $region;
}
}
/**
* Implements hook_theme_suggestions_HOOK_alter().
*
* Provide region based menu suggestions.
*/
function MYTHEME_theme_suggestions_menu_alter(&$suggestions, array $variables) {
if (isset($variables['attributes']['region'])) {
$suggestions[] = 'menu__' . $variables['menu_name'] . '__' . $variables['attributes']['region'];
}
}
RESULT when inspecting the main menu inside the header:
<!-- FILE NAME SUGGESTIONS:
* menu--main.html.twig
* menu--main--header.html.twig
* menu.html.twig
-->
RESULT when inspecting the main menu inside the footer:
<!-- FILE NAME SUGGESTIONS:
* menu--main.html.twig
* menu--main--footer.html.twig
* menu.html.twig
-->