Allow for menu items to added in the current language on a node add/edit page.
When editing/adding a translation of a node the menu item of the original node is still selected in the Menu settings. I should be able to create a new menu item for the current language. The parent selector should also be filtered to current content language or Undefined.
This can be resolved by adding language conditions to the queries.
Find the default values in the current language/und/zxx
function menu_ui_get_menu_link_defaults(NodeInterface $node) {
// Prepare the definition for the edit form.
/** @var \Drupal\node\NodeTypeInterface $node_type */
$node_type = $node->type->entity;
$langcode = $node->language()->getId();
$menu_name = strtok($node_type->getThirdPartySetting('menu_ui', 'parent', 'main:'), ':');
$defaults = FALSE;
if ($node->id()) {
$id = FALSE;
// Give priority to the default menu
$type_menus = $node_type->getThirdPartySetting('menu_ui', 'available_menus', array('main'));
if (in_array($menu_name, $type_menus)) {
$query = \Drupal::entityQuery('menu_link_content')
->condition('link.uri', 'node/' . $node->id())
->condition('menu_name', $menu_name)
->condition('langcode', array($langcode, LanguageInterface::LANGCODE_NOT_SPECIFIED, anguageInterface::LANGCODE_NOT_APPLICABLE), 'IN')
->sort('id', 'ASC')
->range(0, 1);
$result = $query->execute();
$id = (!empty($result)) ? reset($result) : FALSE;
}
// Check all allowed menus if a link does not exist in the default menu.
if (!$id && !empty($type_menus)) {
$query = \Drupal::entityQuery('menu_link_content')
->condition('link.uri', 'entity:node/' . $node->id())
->condition('menu_name', array_values($type_menus), 'IN')
->condition('langcode', array($langcode, LanguageInterface::LANGCODE_NOT_SPECIFIED, LanguageInterface::LANGCODE_NOT_APPLICABLE), 'IN')
->sort('id', 'ASC')
->range(0, 1);
$result = $query->execute();
$id = (!empty($result)) ? reset($result) : FALSE;
}
...
Select the parent items by language.
function menu_ui_form_node_form_alter(&$form, FormStateInterface $form_state) {
$menus = Menu::loadMultiple();
$type_menus = $node_type->getThirdPartySetting('menu_ui', 'available_menus', array('main'));
$available_menus = array();
foreach ($type_menus as $menu) {
if (isset($menus[$menu]) && in_array($menus[$menu]->language()->getId(), array($node->language()->getId(), LanguageInterface::LANGCODE_NOT_SPECIFIED, LanguageInterface::LANGCODE_NOT_APPLICABLE))) {
$available_menus[$menu] = $menus[$menu]->label();
}
}
...
}
Save the menu item with the langcode from the node.
function _menu_ui_node_save(NodeInterface $node, array $values) {
/** @var \Drupal\menu_link_content\MenuLinkContentInterface $entity */
if (!empty($values['entity_id'])) {
$entity = MenuLinkContent::load($values['entity_id']);
}
else {
// Create a new menu_link_content entity.
$entity = entity_create('menu_link_content', array(
'link' => ['uri' => 'entity:node/' . $node->id()],
'langcode' => $node->language()->getId(),
));
This will only work when we are not able to switch the language on a node. In the use case where the language is chosen from the node add/edit page, an ajax update will be needed for the parent menu items. I will try to work it out.