diff --git a/core/modules/menu_link/config/schema/menu_link.schema.yml b/core/modules/menu_link/config/schema/menu_link.schema.yml index 2fddb84..10c6e5d 100644 --- a/core/modules/menu_link/config/schema/menu_link.schema.yml +++ b/core/modules/menu_link/config/schema/menu_link.schema.yml @@ -23,4 +23,4 @@ field.value.menu_link: label: 'Text format' weight: type: integer - label: 'Weight' \ No newline at end of file + label: 'Weight' diff --git a/core/modules/menu_ui/menu_ui.js b/core/modules/menu_link/js/menu_link.js similarity index 91% rename from core/modules/menu_ui/menu_ui.js rename to core/modules/menu_link/js/menu_link.js index 36fb1d6..3087b4a 100644 --- a/core/modules/menu_ui/menu_ui.js +++ b/core/modules/menu_link/js/menu_link.js @@ -2,7 +2,7 @@ "use strict"; - Drupal.behaviors.menuUiDetailsSummaries = { + Drupal.behaviors.menuLinkDetailsSummaries = { attach: function (context) { $(context).find('.menu-link-form').drupalSetSummary(function (context) { var $context = $(context); @@ -19,15 +19,15 @@ /** * Automatically fill in a menu link title, if possible. */ - Drupal.behaviors.menuUiLinkAutomaticTitle = { + Drupal.behaviors.menuLinkFormAutomaticTitle = { attach: function (context) { var $context = $(context); $context.find('.menu-link-form').each(function () { var $this = $(this); // Try to find menu settings widget elements as well as a 'title' field in // the form, but play nicely with user permissions and form alterations. - var $checkbox = $this.find('.form-item-menu-enabled input'); - var $link_title = $context.find('.form-item-menu-title input'); + var $checkbox = $this.find('input.menu-link-enabled', $this); + var $link_title = $context.find('input.menu-link-title', $this); var $title = $this.closest('form').find('.form-item-title-0-value input'); // Bail out if we do not have all required fields. if (!($checkbox.length && $link_title.length && $title.length)) { diff --git a/core/modules/menu_link/menu_link.libraries.yml b/core/modules/menu_link/menu_link.libraries.yml new file mode 100644 index 0000000..6610a24 --- /dev/null +++ b/core/modules/menu_link/menu_link.libraries.yml @@ -0,0 +1,8 @@ +menu_link.form: + version: VERSION + js: + js/menu_link.js: {} + dependencies: + - core/jquery + - core/drupal + - core/drupal.form diff --git a/core/modules/menu_link/src/Plugin/Field/FieldType/MenuLinkItem.php b/core/modules/menu_link/src/Plugin/Field/FieldType/MenuLinkItem.php index 70ef782..06e8367 100644 --- a/core/modules/menu_link/src/Plugin/Field/FieldType/MenuLinkItem.php +++ b/core/modules/menu_link/src/Plugin/Field/FieldType/MenuLinkItem.php @@ -182,11 +182,16 @@ protected function doSave() { // When the entity is saved via a plugin instance, we should not call // the menu tree manager to update the definition a second time. - if (!$this->menuPluginManager->hasDefinition($plugin_id)) { - $this->menuPluginManager->addDefinition($plugin_id, $this->getMenuPluginDefinition()); + if ($menu_plugin_definition = $this->getMenuPluginDefinition()) { + if (!$this->menuPluginManager->hasDefinition($plugin_id)) { + $this->menuPluginManager->addDefinition($plugin_id, $this->getMenuPluginDefinition()); + } + else { + $this->menuPluginManager->updateDefinition($plugin_id, $this->getMenuPluginDefinition(), FALSE); + } } else { - $this->menuPluginManager->updateDefinition($plugin_id, $this->getMenuPluginDefinition(), FALSE); + $this->menuPluginManager->removeDefinition($plugin_id); } } @@ -204,10 +209,17 @@ public function getMenuPluginId() { /** * Generates the plugin definition of the associated menu link. * - * @return array + * @return array|FALSE + * The menu plugin definition, otherwise FALSE. */ protected function getMenuPluginDefinition() { $menu_definition = []; + + // If there is no menu name selected, you don't have a valid menu plugin. + if (!$this->values['menu_name']) { + return FALSE; + } + $entity = $this->getEntity(); $menu_definition['id'] = $this->getPluginId(); $menu_definition['title'] = $this->values['title'] ?: $entity->label(); @@ -220,7 +232,7 @@ protected function getMenuPluginDefinition() { $menu_definition['metadata']['entity_id'] = $entity->id(); $menu_definition['metadata']['entity_type_id'] = $entity->getEntityTypeId(); $menu_definition['metadata']['field_name'] = $this->definition->getFieldDefinition()->getName(); - $menu_definition['metadata']['translateable'] = is_subclass_of($entity, '\Drupal\Core\TypedData\TranslatableInterface'); + $menu_definition['metadata']['translatable'] = is_subclass_of($entity, '\Drupal\Core\TypedData\TranslatableInterface'); $url = $entity->urlInfo(); $menu_definition['route_name'] = $url->getRouteName(); diff --git a/core/modules/menu_link/src/Plugin/Field/FieldWidget/MenuLinkWidget.php b/core/modules/menu_link/src/Plugin/Field/FieldWidget/MenuLinkWidget.php index 1bff7f1..b0c82d7 100644 --- a/core/modules/menu_link/src/Plugin/Field/FieldWidget/MenuLinkWidget.php +++ b/core/modules/menu_link/src/Plugin/Field/FieldWidget/MenuLinkWidget.php @@ -117,26 +117,30 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen $entity = $items->getParent()->getValue(); $element['#pre_render'][] = [$this, 'preRenderMenuDetails']; + $element['#attached']['library'][] = 'menu_link/menu_link.form'; + $element['title'] = [ '#type' => 'textfield', - '#title' => $this > t('Menu link title'), + '#title' => $this->t('Menu link title'), '#default_value' => $default_title, + '#attributes' => ['class' => ['menu-link-title']], ]; $element['description'] = [ '#type' => 'textarea', - '#title' => $this > t('Description'), + '#title' => $this->t('Description'), '#default_value' => $default_description, '#rows' => 1, - '#description' => $this > t('Shown when hovering over the menu link.'), + '#description' => $this->t('Shown when hovering over the menu link.'), ]; - $plugin_id = $items[$delta]->getPluginId(); + $plugin_id = $items[$delta]->getMenuPluginId(); $has_plugin = $plugin_id && $this->menuLinkManager->hasDefinition($plugin_id); $element['enabled'] = [ '#type' => 'checkbox', '#title' => $this->t('Provide a menu link'), '#default_value' => (int) (bool) $has_plugin, + '#attributes' => ['class' => ['menu-link-enabled']], ]; $element['menu'] = [ '#type' => 'details', @@ -186,7 +190,7 @@ public function preRenderMenuDetails($element) { $element['menu']['weight'] = $element['weight']; // Hide the elements when enabled is disabled. - foreach (['menu_parent', 'weight'] as $form_element) { + foreach (['title', 'description', 'menu_parent', 'weight'] as $form_element) { $element['menu'][$form_element]['#states'] = [ 'invisible' => [ 'input[name="' . $element['menu']['enabled']['#name'] . '"' => ['checked' => FALSE], @@ -211,6 +215,8 @@ public function extractFormValues(FieldItemListInterface $items, array $form, Fo list($item->menu_name, $item->parent) = explode(':', $item->menu_parent, 2); } else { + $item->title = ''; + $item->description = ''; $item->menu_name = ''; $item->parent = ''; } diff --git a/core/modules/menu_link/src/Plugin/Menu/MenuLinkField.php b/core/modules/menu_link/src/Plugin/Menu/MenuLinkField.php index f90ebc5..e39e1f9 100644 --- a/core/modules/menu_link/src/Plugin/Menu/MenuLinkField.php +++ b/core/modules/menu_link/src/Plugin/Menu/MenuLinkField.php @@ -132,4 +132,25 @@ public function getEntity() { return $this->entity; } + /** + * {@inheritdoc} + */ + public function isDeletable() { + return TRUE; + } + + /** + * {@inheritdoc} + */ + public function deleteLink() { + $entity = $this->getEntity(); + $field_name = $this->getMetaData()['field_name']; + + $entity->$field_name->title = ''; + $entity->$field_name->description = ''; + $entity->$field_name->menu_name = ''; + $entity->$field_name->parent = ''; + } + + } diff --git a/core/modules/menu_ui/menu_ui.libraries.yml b/core/modules/menu_ui/menu_ui.libraries.yml index c5f9594..31f34d2 100644 --- a/core/modules/menu_ui/menu_ui.libraries.yml +++ b/core/modules/menu_ui/menu_ui.libraries.yml @@ -1,12 +1,3 @@ -drupal.menu_ui: - version: VERSION - js: - menu_ui.js: {} - dependencies: - - core/jquery - - core/drupal - - core/drupal.form - drupal.menu_ui.admin: version: VERSION js: diff --git a/core/modules/menu_ui/src/Tests/MenuNodeTest.php b/core/modules/menu_ui/src/Tests/MenuNodeTest.php index 58c3ad9..725ad0a 100644 --- a/core/modules/menu_ui/src/Tests/MenuNodeTest.php +++ b/core/modules/menu_ui/src/Tests/MenuNodeTest.php @@ -127,7 +127,7 @@ function testMenuNodeFormWidget() { 'menu[0][enabled]' => 1, ); $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save')); - // Assert that there is no link for the node. + // Assert that there is a link for the node. $this->drupalGet('test-page'); $this->assertLink($node->label()); @@ -144,6 +144,10 @@ function testMenuNodeFormWidget() { $this->drupalGet('node/' . $node->id() . '/edit'); $this->assertFieldById('edit-menu-0-weight', 17, 'Menu weight correct in edit form'); + // Ensure that the menu link field is opened up by default. + $this->assertFieldById('edit-menu-0-enabled', 1, 'Provide a menu link checkbox is checked.'); + + // Edit the node and remove the menu link. $edit = array( 'menu[0][enabled]' => FALSE, @@ -153,6 +157,10 @@ function testMenuNodeFormWidget() { $this->drupalGet('test-page'); $this->assertNoLink($node_title); + // Ensure that the menu link is also no longer stored. + $plugin_id = $node->menu->first()->getMenuPluginId(); + $this->assertFalse(\Drupal::service('plugin.manager.menu.link')->hasDefinition($plugin_id)); + // Add a menu link to the Administration menu. $node->menu->menu_name = 'admin'; $node->menu->title = $this->randomMachineName(16);