0

How do I create a menu link programmatically to a node that I can use as a parent for other links?

In MYMODULE.links.module, I defined some links for my navbar:

MYMODULE.parent-fruits:
  title: 'Fruits'
  url: internal:/fruits
  weight: 0
  menu_name: food
MYMODULE.fruits-apple:
  title: 'Apple'
  parent: MYMODULE.parent-fruits
  route_name: view.fruits.apple
  weight: 5
  menu_name: food
MYMODULE.parent-vegetables:
  route_name: view.vegetables.page-main
  weight: 10
  menu_name: food
MYMODULE.vegetables-asparagus:
  parent: MYMODULE.parent-vegetables
  title: 'Asparagus'
  url: internal:/admin/structure/taxonomy/manage/card_group_private/add
  weight: 5
  menu_name: food

In this case, I expect to have a menu that looks like this:

  • Fruits (child-> Apple)
  • Vegetables (child-> asparagus)

When I go to the parent page, the link to the child should appear in the navbar menu (the parent tree should be expanded).

But what I actually get is:

  • Fruits (no children)
  • Vegetables (child-> asparagus)

The problem is caused by defining the menu link with url instead of route_name. I know this because when I change the parent of fruits-apple to parent: MYMODULE.parent-vegetables, then I see Apple as a child of Vegetables.

When I remove parent from Apple, then it appears in the menu (without a parent), so I know the link is defined correctly.

I can also create the Fruits / Apple links in the menu UI, and those work correctly.

Regarding parent: the documentation says this:

Determining the parent menu_link name can be a little tricky at first. If you know the path of the parent menu item, you would need to search for it in all available *.routing.yml files (most text editors and IDEs should allow you to search all files in a project) and find the route name for that path. Then, you would need to search for the route name in all available *.links.menu.yml files. The menu_link whose route_name matches is your link. Alternatively, if you know which module is defining the parent menu link (or one of the parent menu link's children), you can go straight to that module and perform your search.

Since these are node links, I checked node.routing.yml in the core node module, but I couldn't find the route to node pages.

So: how do I create a menu link programmatically to a node that I can use as a parent for other links?

2
  • I think changing from url to route_name is the solution, you normally use url only for external links.
    – 4k4
    Jul 24 '20 at 7:04
  • @4k4 Ok, how do I get the route name for something like /node/7? I updated my question with the explanation I found in the docs, which I don't really understand. Jul 24 '20 at 7:08
1

I think changing from url to route_name is the solution, you normally use url only for external links.

You don't find entity routes in static yml files because they are created dynamically. You could use the Devel module and visit

/devel/routes

or from the command line with Drupal Console:

drupal debug:router

See https://drupalconsole.com/docs/en/commands/debug-router

Then when you have found the route name you have to add the entity id as route parameter.

Example:

mymodule.links.menu.yml

mymodule.node7:
  title: 'Node 7'
  route_name: 'entity.node.canonical'
  route_parameters: { node: '7' }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.