Problem/Motivation

When using route:<nolink> the LinkGenerator class creates a <span> tag instead of an anchor tag which makes sense for certain scenarios, but it is not accessible if the non-link will have interactivity added to it via JavaScript. It would be beneficial to have the option to use the semantically-correct <button> HTML tag here for such cases.

Proposed resolution

Since the only way to modify the HTML tag is through a special route (demonstrated by route:<nolink>), it would appear a new special route is required for this use case: route:<button>

Remaining tasks

User interface changes

API changes

None: If someone defined a <button> route it would break, but that is unlikely. Also, when route:<nolink> was added there was not a corresponding change record.

Data model changes

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Daniel Korte created an issue. See original summary.

Daniel Korte’s picture

Assigned: Daniel Korte » Unassigned
Status: Active » Needs review
FileSize
3.17 KB
Daniel Korte’s picture

Issue summary: View changes
Daniel Korte’s picture

Added type="button" since the default for a button is type="submit" which causes unexpected behavior when editing a menu.

Daniel Korte’s picture

Issue summary: View changes
Issue tags: +Accessibility, +Usability, +D8UX usability

The last submitted patch, 4: allow-button-tag-in-linkgenerator-2999549-4.patch, failed testing. View results

Daniel Korte’s picture

mtift’s picture

We need this functionality, too. Rerolling...

Status: Needs review » Needs work

The last submitted patch, 8: allow-button-tag-in-linkgenerator-2999549-8.patch, failed testing. View results

mtift’s picture

Status: Needs work » Needs review
FileSize
3.23 KB
1.61 KB

I didn't resolve that conflict properly. Trying again.

Status: Needs review » Needs work

The last submitted patch, 10: allow-button-tag-in-linkgenerator-2999549-9.patch, failed testing. View results

mtift’s picture

Fixing a typo

mherchel’s picture

Verified that the latest patch in #12 works.

tim.plunkett’s picture

Issue tags: -accessibility (duplicate tag), -D8UX usability +Accessibility

Fixing tags

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

andrewmacpherson’s picture

+1 for this feature request. The motivation is well described in the issue summary. It's a widely applicable feature for mega-menus, tree-style sidebar menus, login forms presenting login forms on dialogs.

This would benefit from a change record. That should be drafted before RTBC.

The patch looks straightforward enough, but I haven't managed to test this yet. I'm relying on simplytest.me today, and got errors. I've queued another test for the patch in #12.

mherchel’s picture

Draft change record created at https://www.drupal.org/node/3053689

m4olivei’s picture

Status: Needs review » Reviewed & tested by the community

Code looks great.

Also tried it out on a stock Umami install by adding a menu link to the main menu. I set the link to route:<button> and it did indeed show up as a button with the markup:

<button class="menu-main__link" type="button">Empty Button</button>
andrewmacpherson’s picture

Queued tests against 8.8.x

mherchel’s picture

@andrewmacpherson are we supposed to see results posted in this issue? I'm not sure how this works.

andrewmacpherson’s picture

@mherchel - the test results are noted next to the patch itself. You can see the result in comment #12 - it passes against 8.8.x

