Problem/Motivation

If you are attaching some option attributes to a link field (using a custom module for example), those attributes are removed on node save.
One solution is to use link_attributes, but you might not want to allow users to edit those attributes from node edit.

LinkWidget::formElement() puts the options attributes into $element['attributes'], which is a value type element. Upon submitting, LinkWidget::massageFormValues() does not use this value. It is effectively discarded.

Steps to reproduce

Since there's no form element for the attributes in the LinkWidget the easiest way to reproduce the issue is by using Drush.

  1. Add a Link field to any node type.
  2. Create a new instance of that node type. Fill out the link field with any valid input.
  3. Use the following command to set the attributes, replacing "FIELD_MACHINE_NAME" with the machine name of the field you created and "NID" with the node ID of the one you created in the previous step: drush eval '$node = \Drupal\node\Entity\Node::load(NID);$node->FIELD_MACHINE_NAME->options = ["attributes" => ["class" => "test-class"]];$node->save();'
  4. Verify the options you just created with the command drush eval '$node = \Drupal\node\Entity\Node::load(NID);var_dump($node->FIELD_MACHINE_NAME->options);'
  5. Visit the edit form for the node you created. Re-save it.
  6. Verify the options with the same Drush command.

Expected result:
The options should be the same as when you loaded them in step 4, which should look like this:

array(1) {
  ["attributes"]=>
  array(2) {
    ["class"]=>
    string(17) "test-class-edited"
  }
}

Actual result:
The options array is empty:

array(0) {
}

Proposed resolution

Update LinkWidget::massageFormValues() to merge in the submitted attributes. This is tricky to do in a backward-compatible way, maybe impossible. A previous attempt to solve the issue by changing the element structure in the form broke a few modules that deal with link attributes. It may be impossible to fix this issue in a way that is backward compatible for all contrib modules.

Remaining tasks

User interface changes

Introduced terminology

API changes

Data model changes

Release notes snippet

A bug that prevented link attributes from being saved by the link_default widget has been fixed. This change may prevent extending widget classes from working correctly. If you maintain an extending widget that works with link attributes, then you should test that widget to ensure that this change does not disrupt that functionality. Site builders who use attribute-setting modules should test their content to ensure that those attributes continue to work as expected.

Issue fork drupal-3056652

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

aalin created an issue. See original summary.

aalin’s picture

Version: 8.7.x-dev » 8.8.x-dev
StatusFileSize
new766 bytes

changing $element['attributes'] = .. to $element['options']['attributes'] is fixing this

aalin’s picture

Status: Active » Needs review
idebr’s picture

Issue tags: +Needs tests

@aalin Can you add a test case showcasing the current failing behavior?

aalin’s picture

1. Set some custom option attributes to a field (consider that the field is not empty):

  $node = Node::load(1); // an existing node
  $field = $node->get('field_link')->first();
  // Set options attributes
  $fieldOptions = $field->get('options')->toArray();
  if (!isset($fieldOptions['attributes'])) {
    $fieldOptions = ['attributes' => []];
  }
  $fieldOptions['attributes'] += ['data-ga-event'=>'my-event'];
  $field->set('options', $fieldOptions);
  $node->save(); // save the node, that will update the link field

2. check that the custom options exists:

 $node = Node::load(1);
  kint( $node->get('field_link')->first()->getUrl()->getOption('attributes') );

this will output: [data-ga-event] => my-event

3. go to: /node/1/edit and save

4. check again custom options on field_link:

$node = Node::load(1);
  kint( $node->get('field_link')->first()->getUrl()->getOption('attributes') );

this will output NULL

mashermike’s picture

Status: Needs review » Needs work

The last submitted patch, 6: link-option-attributes-3056652-tests-only.patch, failed testing. View results

mashermike’s picture

Status: Needs work » Needs review
StatusFileSize
new3.34 KB
mashermike’s picture

Issue tags: -Needs tests

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.

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

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

ranjith_kumar_k_u’s picture

StatusFileSize
new3.34 KB

Re-rolled #8 for 9.4.

Status: Needs review » Needs work

The last submitted patch, 15: 3056652-15.patch, failed testing. View results

yogeshmpawar’s picture

Status: Needs work » Needs review
StatusFileSize
new3.36 KB
new870 bytes

Hope updated patch will fix test failures.

Status: Needs review » Needs work

