0

i'm maintaining a drupal i didn't developed. I fixed some issues in the menu template (e.g. /themes/custom/{mytheme}/templates/menu--menu-{my-menu-name} )

this template is called at two places in the application, it's rendered in region-header of the drupal site as intended, but is also served as raw HTML content in a specific page to provide the header to another application.

Despite being processed in the same hook ( hook_preprocess_menu ) and rendered by the same template ( /themes/custom/{mytheme}/templates/menu--menu-{my-menu-name} ) i got a slight difference between the two HTML final inputs.

It originates from $variables['items'] in hook_preprocess_menu :

at one point, there's a level 2 items which contains two level 3 items, and in one case (in region--header), the $item['below'] is correctly filled with the 2 sub items, in the other case ( the specific page ), the same $item['below'] is empty. Template debug is on so i can see with the HTML comments that the same template is rendered. the cache has been repeatedly emptied.

I can't really share the dumps here as they're huge, but here is the hook that renders the menu

notes : i left the dump() used to debug $variables['items'] , and i edited some of the source code so my company's name is not showing up

function process_menu_recursive(array &$items) { foreach ($items as &$item) { if (!empty($item['below'])) { process_menu_recursive($item['below']); } if ($entity = get_menu_link_entity($item['original_link'])) { $uuid = $entity->getDerivativeId(); $entity = \Drupal::service('entity.repository')->loadEntityByUuid('menu_link_content', $uuid); $item['field_menu_right_panel'] = $entity->field_menu_right_panel->value; $item['description'] = $entity->getDescription(); } } } function hook_preprocess_menu(&$variables, $hook) { if ($hook == 'menu__menu_{my-menu-name}') { $config = \Drupal::config('ap_commons.settings'); $variables['simulation_url'] = $config->get('ap_commons_simulation_url_recette'); $variables['simulation_texte'] = $config->get('ap_commons_simulation_texte'); $variables['souscrire_texte'] = $config->get('ap_commons_souscrire_texte'); foreach ($variables['items'] as &$item) { if (!empty($item['below'])) { process_menu_recursive($item['below']); } } $request = \Drupal::request(); $pathInfo = $request->getPathInfo(); $display_client_meta = FALSE; $user_java_session = \Drupal::request()->query->all(); dump($variables['items']); exit(); $variables['user_java_session'] = $user_java_session; $variables['#cache']['tags'][] = $login_button_text_hash; $variables['#cache']['max-age'] = 0; } } 

UPDATE :

as the incorrect menu was called in a specific node template (node--header-fragment.html.twig), i went to hook_preprocess_page to see if i could find a new lead :

function hook_preprocess_node(array &$variables) { $node = isset($variables["elements"]["#node"]) ? $variables["elements"]["#node"] : false; $variables['nid'] = 0; if ($node) { if (isset($variables["elements"]["#node"]) && $node !== null && $node->id()) { $variables['nid'] = $node->id(); $node_type = $node->getType(); $function = __FUNCTION__ . '_' . $node_type; if (function_exists($function)) { $function($variables); } } } $variables['request_uri'] = $_SERVER['REQUEST_URI']; $url = Drupal::service('path_alias.manager') ->getAliasByPath(\Drupal::service('path.current')->getPath()); $variables["current_url"] = $url; if (in_array($url, ["/ap/nav/header", "/ap/footer"])) { if ($url == "/ap/nav/header") { // <-- URL of node that renders the menu $menu_name = 'menu-alta-big-menu'; $menu_tree = \Drupal::menuTree(); $parameters = $menu_tree->getCurrentRouteMenuTreeParameters($menu_name); $tree = $menu_tree->load($menu_name, $parameters); $manipulators = array(array('callable' => 'menu.default_tree_manipulators:checkAccess'), array('callable' => 'menu.default_tree_manipulators:generateIndexAndSort'),); $tree = $menu_tree->transform($tree, $manipulators); $menu = $menu_tree->build($tree); dump($tree); dump($menu); exit(); $variables['elements']['mymenu'] = $menu; } $config = Drupal::config('ap_commons.settings'); $variables['footer_social_1'] = $config->get('ap_commons_footer_social_1'); $variables['footer_social_2'] = $config->get('ap_commons_footer_social_2'); $variables['footer_accroche_1'] = $config->get('ap_commons_footer_accroche_1'); $variables['footer_accroche_2'] = $config->get('ap_commons_footer_accroche_2'); $variables['footer_accroche_3'] = $config->get('ap_commons_footer_accroche_3'); $variables['footer_accroche_4'] = $config->get('ap_commons_footer_accroche_4'); $variables['simulation_texte'] = $config->get('ap_commons_simulation_texte'); $variables['souscrire_texte'] = $config->get('ap_commons_souscrire_texte'); } } 

Turns out the whole-menu is re-rendered via \Drupal::menuTree(), using manipulators. the dump of the unordered tree contains my 2 items, but the ordered menu generated by $menu = $menu_tree->build($tree); doesn't

7
  • How are the 2 sections being rendered? I'd look there initially, as for example if its a menu block you can control the max depth. So could be something as simple as that Commented Jun 13, 2024 at 14:14
  • the not working section is rendered in a page node, the template inclusion goes like this : ``` themes/custom/{mytheme}/templates/page--no--wrapper.html.twig themes/custom/{mytheme}/templates/regions/region.html.twig themes/custom/{mytheme}/templates/blocks/block.html.twig themes/custom/{mytheme}/templates/nodes/node--header--fragment.html.twig themes/custom/{mytheme}/templates/menu--menu-{menu-name}.html.twig ``` Commented Jun 13, 2024 at 14:44
  • the working section is rendered in all drupal pages, via a block inside region--header (sorry for the prev. comment i wanted to include all templates but the formatting is limited in comments it's not very readable) Commented Jun 13, 2024 at 14:51
  • Editors can define in the admin UI if children should be rendered or not (should not matter here because same menu). And site Admins can change levels of rendered menus when placing the block in the regions (even the same menu can be placed with different levels in different regions). Maybe those 2 blocks are simply configured differently? Commented Jun 13, 2024 at 14:54
  • this is not related to a block configuration, but checking how the templates inclusions went was a good idea. I found a very suspicious if() condition in hook_preprocess_node, i'm investigating Commented Jun 13, 2024 at 15:21

1 Answer 1

0

Found the issue in hook_preprocess_node :

i replaced $parameters = $menu_tree->getCurrentRouteMenuTreeParameters($menu_name); with a clean object : $parameters = new \Drupal\Core\Menu\MenuTreeParameters();

and my issue is gone. It's still very obscure to me, the method name suggests that my menu is rendered differently depending on route ? i don't see any customization options in Drupal's back-office that allows it, so i can use an explanation on the subject.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.