I'm attempting to create my first module, which doesn't do much. I'm looking to:

  1. Add a couple of extra fields to a menu item.
  2. Save them in to the menu_link_content_data table.
  3. Access them within theme templates.
  4. Remove the items from the menu_link_content_data table when the module is uninstalled.

I've managed (after A LOT of reading through the awful docs) to get 1-3 completed, but 4 is giving me issues.

Does anyone know how to do this?

I've tried the following in my_module.module file:

function detailed_menu_uninstall() {
  // Deletes the field storage for the 'detailed_menu_heading' base field.
  $definition = \Drupal::service('entity_field.manager')->getFieldStorageDefinitions('menu_link_content')['detailed_menu_heading'];

Where detailed_menu_heading is the name of the table that was added to the menu_link_content_data table (using HOOK_entity_base_field_info(), with $fields['detailed_menu_heading'] = BaseFieldDefinition::create()). But it doesn't seem to work.

If anyone could give some advice (while I still have a few homer-esque strands of hair left), that would be awesome!



After a few more hours of head scratching and hair pulling, I think I've found (or so it would seem) the answer... I'm writing this for myself, as well as anyone else who might stumble across it by route of the all-mighty Google.

From what I can gather, the EntityManager Service has been split up in to several parts. As a result, the bit we're interested in lies within the Entity Field Manager service / class.

We can use this to grab the definition (which I believe is Drupal for - the set of instructions that provide relevant information about an entity [or part thereof]) of our custom entity field.

Now that we have a Drupal readable way of referencing the entity field we're interested in manipulating, we need to actually manipulate it.

Soo... There are a few ways to do this, but I believe the best way is to make use of Drupal's Field Definition Listener service, that seems to do the job we're after. What this listener will do is handle getting rid of all the places that the entity field has been buried away within Drupal itself. From the sounds of the service name it should be using the event dispatcher system somewhere, somehow; although, looking at the source I can't find anywhere that actually does this? (this is in contrast to field_storage_definition.listener, which does dispatch an event, but didn't seem to work, and would white screen with an SQL error, complaining that it can't find the given field when used...)

With these two pieces of the puzzle, it's just a case of putting them together to get the functionality working correctly.

I ended up with:

function detailed_menu_uninstall() {

  // Grabs the entity Field Manager service.
  $entityFieldManager = Drupal::service('entity_field.manager');

  // Grabs the Field Definition listener.
  $fieldDefinitionListener = \Drupal::service('field_definition.listener');

  // Ensures(?) that the field storage for the 'detailed_menu_heading' base field is deleted
  // properly when the module is uninstalled.
  $definition = $entityFieldManager->getFieldStorageDefinitions('menu_link_content')['detailed_menu_heading'];

One thing to note is that if I add more definitions to be installed, and consequently uninstalled in this hook, they don't actually need to be put in the uninstall hook, and I'm not sure why... It's as if Drupal just needs a nudge to be told that some things need to be removed from the entity properly, and Drupal does the rest to check what that is? I'm really not sure.

| improve this answer | |

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.