I have seen How do I create menu links programmatically? but how do I update or delete menu items in Drupal 8?
By programmatically, I mean dynamically; YAML configuration files are not going to help.
Drupal Answers is a question and answer site for Drupal developers and administrators. It only takes a minute to sign up.
Sign up to join this communityI have seen How do I create menu links programmatically? but how do I update or delete menu items in Drupal 8?
By programmatically, I mean dynamically; YAML configuration files are not going to help.
First you will have to load the entity. Either way works:
$menu_link = MenuLinkContent::load($menu_link_id);
or ...
$menu_link = \Drupal::entityTypeManager()->getStorage('menu_link_content')->load($menu_link_id);
Next you can update value using set()
method or through the magic method __set...
$menu_link->expanded = TRUE;
To save, simply call the save()
method.
To delete, simply call the delete()
method.
I had to do some thing like ....
//menuLinkManager = 'plugin.manager.menu.link' $result = $this->menuLinkManager->loadLinksByRoute('entity.node.canonical', ['node' => $node->id()]); foreach ($result as $menu_item) { if (is_object($menu_item)) { $id = $menu_item->getPluginDefinition()['metadata']['entity_id']; $menu_link = $this->entityTypeManager->getStorage('menu_link_content')->load($id); $menu_link->enabled = 0; $menu_link->save()
Probably too late I did like:
$menu_handler = \Drupal::service('menu.link_tree')
->load("menu-name", new \Drupal\Core\Menu\MenuTreeParameters());
foreach($menu_handler as $key=>$value) {
if('Name' == $value->link->getTitle()) {
$link = $value->link;
$link->updateLink(
[
'enabled'=>'1',
'title'=>'New Name'
],
true
);
}
}
This is how i delete all the links in a particular menu like footer
$old_menu_links = \Drupal::entityTypeManager()->getStorage('menu_link_content')
->loadByProperties(['menu_name' => 'footer']);
foreach ($old_menu_links as $old_menu_link) {
$old_menu_link->delete();
}
And to update existing menu,
$menu_links = \Drupal::entityTypeManager()->getStorage('menu_link_content')
->loadByProperties(['menu_name' => 'footer']);
foreach ($menu_links as $menu_link) {
if ($menu_link->gettitle() == 'old-title') {
$menu_link->set('title', 'new-title');
$menu_link->save();
}
}
This turned out to be insanely complicated. Apparently not every menu link is a MenuLinkContent
object. Sometimes it is a MenuLinkDefault
object. In that case, you cannot use ->set()
or ->save()
. This is the most complete answer to cover both cases. Put this inside of an hook_update_n()
and change $disabled_routes
and $menu
to your needs. In this example I am disabling menu links.
$disable_routes = [
'<front>',
'view.frontpage.page_1',
'private_message.private_message_page',
'view.opigno_calendar.page_month',
];
$menu_name = 'main';
$menu_link_manager = \Drupal::service('plugin.manager.menu.link');
$menu_link_tree_elements = \Drupal::service('menu.link_tree')
->load($menu_name, new \Drupal\Core\Menu\MenuTreeParameters());
foreach ($disable_routes as $disable_route) {
foreach ($menu_link_tree_elements as $key => $menu_link_tree_element) {
$menu_link_default = $menu_link_tree_element->link;
$plugin_definition = $menu_link_default->getPluginDefinition();
$link_route = $plugin_definition['route_name'];
if ($link_route == $disable_route) {
$uuid = $menu_link_default->getDerivativeId();
if (!empty($uuid)) {
$menu_link_content = \Drupal::service('entity.repository')
->loadEntityByUuid('menu_link_content', $uuid);
$menu_link_content->set('enabled', 0);
$menu_link_content->save();
}
else {
$menu_link = $menu_link_manager->getDefinition($key);
$menu_link['enabled'] = 0;
$menu_link_manager->updateDefinition($key, $menu_link);
// Not sure if this is necessary.
$menu_link_default->updateLink(
[
'enabled' => 0,
],
true
);
}
}
}
}