alexpott’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs followup
  1. --- /dev/null
    +++ b/core/lib/Drupal/Core/GeneratedButton.php
    

    I'm not convinced we've using the correct namespace here - but it is the namespace we've used for \Drupal\Core\GeneratedLink and \Drupal\Core\GeneratedNoLink - I think we should consider moving these to either Drupal\Core\Routing, Drupal\Core\Menu, Drupal\Core\Utility (along side LinkGenerator) or somewhere new - let's open a follow-up for that.

  2. +++ b/core/lib/Drupal/Core/GeneratedButton.php
    @@ -0,0 +1,15 @@
    +/**
    + * This class holds a <button> generated from the <button> route.
    + */
    +class GeneratedButton extends GeneratedLink {
    

    One thing I was thinking about is how this relates to and more importantly does not relate to \Drupal\Core\Render\Element\Button and what confusion it could introduce. I think the description here might need to go into that. Or at least mention that this is not for generating buttons for forms but for putting a button in a list of links such as a multi-level menu.

mtift’s picture

Issue tags: -Needs followup

Item 1 (from #22) should be resolved with https://www.drupal.org/project/drupal/issues/3074978. Next I'll work on item 2.

mtift’s picture

Here's the updated patch that addresses item 2 from #22

mherchel’s picture

Status: Needs review » Reviewed & tested by the community

Issue and comment look good to me. Thanks @mtift!

catch’s picture

+++ b/core/lib/Drupal/Core/GeneratedButton.php
@@ -0,0 +1,19 @@
+/**
+ * This class holds a <button> generated from the <button> route.
+ *

<button> generated from the <button> route is very confusing to read. First I thought it was a mistake in the patch, but reading GeneratedNoLink it's correct, but still confusing. I tried to think of alternative wording but struggled a bit.

larowlan’s picture

Status: Reviewed & tested by the community » Needs review
+++ b/core/lib/Drupal/Core/Utility/LinkGenerator.php
@@ -170,6 +171,11 @@ public function generate($text, Url $url) {
+    elseif ($url->isRouted() && $url->getRouteName() === '<button>') {

this is getting unwieldy now, can we add a protected method the elements after this that are common and return early instead of stacking up the elseifs

e.g. lines 181-187 of HEAD

if (!($variables['text'] instanceof MarkupInterface)) {
      $variables['text'] = Html::escape($variables['text']);
    }
    $attributes = new Attribute($attributes);
    // This is safe because Attribute does escaping and $variables['text'] is
    // either rendered or escaped.
    return $generated_link->setGeneratedLink('<' . $generated_link::TAG . $attributes . '>' . $variables['text'] . '</' . $generated_link::TAG . '>');

Would become a new method, something like doGenerate

Then inside the first if we'd do


return $this->doGenerate($generated_link, $attributes);

Then the next two elseifs (with this patch) become just ifs that also return

and the final else is not needed, as by that stage the others have returned.

mtift’s picture

Status: Needs review » Needs work
mtift’s picture

Status: Needs work » Needs review
FileSize
5.12 KB
4.66 KB

Sounds good.

mtift’s picture

Status: Needs review » Needs work

That last patch doesn't work. Missing $variables and perhaps more.

mtift’s picture

mherchel’s picture

Status: Needs review » Reviewed & tested by the community

Verified #31 patch applies and is working correctly!

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

eeyorr’s picture

Any updates on when this will be committed?

eeyorr’s picture

Is this going to be committed???

mherchel’s picture

@eeyorr At the earliest this will go in Drupal 9.1 (probably early 2021).

Currently the core committers are trying to work out all of the deprecations in Drupal 9.0 to get that out of the door.

I'm planning on going to Drupal Dev Days in about a month. Assume there are some core committers there, I'm going to bug them :P

eeyorr’s picture

@mherchel, thanks for the update!

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

#26 hasn't been addressed but I can't think of a better wording either. @mherchel actually we can commit this to 8.9.x and 9.0.x now. Nothing is frozen - yes issues like this are not a priority but this is still a good thing to add to core that's very difficult for contrib to do.

Committed and pushed 8ed835c0bc to 9.0.x and 485db38e54 to 8.9.x. Thanks!

diff --git a/core/lib/Drupal/Core/Utility/LinkGenerator.php b/core/lib/Drupal/Core/Utility/LinkGenerator.php
index d5be974951..665e1d3192 100644
--- a/core/lib/Drupal/Core/Utility/LinkGenerator.php
+++ b/core/lib/Drupal/Core/Utility/LinkGenerator.php
@@ -197,7 +197,7 @@ public function generate($text, Url $url) {
    * @param array $variables
    *   The link text, url, and other options.
    *
-   * @return Drupal\Core\GeneratedLink $generated_link
+   * @return Drupal\Core\GeneratedLink
    *   The generated link, along with its associated cacheability metadata.
    */
   protected function doGenerate($generated_link, $attributes, $variables) {

Fixed coding standards on commit.

  • alexpott committed 8ed835c on 9.0.x
    Issue #2999549 by mtift, Daniel Korte, mherchel, alexpott, larowlan:...

  • alexpott committed 485db38 on 8.9.x
    Issue #2999549 by mtift, Daniel Korte, mherchel, alexpott, larowlan:...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

andrewmacpherson’s picture

The change record for this issue is still at draft status. Should it be published?