diff --git a/core/modules/link/src/LinkItemInterface.php b/core/modules/link/src/LinkItemInterface.php index f6a48f0..81df7a0 100644 --- a/core/modules/link/src/LinkItemInterface.php +++ b/core/modules/link/src/LinkItemInterface.php @@ -19,7 +19,7 @@ */ const LINK_INTERNAL = 0x01; - /** + /**My test link label * Specifies whether the field supports only external URLs. */ const LINK_EXTERNAL = 0x10; diff --git a/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php b/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php index 7ed62ba..7c48c13 100644 --- a/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php +++ b/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php @@ -170,9 +170,17 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen /** @var \Drupal\link\LinkItemInterface $item */ $item = $items[$delta]; + // We will customize the form depending on if the title form element is to + // be shown, and what the cardinality is. + $title_is_enabled = $this->getFieldSetting('title') != DRUPAL_DISABLED; + $cardinality_is_one = $this->fieldDefinition->getFieldStorageDefinition()->getCardinality() == 1; + $element['uri'] = array( '#type' => 'url', - '#title' => $this->t('URL'), + // When the title is not enabled, we will not use a fieldset and will + // lose the field label. So, use the field label as the uri form element + // label in that case. + '#title' => ($title_is_enabled || !$cardinality_is_one) ? $this->t('URL') : $this->fieldDefinition->getLabel() . ' (' . $this->t('URL') . ')', '#placeholder' => $this->getSetting('placeholder_url'), // The current field value could have been entered by a different user. // However, if it is inaccessible to the current user, do not display it @@ -183,6 +191,13 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen '#required' => $element['#required'], ); + // We will be taking off the fieldset since the title is not enabled. Which + // will mean the description from the field will not show when there is + // more than one link. Add the description from the field so it shows. + if ($cardinality_is_one && !$title_is_enabled) { + $element['uri']['#description'] = $this->fieldDefinition->getDescription(); + } + // If the field is configured to support internal links, it cannot use the // 'url' form element and we have to do the validation ourselves. if ($this->supportsInternalLinks()) { @@ -203,15 +218,30 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen if (!$this->supportsExternalLinks()) { $element['uri']['#field_prefix'] = rtrim(\Drupal::url('', array(), array('absolute' => TRUE)), '/'); } - // If the field is configured to allow both internal and external links, - // show a useful description. - elseif ($this->supportsExternalLinks() && $this->supportsInternalLinks()) { - $element['uri']['#description'] = $this->t('Start typing the title of a piece of content to select it. You can also enter an internal path such as %add-node or an external URL such as %url. Enter %front to link to the front page.', array('%front' => '', '%add-node' => '/node/add', '%url' => 'http://example.com')); - } - // If the field is configured to allow only external links, show a useful - // description. - elseif ($this->supportsExternalLinks() && !$this->supportsInternalLinks()) { - $element['uri']['#description'] = $this->t('This must be an external URL such as %url.', array('%url' => 'http://example.com')); + // Internal-only does not need a description, since the field prefix + // accomplishes what help text would. When external is allowed, show a + // useful description. + else { + // If description is not already initialized from the field, initialize + // it. If using the description from the field, add a space before + // appending the description from the uri form element. + if (!isset($element['uri']['#description'])) { + $element['uri']['#description'] = ''; + } + else { + $element['uri']['#description'] .= ' '; + } + + // If the field is configured to allow both internal and external links, + // show a useful description. + if ($this->supportsExternalLinks() && $this->supportsInternalLinks()) { + $element['uri']['#description'] .= $this->t('Start typing the title of a piece of content to select it. You can also enter an internal path such as %add-node or an external URL such as %url. Enter %front to link to the front page.', array('%front' => '', '%add-node' => '/node/add', '%url' => 'http://example.com')); + } + // If the field is configured to allow only external links, show a useful + // description. + elseif ($this->supportsExternalLinks() && !$this->supportsInternalLinks()) { + $element['uri']['#description'] .= $this->t('This must be an external URL such as %url.', array('%url' => 'http://example.com')); + } } $element['title'] = array( @@ -220,7 +250,7 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen '#placeholder' => $this->getSetting('placeholder_title'), '#default_value' => isset($items[$delta]->title) ? $items[$delta]->title : NULL, '#maxlength' => 255, - '#access' => $this->getFieldSetting('title') != DRUPAL_DISABLED, + '#access' => $title_is_enabled, ); // Post-process the title field to make it conditionally required if URL is // non-empty. Omit the validation on the field edit form, since the field @@ -238,8 +268,15 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen '#attributes' => array('class' => array('link-field-widget-attributes')), ); - // If cardinality is 1, ensure a proper label is output for the field. - if ($this->fieldDefinition->getFieldStorageDefinition()->getCardinality() == 1) { + // If cardinality is 1, a title and URI form elements will mix with other + // form elements and not appear related. Ensure a label is output for the + // link field and the title and URI form elements are grouped by making it + // a fieldset. When the cardinality is greater than one, each set of title + // and URI form elements are already grouped visually, because of the UI + // that allows reordering them. Also, if the title form element is not shown + // we do not need the grouping. So, only make it a fieldset when title is + // enabled. + if ($cardinality_is_one && $title_is_enabled) { // If the link title is disabled, use the field definition label as the // title of the 'uri' element. if ($this->getFieldSetting('title') == DRUPAL_DISABLED) { diff --git a/core/modules/link/src/Tests/LinkFieldUITest.php b/core/modules/link/src/Tests/LinkFieldUITest.php index 97fd9c8..a1d28b8 100644 --- a/core/modules/link/src/Tests/LinkFieldUITest.php +++ b/core/modules/link/src/Tests/LinkFieldUITest.php @@ -50,6 +50,8 @@ protected function setUp() { * Tests the link field UI. */ function testFieldUI() { + /* + // Add a content type. $type = $this->drupalCreateContentType(); $type_path = 'admin/structure/types/manage/' . $type->id(); @@ -92,6 +94,35 @@ function testFieldUI() { $this->drupalLogin($this->drupalCreateUser(['create ' . $type->id() . ' content'])); $this->drupalGet($add_path); $this->assertRaw('This must be an external URL such as http://example.com.'); + + */ + + // Log in an admin to set up the next content type. + $this->drupalLogin($this->adminUser); + + // Add a different content type. + $type = $this->drupalCreateContentType(); + $type_path = 'admin/structure/types/manage/' . $type->id(); + $add_path = 'node/add/' . $type->id(); + + // Add a link field to the newly-created type. Specify it must allow + // internal only links. Default is cardinality 1. Specify it must a + // description for the field. And, make the link text disabled. + $label = $this->randomMachineName(); + $description = $this->randomMachineName(); + $field_name = Unicode::strtolower($label); + $field_edit = [ + 'field[settings][link_type]' => LinkItemInterface::LINK_INTERNAL, + // 'field[settings][description]' => $description, + 'field[settings][title]' => 0, + ]; + $this->fieldUIAddNewField($type_path, $field_name, $label, 'link', array(), $field_edit); + + // There is no help text for internal only links, an input field prefix is + // used instead. Test for the prefix. + $this->drupalLogin($this->drupalCreateUser(['create ' . $type->id() . ' content'])); + $this->drupalGet($add_path); + $this->assertRaw($description); } } diff --git a/core/modules/menu_link_content/src/Tests/MenuLinkContentFormTest.php b/core/modules/menu_link_content/src/Tests/MenuLinkContentFormTest.php index 7129d38..d60cca7 100644 --- a/core/modules/menu_link_content/src/Tests/MenuLinkContentFormTest.php +++ b/core/modules/menu_link_content/src/Tests/MenuLinkContentFormTest.php @@ -42,6 +42,8 @@ public function testMenuLinkContentForm() { $element = $this->xpath('//select[@id = :id]/option[@selected]', array(':id' => 'edit-menu-parent')); $this->assertTrue($element, 'A default menu parent was found.'); $this->assertEqual('admin:', $element[0]['value'], ' menu is the parent.'); + // Test the field description is present. + $this->assertRaw('The location this menu link points to.'); $this->drupalPostForm( NULL, diff --git a/core/modules/shortcut/src/Tests/ShortcutLinksTest.php b/core/modules/shortcut/src/Tests/ShortcutLinksTest.php index bf98504..0d51c54 100644 --- a/core/modules/shortcut/src/Tests/ShortcutLinksTest.php +++ b/core/modules/shortcut/src/Tests/ShortcutLinksTest.php @@ -55,6 +55,11 @@ public function testShortcutLinkAdd() { '/admin/config/system/site-information', ]; + // Test the add shortcut form UI. Test that the base field description is + // there. + $this->drupalGet('admin/config/user-interface/shortcut/manage/' . $set->id() . '/add-link'); + $this->assertRaw('The location this shortcut points to.'); + // Check that each new shortcut links where it should. foreach ($test_cases as $test_path) { $title = $this->randomMachineName();