In mytheme_preprocess_menu(), I am altering the main menu:

function mytheme_preprocess_menu(&$variables, $hook) {
  $node = \Drupal::routeMatch()->getParameter('node');
  if ('menu__main' == $hook) {
    if ($node) {
      _mytheme_menu_replace_with_project_items($node, $variables['items']);

In _mytheme_menu_replace_with_project_items(), I check whether the current node is a project node, and show that node's submenu instead.

When I visit the node the menu gets displayed, but when I add another node with another project reference, the menu of the former node gets displayed.

How can I correctly cache that?

I tried with the following code, but it didn't work.

$variables['#cache']['tags'][] = 'node:' . $node->id();
$variables['#cache']['contexts'][] = 'route.name';
$variables['#cache']['contexts'][] = 'theme';

1 Answer 1


Okay, so this combination worked...

$variables['#cache']['tags'] = ['node:' . $node->id()];
$variables['#cache']['contexts'] = ['route', 'theme'];
$variables['#cache']['keys'] = ['entity_view', 'node', $node->id()];

I dont see a huge difference to my first attempt but whatever!

  • $variables['#cache'] should not even be used, since $variables is not a render array.
    – apaderno
    Commented Jul 26, 2016 at 8:30
  • $variables['#cache']['contexts] existed in the first place, i was just adding contexts and tags
    – Alex
    Commented Jul 26, 2016 at 8:38
  • 1
    @Alex: It is the context route what makes the difference. route.name is without parameters and is the same for all nodes.
    – 4uk4
    Commented Jul 26, 2016 at 9:16

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.