I have a menu with a machine name of menu-principal, which in turn has a theme hook of menu__menu_principal and a template of menu--menu-principal.html.twig. I'm trying to inject another menu into the template in a variable so that I can render it in this menu template but so far have been unsuccessful.

I tried to add a preprocess function to my MY_THEME.theme but this doesn't seem to work. My code is as follows:

 * Implements hook_preprocess_HOOK().
function MYTHEME_preprocess_menu__menu_principal(&$variables) {
  $menu_tree_service = \Drupal::service('menu.link_tree');
  $menu_name = 'menu-quicklinks';
  $menu_parameters = new \Drupal\Core\Menu\MenuTreeParameters();
  $tree = $menu_tree_service->load($menu_name, $menu_parameters);
  $variables['quicklinks'] = $tree;

When I go to to the template and use {{ kint() }} to dump out the defined variables, I don't see the variable. I only see the following:

{{ kint() }} output in menu--menu-principal.html.twig

I then found this answer and tried the following, using the example from the answer there:

 * Implements hook_theme_registry_alter().
function MY_THEME_theme_registry_alter(&$theme_registry) {
  $theme_registry['menu__menu_principal']['variables']['quicklinks'] = [];

I used dd() to verify that $theme_registry['menu__menu_principal']['variables'] existed and that the variables were definitely being set in the theme registry, but it still didn't work.

  • 1
    Your hook preprocess won't get called. Preprocess hook names don't work like templates with interpolated suggestions. Call the function MYTHEME_preprocess_menu and add a test in it for the menu you want. Jul 13, 2018 at 11:27
  • @AlfredArmstrong Thanks for the suggestion, I will try that. It’s strange that I get {{ kint () }} output for it, though, so it does seem to fire. It perhaps just doesn’t do anything. Jul 13, 2018 at 13:20
  • Name suggestions do work for templates, so your specific template is called, just not for preprocess functions. Jul 13, 2018 at 13:26

1 Answer 1


I had the same issue, but i was using {{ dump() }} to debug the template

The problem

I have the same arguments when i am using {{ dump() }} inside macro tags. For example:

   {% macro menu_links(items, attributes, menu_level ) %}
       {{ dump() }}
       ... code ...
   {% endmacro %}

If you focus on function menu_links(), you realize that variables are available in your degug trace. So, the macro tags have isolated the bunch of code and variables can't be accessed.

The solution

If you place the debug code outside of macro tags, you can see the variables that has been passed throught a preproccess function. For example:

   # You can see here your variables
   {{ dump() }}

   {% macro menu_links(items, attributes, menu_level ) %}
       ... code ...
   {% endmacro %}

How can you pass variables to macro ?

There are an invocation of menu_links() in template, so you only need to add all the arguments you want to pass them to the macro.

   {{ menus.menu_links(items, attributes, 0, my_custom_argument ) }}

   {% macro menu_links(items, attributes, menu_level, my_custom_argument ) %}
       ... code ...
   {% endmacro %}

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.