The last submitted patch, 17: 3056652-17.patch, failed testing. View results

yogeshmpawar’s picture

Status: Needs work » Needs review
StatusFileSize
new3.38 KB
new1.38 KB

Another try to fix test failures.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

smustgrave’s picture

Status: Needs review » Reviewed & tested by the community

This looks valid. and the test cases seem to pass.

smustgrave’s picture

Issue tags: +Bug Smash Initiative
catch’s picture

Version: 9.5.x-dev » 9.4.x-dev
Status: Reviewed & tested by the community » Fixed

Committed/pushed to 10.1.x, cherry-picked to 10.0.x, 9.5.x, 9.4.x, thanks!

  • catch committed 02cc55d on 10.0.x
    Issue #3056652 by yogeshmpawar, mashermike, aalin, ranjith_kumar_k_u:...
  • catch committed 8eea239 on 10.1.x
    Issue #3056652 by yogeshmpawar, mashermike, aalin, ranjith_kumar_k_u:...
  • catch committed b9942ab on 9.4.x
    Issue #3056652 by yogeshmpawar, mashermike, aalin, ranjith_kumar_k_u:...
  • catch committed 2d7b035 on 9.5.x
    Issue #3056652 by yogeshmpawar, mashermike, aalin, ranjith_kumar_k_u:...
maxstarkenburg’s picture

I'm finding that this change is breaking some link-related contrib. For example, link_class and link_target no longer allow edits to their respective attribute values once a field has been saved the first time (#3301937: Link classes can't be edited/updated after core 9.4.5 update and #3302123: Targets can't be updated after core 9.4.5 update (ok as of 9.4.6)), and menu_link_attributes has a more "additive" problem now, with replacement values just being concatenated onto the previous one (#3302105: As of core 9.4.5, can't remove link attribute values once applied). Haven't (yet) tested link_attributes and other modules I might not be aware of that might be affected.

I don't know if the onus is on core to make a further change for this issue to work better with these modules, or whether it's on contrib to "get with the [new] program", so to speak, but in any case, since I have some affected sites where I can't just remove these modules, and also because I'm not sure about those modules' maintenance statuses, I've made a patch for core that basically reverts the change made here, to use in the meanwhile.

maxstarkenburg’s picture

Also, please let me know if best practice in a case like (especially where the change was already released) is to file a new issue instead of tacking on comments to the originating one?

smustgrave’s picture

Think it's best to open a new issue referencing this one.

maxstarkenburg’s picture

Thanks @smustgrave, I've created #3302472: Multiple link-related contrib modules broken by #3056652 to address the breakage (should probably port the patch over there too, though am already using the above one on a few of my composer.json files, heh).

idebr’s picture

Status: Reviewed & tested by the community » Fixed

Restoring the issue status to 'Fixed' as a follow-up issue is available at #3302472: Multiple link-related contrib modules broken by #3056652

idebr’s picture

Version: 9.5.x-dev » 9.4.x-dev

  • catch committed a75c1ca on 9.4.x
    Revert "Issue #3056652 by yogeshmpawar, mashermike, aalin,...
catch’s picture

Version: 9.4.x-dev » 9.5.x-dev

I've just reverted this from the 9.4.x branch, so those modules will work again with no changes in the next patch release of 9.4.x. If the contrib modules need adapting to work with both versions of the form structure, then they should end up working with the (old) 9.4.x and (new) 9.5.x versions anyway.

catch’s picture

catch’s picture

Status: Fixed » Needs work
Issue tags: +Needs change record, +Needs release note

fwiw if an issue has very recently been committed and introduced an obvious regression, it's OK to re-open it for a revert. For every other case, it's better to open a follow-up.

I thought about this some more and went-ahead and reverted from all branches.

If the contrib module just need to adapt to the new form structure, we can possibly re-commit this to 10.1.x-9.5.x with a release note and change record.

If this was a form element I probably would have thought about this before commit, but I wouldn't have expected contrib modules to be relying on a #type => value that wasn't working in core, so it'd be good to understand why the contrib modules broke due to this.

  • catch committed 4be368f on 10.0.x
    Revert "Issue #3056652 by yogeshmpawar, mashermike, aalin,...
  • catch committed 4ab6486 on 10.1.x
    Revert "Issue #3056652 by yogeshmpawar, mashermike, aalin,...
  • catch committed 3ba7edd on 9.5.x
    Revert "Issue #3056652 by yogeshmpawar, mashermike, aalin,...
