Problem/Motivation
If the Allow link text setting of a link field is changed from Optional/Required to Disabled after content has been saved, when the content is edited again the title won't be reset to NULL and the content will then display the old title value.
Steps to reproduce
- Add a field link to the content type article with the setting Required for Allow link text
- Create a content and put a URL/Title in this link e.g. : https://www.drupal.org/8 / About Drupal 8
- Save and view the content, you will see
<a href="https://www.drupal.org/8">About Drupal 8</a> - Change the configuration of the link field to set the title as Disabled
- Edit your content and replace the URL by https://www.drupal.org/about/9
- Save and view the content, you will see
<a href="https://www.drupal.org/about/9">About Drupal 8</a>(new URL with old title) instead of<a href="https://www.drupal.org/about/9">https://www.drupal.org/about/9</a>
So the old title is kept and isn't editable anymore by the end user unless the administrator changes back the link field settting.
Proposed resolution
Reset the link title value if the setting is Disabled
Remaining tasks
Manual testing
Review
Commit
User interface changes
Link title uses current correct value.
API changes
N/A
Data model changes
N/A
Release notes snippet
| Comment | File | Size | Author |
|---|
Issue fork drupal-3165999
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
Comment #2
tostinni commentedHere is a patch to reset the
#default_valueif the title setting is set to Disabled.I'm not sure the double
?test is very readable, should I create a$default_valuevariable and set it outside the element ?I imagine this would need some tests ?
Comment #3
anu.a_95 commentedApplied patch #2 successfully
Steps for reproducing the issue mentioned in the issue description is easy to follow.
Before patch

Even if we edit the URL, old link text with new url will be shown.
After patch
When the link text is disabled and a content with link text is edited, old link text won't be displayed and the updated url will be shown
Comment #4
anu.a_95 commentedComment #5
larowlanI don't think this is technically a bug, but I think we should still resolve it.
We need a test here demonstrating the issue and that it is fixed
Comment #6
tostinni commentedThanks for the review, here is the test that I added at the end of
testLinkTitle()so we can benefit from the initial setup of the field and then change the settings of the test field to demonstrate the bug is now fixed.Comment #7
quietone commentedLooks like a test has been added, removing tag
Comment #9
ranjith_kumar_k_u commentedI have applied the #6 patch on 9.2.x dev version and it works fine .
.RTBC
Before Patch
After Patch
Comment #10
ranjith_kumar_k_u commentedRe-rolled
Comment #12
quietone commented(isset($items[$delta]->title) ? $items[$delta]->title : NULL)
could use the null coalescing operator, ??.
This could be simpler.
Verify that if the title field is disabled the link is rendered using the URL as text.
drupalPostForm and assertText have been deprecated.
Comment #13
vakulrai commented@quietone , I have updated the patch as per the inputs given by you.
Please review.
Comment #14
quietone commented@vakulrai, thanks.
This time I applied that patch locally. And seeing it my editor I noticed more items.
I didn't notice this before but there are now 3 instances of $this->getFieldSetting('title'). I think it is now time to put that in a variable and then use the variable here, say,
$title = $this->getFieldSetting('title').One advantage is that it will reduce the length of the line being added which, at least for me, will make it easier to read.No need to do this here for the one line added many lines below in this test.
Wrapping is wrong here.
The field config has not changed so does not need to be loaded again.
Remove use of t(), it is only used in tests when specifically testing translations.
change to using $this->assertSession()
Comment #15
vakulrai commented@quietone , I have changed the patch as per #14, Please review.
Thanks
Comment #16
vakulrai commentedUploaded wrong interdiff in # 15, please consider this one.
Comment #17
vakulrai commentedComment #18
quietone commentedGetting there. :-)
Some out of scope changes have crept in.
Out of scope change.
The variable I suggested $title doesn't make much sense because this is a setting. The name should be descriptive, maybe $title_settings? Of course, you may think of something better.
Out of scope change.
Not wrapped correctly. More details about this standard is in the Drupal API documentation standards (general) sectiion.
As mentioned in #15.5 t() is not used in tests, unless specifically testing translations. This should be a string of the text expected. Refer to the other assertions in the test.
We also need a fail patch for this. Remember to upload that first then the success path.
Comment #19
neslee canil pinto@quietone updated as per #18, and i had a question regarding failing patch, where do we modify code for that case, under tests folders?
Comment #20
gauravvvv commentedAttached before and after patch screenshot for reference.
Patch #19 seems fine.
Comment #21
quietone commented@Neslee Canil Pinto, nice question. A fail patch is a patch that contains the test file(s) only. In this case, when the testbot runs the tests with a fail patch testLinkTitle will fail and that gives us evidence that the test is actually testing something we want to change. And then when the 'success' patch runs we have evidence that the fix does, in fact, fix the thing being tested. The fail patch is typically named 3165999-commentNumber-fail.patch. As an example, see https://www.drupal.org/project/drupal/issues/3109767#comment-14093095. It is important to upload the fail patch first and then the success patch. That way the testbot finishes with the success patch and updates the Status based on the success patch.
#18.4 needs to be fixed, the comment should be wrapped at 80 columns.
This time I manually tested the patch and can confirm it works. And I added the complete template to the IS and added remaining tasks.
Comment #22
vakulrai commented@quietone , I have followed the flow you have stated in #21, hence reuploading the patch with updated fix for #18.4 and fail patch followed by success patch .I have also made changes to the comment text, which follows 80 line syntax.
Please review.
Comment #24
quietone commented@vakulrai, thanks.
Everything in #18 and #21 have been addressed. I didn't find anything else that needs to be done when reading through the issue.
Comment #25
larowlan@Gauravmahlawat, I'm removing your issue-credit for attaching screenshots, as they'd already been added twice above.
Crediting @quietone for reviews that strongly shaped the final patch
Comment #26
larowlanLooks good, Needs Review for point 1 below - tl;dr I don't think we need to null coalesce $item[$delta]->title, I think TypedData API will have our back there
It would be good to add some additional brackets here for readability
e.g.
But now that I write that, I see we're null coalescing to ... null
Is there a scenario where $items[$delta]->title would raise an error? Given that is going through the Typed data API, I think that it would return NULL regardless and shouldn't raise and error.
reading this your first thought is wait, why cast the result of ->toString to a string, and then I realised that ->toString returns a GeneratedLink 🤦♂️ not the best naming
Comment #29
smustgrave commentedNeeds reroll and #26 needs to be addressed.
Comment #30
akashkumar07 commentedReroll added for patch #22.
Comment #31
smustgrave commentedYou rerolled the tests only patch..
And by skipping the actual patch didn't address #26 issues.
Please read the ticket and check the code before uploading a patch. Helps keep things clear. Would recommend reading up on some documentation on drupal.org tons of good stuff that really helped me!
Comment #32
akashkumar07 commentedHi @smustgrave,
The file
already has #22 patch changes for 9.5.x-dev. So I skipped it and #26 suggestion was not address.
Thanks
Comment #33
smustgrave commentedCan you double check that? I'm not seeing it. And if it were already addressed then this ticket is a duplicate
Comment #34
smustgrave commentedSkipping #30 because it just rerolled the tests only patch from #22.
I confirmed the full changes in #22 were not included as mentioned in #32 so no worries.
Tried addressing #26 comments
26.1 = Added the brackets but seems more like a comment and discussion
26.2 = Also seems like a comment more than a requested change.
Comment #35
sonam.chaturvedi commentedVerified the patch and tested on 9.5.x-dev. Patch applied successfully.
Test Steps:
1. Add a field link to the content type article with the setting Required for Allow link text
2. Create a content and put a URL/Title in this link e.g. : https://www.example.com / Example Domain
3. Save and view the content, you will see Example Domain
4. Change the configuration of the link field to set the title as Disabled
5. Edit your content and replace the URL by https://www.google.com
6. Save and view the content, you will see https://www.google.com
Test Result:
When the Allow link text setting of a link field is changed from Optional/Required to Disabled after content has been saved and the content is edited again > Then the content displays the new title value
Before Patch:

