- Issue created by @borutpiletic
- ๐บ๐ฆUkraine lobodacyril
Some time ago, Drupal Core added a bundle field to content menu items, and by default, it's always the same as the menu name. Unfortunately, no one noticed that, and the module created menu items without a bundle, and the core changed the bundle with the "menu_link_content" which is the entity name. Because of that, you can't translate menu items. If your menu is "main_menu", and you set translation for that, the core identifies menu items you created via this module as "menu_link_content" and this bundle doesn't have translation settings. To solve this, all the bundles should be the same as the menu names. This update did this.
I couldn't reproduce this issue you experienced, please provide more information about your menu names, menu items, and maybe screenshots what happened after update.
- ๐ซ๐ฎFinland Alexander Tallqvist
We are experiencing the same issue on our multilingual Drupal site running Drupal 10.3.11.
Default language: Finnish (FI)
Translated languages: English (EN) and Swedish (SV)
Issue Details
After applying the latest version of
taxonomy_menu_ui
and running database updates, we encountered the following problems:1. Fatal Error When Editing or Unpublishing Translated Nodes
Attempting to edit or unpublish a translated version of a node (SV or EN) results in a fatal error when saving:
InvalidArgumentException: A translation already exists for the specified language (sv). in Drupal\Core\Entity\ContentEntityBase->onChange() (line 840 of /app/web/core/lib/Drupal/Core/Entity/ContentEntityBase.php).
#0 /app/web/core/lib/Drupal/Core/Entity/Plugin/DataType/EntityAdapter.php(140): Drupal\Core\Entity\ContentEntityBase->onChange('langcode') #1 /app/web/core/lib/Drupal/Core/TypedData/Plugin/DataType/ItemList.php(82): Drupal\Core\Entity\Plugin\DataType\EntityAdapter->onChange('langcode') #2 /app/web/core/lib/Drupal/Core/Field/FieldItemList.php(107): Drupal\Core\TypedData\Plugin\DataType\ItemList->setValue(Array, true) #3 /app/web/core/lib/Drupal/Core/Entity/ContentEntityBase.php(657): Drupal\Core\Field\FieldItemList->setValue(Array, true) #4 /app/web/core/modules/menu_ui/menu_ui.module(109): Drupal\Core\Entity\ContentEntityBase->set('langcode', 'sv') #5 /app/web/core/modules/menu_ui/menu_ui.module(349): _menu_ui_node_save(Object(Drupal\node\Entity\Node), Array) #6 [internal function]: menu_ui_form_node_form_submit(Array, Object(Drupal\Core\Form\FormState)) #7 /app/web/core/lib/Drupal/Core/Form/FormSubmitter.php(129): call_user_func_array('menu_ui_form_no...', Array) #8 /app/web/core/lib/Drupal/Core/Form/FormSubmitter.php(67): Drupal\Core\Form\FormSubmitter->executeSubmitHandlers(Array, Object(Drupal\Core\Form\FormState)) #9 /app/web/core/lib/Drupal/Core/Form/FormBuilder.php(597): Drupal\Core\Form\FormSubmitter->doSubmitForm(Array, Object(Drupal\Core\Form\FormState)) #10 /app/web/core/lib/Drupal/Core/Form/FormBuilder.php(326): Drupal\Core\Form\FormBuilder->processForm('node_page_edit_...', Array, Object(Drupal\Core\Form\FormState)) #11 /app/web/core/lib/Drupal/Core/Controller/FormController.php(73): Drupal\Core\Form\FormBuilder->buildForm(Object(Drupal\node\NodeForm), Object(Drupal\Core\Form\FormState)) #12 [internal function]: Drupal\Core\Controller\FormController->getContentResult(Object(Symfony\Component\HttpFoundation\Request), Object(Drupal\Core\Routing\RouteMatch)) #13 /app/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(123): call_user_func_array(Array, Array) #14 /app/web/core/lib/Drupal/Core/Render/Renderer.php(638): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() #15 /app/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(121): Drupal\Core\Render\Renderer->executeInRenderContext(Object(Drupal\Core\Render\RenderContext), Object(Closure)) #16 /app/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(97): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array) #17 /app/vendor/symfony/http-kernel/HttpKernel.php(181): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() #18 /app/vendor/symfony/http-kernel/HttpKernel.php(76): Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object(Symfony\Component\HttpFoundation\Request), 1) #19 /app/web/modules/contrib/force_password_change/src/Service/ForcePasswordChangeRedirectMiddleware.php(43): Symfony\Component\HttpKernel\HttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #20 /app/web/core/lib/Drupal/Core/StackMiddleware/Session.php(53): Drupal\force_password_change\Service\ForcePasswordChangeRedirectMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #21 /app/web/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(48): Drupal\Core\StackMiddleware\Session->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #22 /app/web/core/lib/Drupal/Core/StackMiddleware/ContentLength.php(28): Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #23 /app/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(106): Drupal\Core\StackMiddleware\ContentLength->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #24 /app/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(85): Drupal\page_cache\StackMiddleware\PageCache->pass(Object(Symfony\Component\HttpFoundation\Request), 1, true) #25 /app/web/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(48): Drupal\page_cache\StackMiddleware\PageCache->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #26 /app/web/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(51): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #27 /app/web/core/lib/Drupal/Core/StackMiddleware/AjaxPageState.php(36): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #28 /app/web/core/lib/Drupal/Core/StackMiddleware/StackedHttpKernel.php(51): Drupal\Core\StackMiddleware\AjaxPageState->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #29 /app/web/core/lib/Drupal/Core/DrupalKernel.php(741): Drupal\Core\StackMiddleware\StackedHttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true) #30 /app/web/index.php(19): Drupal\Core\DrupalKernel->handle(Object(Symfony\Component\HttpFoundation\Request)) #31 {main}
2. Menu Link Text Overwritten After Fatal Error
After triggering the fatal error, the menu link text of the original (FI) translation is overwritten with the text from the edited translation.
Example:
Original FI node menu link text: "Hei maailma!"
Translated EN node menu link text: "Hello world!"
If we attempt to unpublish the EN version, the fatal error occurs.
After this, the FI node's menu text changes to "Hello world!" instead of staying as "Hei maailma!".Potential fix
Adding the following update hook to a module and running database updates seems to fix the issue for use:
function hook_update(): void { $entities = \Drupal::entityTypeManager() ->getStorage('menu_link_content') ->loadMultiple(); foreach ($entities as $entity) { if ($entity->get('bundle')->value !== 'menu_link_content') { $entity->set('bundle', 'menu_link_content'); $entity->save(); } } }
- ๐บ๐ฆUkraine lobodacyril
It happened because the menu name was previously used to get to the menu to which the link belonged. Later, the bundle field was defined for this purpose, and the menu name field is a rudiment field now. We didn't notice it in time, so you have the bundle field empty for menu items that were created by this module or by other modules. So if you have several menus, for example, header, and footer, then all menu items for the header will have bundle and menu name field as "header" and "footer" for footer.
For me, the menu_link_content bundle is incorrect since it doesn't belong to any menu. I'm curious how you created translation for menus that don't have a bundle since you can't create a translation configuration for that.
For me the same error. After Taxonomy menu UI module update i can not update existing node translations with menu link. When i try to modify the menu item from the menu configuration i get error:
Drupal\Component\Plugin\Exception\PluginNotFoundException: The "entity:menu_link_content:main" plugin does not exist. Valid plugin IDs for Drupal\Core\TypedData\TypedDataManager are: ... entity_revision:menu_link_content, entity_revision:menu_link_content:menu_link_content, ... entity:menu_link_content, entity:menu_link_content:menu_link_content, ... in Drupal\Core\Plugin\DefaultPluginManager->doGetDefinition() (line 53 of /core/lib/Drupal/Component/Plugin/Discovery/DiscoveryTrait.php).
- ๐บ๐ฆUkraine lobodacyril
It seems that the menu module sometimes uses the menu name for bundle and sometimes the menu_link_content value. I'm not sure what's going on there, but it looks like a major issue for now. I can't reproduce it on my side since all my websites that use this module had a smooth transition to the new version.
It'd be good if someone gave me the configuration files and composer.json that you use.
- ๐จ๐ฟCzech Republic jaroslav ฤervenรฝ
I tested the hook update and it helped.
- ๐ง๐พBelarus dewalt
I have the same issue with error on menu item edit:
Drupal\Component\Plugin\Exception\PluginNotFoundException: The "entity:menu_link_content:main" plugin does not exist.
Drupal\Component\Plugin\Exception\PluginNotFoundException: The "entity:menu_link_content:footer" plugin does not exist.
Thanks Jaroslav, the patch is working for existing menu items. I've extended it to avoid the issue with new created ones. Bundle isn't needed to be specified due https://www.drupal.org/project/drupal/issues/2350915 โ .
Kyrylo, I see you've tried to add translations support here - https://git.drupalcode.org/project/taxonomy_menu_ui/-/commit/ae60c128775.... I have no idea how setting the bundle field should help, please look "_menu_ui_node_save" for example. The main idea is:
- If link exist and it is a translation of existing link - create it with "$entity->addTranslation($term->language()->getId(), $data)";
- If link is new, please ensure that the link langcode matches with term langcode: "$entity->set('langcode', $term->language()->getId());" - First commit to issue fork.
- Merge request !6Changing menu bundle to current menu name is breaking menu structure. โ (Merged) created by shivam_tiwari
- ๐ฎ๐ณIndia shivam_tiwari
I faced same issue after updating taxonomy_menu_ui module to the latest version. I checked patches added here. #8 patch fixed issue for me. I created MR so we can run test and merge this update to the latest versions.
Thanks - ๐บ๐ธUnited States banoodle San Francisco, CA
Confirming the mr fixes the problem introduced by update 9001.
The site I experienced this problem on uses translation and we didn't have any blank bundles in the menu_link_content_data table and everything was working fine until we attempted to upgrade from 3.0.3 to 3.0.5 of this module.
Update 9001 made the translation settings and a custom field we added on menu links vanish from the UI and front-end.
- ๐บ๐ฆUkraine lobodacyril
Merge request #6 is completely wrong even though it solves your problem. The bundle field should contain the same as menu_name because if you enable translations for the menu, you will not be able to translate menu items. Translation settings correspond to the bundle name and if they do not fit, then by default the translation is disabled. Let's say you have a menu "Header", then you want to translate it. You go to settings and enable translation for them. But if you try to translate its menu items, their bundle will be menu_link_content not header and Drupal will not allow you to translate them. Read comment #4.
I couldn't reproduce this when Drupal creates a menu item with the menu_link_content bundle. It may happen in the previous versions of Drupal when it added the bundle field but the current structure requires to have bundle the same as menu_name. The menu_item field still exists and as I understand it's a rudiment and will be deleted in the future.
If you can reproduce the menu_link_content bundle from a fresh install, then tell me how to do it.