segx’s picture

Patch #25 seems to be implemented and the problem is fixed in the 9.4.6 update. Please verify ... thank you!

maxstarkenburg’s picture

@segx I did a quick test with menu_link_attributes on a site after updating to core 9.4.6 and can verify that the problem is now absent with regard to that module (I would assume the other modules affected are now fine again too). The original issue posted at top however is, I suppose, back to square one.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

dcam’s picture

Issue summary: View changes
Issue tags: -link, -attributes

Updated the IS.

dcam’s picture

Status: Needs work » Needs review

I've verified that MR 13299 is compatible with the link_class, link_target, and link_attributes modules. It is NOT compatible with menu_link_attributes.

...I wouldn't have expected contrib modules to be relying on a #type => value that wasn't working in core, so it'd be good to understand why the contrib modules broke due to this.

They aren't relying on the value. They are relying on the $element['options']['attributes'] render array keys. There's no problem while the Core widget sets $element['attributes']. Nothing else uses it. But the contrib modules' widgets all set up their render arrays to match the expected structure of a URL's options array. They make actual form elements at $element['options']['attributes']. When Core suddenly started doing it too everything broke, probably because Core set it as a value element. But then you had a module like link_attributes turning it into a details with child elements for the different attributes. It's a wonder that they weren't more broken than they were. That's why I decided to leave the Core widget's structure as it has been. Instead, I'm merging the attributes into the field value in massageFormValues().

menu_link_attributes is different because it merges its attribute values in at https://git.drupalcode.org/project/menu_link_attributes/-/blob/8.x-1.x/m.... So we end up with the same "additive" problem described in #25. I don't know if something can be done about this. I'm looking for other opinions, so I'm setting this to Needs Review.

I haven't written a change record pending a decision on a final approach to fix this.

dcam’s picture

Tagging for framework manager review due to the issue with contrib compatibility described in #42.

smustgrave’s picture

Question is there anything we can do to not break menu_link_attributes and still fix the bug? And deprecate the BC way to give that module time to update? Know we shouldn't let contrib dictate a core fix but that module does have 82K downloads.

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.

smustgrave’s picture

Status: Needs review » Needs work

This one appears to need a rebase. I was about to mark it RTBC just to get into the queue to get in front of a manager.

dcam’s picture

Issue summary: View changes
Status: Needs work » Needs review
Issue tags: -Needs change record, -Needs release note

Amazingly, the Update Fork button worked to rebase the MR, even though it was more than 1000 commits behind.

Question is there anything we can do to not break menu_link_attributes and still fix the bug?

I don't think so.

I went ahead and added the change record and release notes snippet. I didn't give before/after examples because any changes that need to be made by extending widgets or modules will be implementation-specific. There's no one single thing that anyone needs to do in order to update their code.

smustgrave’s picture

Status: Needs review » Reviewed & tested by the community

Probably still needs framework manager sign off but since it's been 6 months going to RTBC to hopefully get some attention.

catch’s picture

Status: Reviewed & tested by the community » Needs review

Can we open an issue again menu_link_attributes? Ideal thing would be if they can implement things so it will work for both before and after this commit in a new release.

smustgrave’s picture

Status: Needs review » Reviewed & tested by the community
quietone’s picture

Issue tags: +12.0.0 release notes

I updated the branch in the MR and reworked it so the change is the first item. I also make a heading for the action maintainers and site builders should take so it is easier to find. Therefore, the change record needs review.

Adding release note tag so we can inform maintainers/site builders.

catch’s picture

Status: Reviewed & tested by the community » Needs work

Couple of minor comments on the MR.

dcam’s picture

Status: Needs work » Needs review

Feedback was addressed.

mohit_aghera’s picture

Status: Needs review » Reviewed & tested by the community

All 3 feedback items are addressed.
Moving backed to RTBC.

larowlan’s picture

Status: Reviewed & tested by the community » Needs work

Left a comment on the MR regarding a bug this introduces.

We need to expand test coverage for that case as well.

The good news is I ran the link_attributes test suite against this branch and it passed.

link_attributes has a widget that extends this one AND adds support for attributes via a UI.

My gut feeling is to close won't fix this and ask people to use that module - that's what it's for!