Score:0

Set the menu link description in hook_entity_presave()

cn flag

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";
    
  }
}
Score:0
in flag

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);
  }
}
websoft avatar
cn flag
Hello, thanks very much. I tried the above but I get the following error?
websoft avatar
cn flag
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 avatar
cn flag
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?
sonfd avatar
in flag
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 avatar
in flag
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](https://stackoverflow.com/questions/536514/when-should-i-use-type-hinting-in-php)
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.