0

How do I update the menu link description with hook_ENTITY_TYPE_presave()?

I can print out the menu link title and menu link description with the following code.

kint($entity->menu['title']);  
kint($entity->menu['description']);

I only want to update the menu link description when the menu link title is not NULL so the menu link will exist. In fact, I'm wanting to copy the menu link title into the menu link description (when the menu link title is not empty).

The following code updates the node title, but I would like to know how to update the menu link description.

/**
 * Implements hook_ENTITY_TYPE_presave().
 */
function hook_entity_presave(Drupal\Core\Entity\EntityInterface $entity) {
  
  if ($entity->bundle() == 'page') {

    // save a different value as title
    $entity->title = 'New Title';

    // The below outputs the 'title' and 'description' of the menu link
    kint($entity->menu['title']);
    kint($entity->menu['description']);

    // how do I update the menu description?
    // the below doesn't work?
    $entity->menu['description'] = "New menu link description";
    
  }
}
0

Menu links are entities themselves. Unless you've done something special to create a new menu link entity type, they will be entity type menu_link_content.

You can use hook_ENTITY_TYPE_presave() to make your change. Note that when you see an all-caps section of a hook, that means it should be replaced by a specific value, e.g. hook_node_presave() or hook_menu_link_content_presave(). The difference between these and hook_entity_presave() is that the latter will fire when any entity is saved, while the entity type specific hooks will only fire when an entity of that specific type is saved.

Given all of this, something like the following should work:

// Top of file.
use Drupal\menu_link_content\MenuLinkContentInterface;

/**
 * Ensure that any menu link with a title has a description that matches.
 *
 * Implements hook_ENTITY_TYPE_presave().
 */
MY_MODULE_menu_link_content_presave(MenuLinkContentInterface $menu_link) {
  if (!$menu_link->title->isEmpty()) {
    $menu_link->set('description', $menu_link->title->value);
  }
}
5
  • Hello, thanks very much. I tried the above but I get the following error?
    – websoft
    Jul 2 at 15:21
  • TypeError: Argument 1 passed to addmenudesc_menu_link_content_presave() must be an instance of Drupal\menu_link_content\Entity\MenuLinkContentInterface, instance of Drupal\menu_link_content\Entity\MenuLinkContent given in addmenudesc_menu_link_content_presave() (line 11 of /Users/mikereid/Sites/dev/d8/craftedbydesign/web/modules/custom/addmenudesc/addmenudesc.module)
    – websoft
    Jul 2 at 15:21
  • I've used function addmenudesc_menu_link_content_presave($menu_link) { } and now it appears to work perfectly. I omitted the MenuLinkContentInterface? Is there any reason why it should have the MenuLinkContentInterface?
    – websoft
    Jul 2 at 16:03
  • Oh, my mistake. I had the path wrong for the MenuLinkContentInterface class. I updated the answer - the correct use statement is use Drupal\menu_link_content\MenuLinkContentInterface;
    – sonfd
    Jul 2 at 16:15
  • It's just helpful to type your parameters when you can. A side effect is that it helps your IDE know what the variable is, but more importantly it make sure that the variable passed to the function is the type that the function expects (or errors). There are some nice points on When should I use type hinting in PHP
    – sonfd
    Jul 2 at 16:20

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.