After Patch:

RTBC +1
Comment #36
smustgrave commentedThank you for reviewing @sonam.chaturvedi if you feel this good can you move to RTBC please.
Comment #37
abhijith s commentedApplied patch #34 on 9.5.x and it fixes the issue.
Before patch:

After patch:

Comment #38
smustgrave commentedThank you for testing if you think the issue is fixed please mark it as such
Comment #39
Manibharathi E R commentedPatch #34 Applied successfully on Drupal 9.4.x and Drupal 9.5.x.
Comment #40
Munavijayalakshmi commentedPatch #34 is working fine.
see in #35, #37 and #39 comments.
problem solved after applying the #34 patch.
changed to RTBC.
Comment #41
Munavijayalakshmi commentedComment #42
kristen pol@smustgrave Regarding #36 and #38, manual testing is only one step before RTBC.
From what I can tell no code review or other core gate checks have happened since #34.
I'm moving this back to needs review for this reason.
THIS ISSUE DOES NOT NEED MORE MANUAL TESTING. (It needs code review and core gate checks. Thanks.)
Comment #44
catchNot sure about the nested ternary, but that's just a preference and in this case moving it out of the array doesn't necessarily help. Otherwise looks good.
Comment #45
larowlana nitpick so small you need an electron microscope to see it, but I think this should be $title_setting, not $title_settings
#26.1 still hasn't been addressed here, and was also flagged by @catch as iffy
Comment #46
rishabh vishwakarma commentedAddressed #45.1
Comment #47
rinku jacob 13 commentedTested and verified the last patch #46. It was successfully applied on drupal 9.5.x. The above patch changed as per commented on #45. The above patch is not applicable for drupal version 10.1.x.
Comment #48
quietone commentedNeeds work for #45.2
@Rinku Jacob 13, Before testing an issue it is good practice to read the comments. The work requested in #45 is not complete which means this patch is not ready for testing.
Comment #49
rinku jacob 13 commentedHi @quietone , sorry for the mistake i have done. I didn't noticed comment on 45.2. According to comment on 26.1 we can change
'#default_value' => $title_setting === DRUPAL_DISABLED ? NULL : ($items[$delta]->title ?? NULL),to
'#default_value' => $title_setting === DRUPAL_DISABLED ? NULL : ($items[$delta]->title),because it shouldn't raise an error. I think this changes we need to do here. If it's wrong please excuse me. If it is correct i will create a patch based on that.
Comment #50
smustgrave commented#46 seemed to be making additional changes then 45.1
Addressed both points. Just moved the ternary check above to make it easier to read.
Comment #51
asha nair commentedApplied patch #50 successfully and it fixed the issue. Also addressed both points mentioned in #45.
Comment #52
asha nair commentedComment #53
feyp commentedThis issue is being reviewed by the kind folks in Slack, #need-reveiw-queue. We are working to keep the size of Needs Review queue [2700+ issues] to around 400 (1 month or less), following Review a patch or merge request as a guide.
Manually tested the patch on 10.1.x-dev and it resolves the issue. The IS looks good. Before/after screenshots for this iteration were added in #52.
I wondered if this should use FormattableMarkup, but given that
\d+matches only integer values, I think it can be ommitted in this case. Didn't find any other issues. So I'd say the code looks good.Bottom line: I think the issue is RTBC.
Comment #55
smustgrave commentedRandom failure
Comment #57
smustgrave commentedRandom
Comment #59
smustgrave commentedThink it's random.
Comment #61
smustgrave commentedRandom failure
Comment #63
larowlanubernit: do we need two calls to isset here?
I think php will allow just the second one
Fine to self-rtbc after that change, please ping me to look again at that point.
Comment #64
akashkumar07 commentedHi @larowlan,
I have removed the
isset($items[$delta])as per #63 comment.Thanks!
Comment #65
larowlanLooks like failing linting, thanks
Comment #66
mrinalini9 commentedUpdated patch #64 by fixing it, please review it.
Thanks!
Comment #67
smustgrave commentedRemoving credit for Ahmad Smhan for the empty commit
#64 appeared to be adding out of scope of changes
#66 seems good. Since this was previously RTBC and nitpicky change, think safe to remark it.
Comment #68
larowlanUpdating issue credits
Comment #69
larowlanI was about to commit this and whilst going through my internal checklist realised that we're making a widget/form level change here but we're not doing anything to address API level changes too.
Which leads me to believe that the fix probably belongs in LinkItem instead of in the widget.
So can we undo our changes to the widget here and instead change LinkItem::setValue to set the title to NULL when the title option is set to Disabled
We can use \Drupal\Tests\link\Kernel\LinkItemTest::testLinkItem to extend test coverage for that change.
We can retain the test changes we've made in this issue, but we need to undo the changes to the widget.
Sorry for not realising this sooner, I realise we've been around and around a few times on this one.
Comment #73
dcam commentedPer @larowlan's comment in #69 I moved the changes to
LinkItem::setValue().Comment #74
smustgrave commentedFeedback appears to be addressed.
Comment #75
catchThis is going to silently delete old data which if a site is experimenting with field settings might possibly want to be kept around. Including in migrations judging by the test changes.
What about checking the field setting in the formatter instead?
Comment #76
dcam commentedYou'd have to implement the setting check in every formatter. There's no guarantee contrib formatters would comply or that compliance would happen quickly. That could result in an issue where a link is displayed with different formatters in different contexts where it's rendered with and without a title.
I'm also concerned about the title subfield getting disabled and then re-enabled at some point much later on. During that time span links may be changed, but old hidden title values would be retained and could get out-of-date. That thought kind of drives home the point that we're going down a rabbit hole of edge cases. Regardless, it's a concern.
I don't know that there's a perfect solution.
Comment #78
smustgrave commented@catch thoughts on #76?
Comment #79
smustgrave commented@catch what do you think about landing in 12 only? As dcam mentioned may not have a perfect solution but this seems like an improvement.
Comment #80
godotislateApologies, I know this one's gone around a couple times, but I think we can address #75 by overriding the magic getter instead of setting the value to NULL in setValue(). (For D12, we could also use property hooks once we figure out what we're going to do about code style sniffs, but that's a follow up.)
Something like
Edited to add:
Actually, maybe not. I think this might cause the empty value to be set in storage on a re-save.
Comment #81
dcam commentedYes, it does. I tested it by removing the current changes to
LinkItemand adding the magic getter from #80. The title was set to NULL upon re-saving the entity while the title field was disabled.I'm restoring the RTBC status.