I'm struggling to figure out relationship between MenuLink and MenuLinkContent.

I'm creating new menu item like:

$menuItem = MenuLinkContent::create($params);

I can also query those elements like:

$menuItems = \Drupal::entityTypeManager()->getStorage('menu_link_content')->loadByProperties(['link.uri' => "internal:$path"]);

And that works well. Now if I need one of those object I want to get it's "siblings" - other object that share same parent. I have some weird structure:

$this->menuLinkManager = \Drupal::service('plugin.manager.menu.link');
$parentId = $menuItem->getParentId();
$parent = $this->menuLinkManager->createInstance($this->menuLinkManager->getDefinition($parentId)['id']);

And here I'm getting it's parent, but it's not MenuLinkContent object any more but instance of MenuLinkInterface. It has some fields as MenuLinkContent, but not all. I.e. I don't know how to get link path and similar.

There I can go further:

$siblings = $this->menuLinkManager->getChildIds($parent->getPluginId());

But main question is how to get MenuLinkContent when I have that MenuLinkInterface object?

Sub-question - why oh why is needed this parallel menu system and parallel menu classes?

  • 1
    Interfaces are not objects, they are the definition of the requirements of the class that implements the interface. MenuLinkContent implements MenuLinkInterface, its likely that the object you are working with is actually a MenuLinkContent object.
    – Jaypan
    Commented Mar 11, 2022 at 16:37
  • See drupal.stackexchange.com/questions/259739/…
    – 4uk4
    Commented Mar 11, 2022 at 16:43
  • The MenuLinkContent class implements MenuLinkInterface and ContainerFactoryPluginInterface.
    – apaderno
    Commented Mar 11, 2022 at 17:53
  • Given that the second interface defines only the create() method, is there any method you need that isn't defined in the MenuLinkInterface interface?
    – apaderno
    Commented Mar 11, 2022 at 17:54
  • (Also, be careful not to confuse the MenuLinkContent class, which implements a plugin, with the MenuLinkContent class that is an entity class.)
    – apaderno
    Commented Mar 11, 2022 at 17:57

1 Answer 1

$siblings = $this->menuLinkManager->getChildIds($parent->getPluginId());

But main question is how to get MenuLinkContent when I have that MenuLinkInterface object?

There are two types of plugin IDs. Without or with a colon :.

Non-derived plugins

Without they point directly to a single plugin definition.

For example the admin menu


consists mainly of non-derived menu links which IDs you find in *.links.menu.yml files.

Derived plugins

With colon the first part is the base plugin ID and the second part is the derivative ID.

For example, if you have created a multi-level main menu from UI and apply this command on a menu parent


You get links like this


for the base plugin MenuLinkContent (BTW also defined in a YAML file) with a deriver for MenuLinkContent entities (identified by UUID).

$entity = \Drupal::service('entity.repository')
  ->loadEntityByUuid('menu_link_content', '421a421a-cb1d-33e7-a810-1e7341f7906b');

If you have already a plugin instance you can get the UUID from the plugin object. See https://drupal.stackexchange.com/a/235769/47547

  • Thank you. I figured it out after following link from your comment but it's definitely good to have complete answer. IMHO it's unnecessary complicated: for some queries I need menu link manager, for others entity repository. Sometime id is just a number, like a node id, other time it's content_type:uuid. Some time you can access all the properties, sometime you can't. Again, IMHO having single repository, single id format, single class and always all fields available would make life much more easier. And worse, it's hard to find proper documentation/example. Forgive my naive point of view.
    – MilanG
    Commented Mar 14, 2022 at 7:17

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.