If I enter an ampersand character (&) in a group title, it gets double-escaped in the final output. This is because Html::escape() is being called on it, but it will still get escaped again before reaching the page (though I'm not quite sure at what point).
(This issue is very much related to #2652934: Horizontal tab title is not properly retrieved from the details form element and all title html attributes are lost, which was asking to allow HTML in group titles, but the committed solution did not actually match the problem. If HTML can get supported correctly, then this issue can be rejected. This is just about solving the double-escaping, but personally I'd actually prefer to be able to have HTML in my tab titles.)
| Comment | File | Size | Author |
|---|---|---|---|
| #25 | field_group-double_escaped_titles-2822299-25.patch | 3.86 KB | anshu raj |
| #24 | field_group-double_escaped_titles-2822299-24.patch | 3.6 KB | luke adams |
Comments
Comment #2
james.williamsHere's a patch.
Comment #3
jmarcou commentedThe bug was originally introduce with this fix : https://www.drupal.org/node/2698405
When
SafeMarkup::checkPlain()was replaced byHtml::escape().Html::escapereturns a string, whereasSafeMarkup::checkPlain()return an MarkupInterface object (like$this->t()orMarkup::create()), so the "#title" key should contain a MarkupInterface object.Now why this get double-escaped for the "Tab" widget (which is in fact a "Details" with additional features) and not for a "Fieldset" widget even if they have the same title value as input ?
You can find the answer in the "/core/includes/form.inc" file of Drupal Core.
For a "Details" widget, the title gets generated like that :
$variables['title'] = (!empty($element['#title'])) ? $element['#title'] : '';When "Fieldset" widget generates the title like that :
(Notice how the value is wrapped in an array with the key "#markup" to mimic a MarkupInterface object)
If you try to replace
$variables['title'] = (!empty($element['#title'])) ? $element['#title'] : '';by
$variables['title'] = ['#markup' => (!empty($element['#title'])) ? $element['#title'] : ''];you'll see it do the trick too.
So may be, it's a Drupal Core issue originally ; but I suggest every variables given to Twig templates to be MarkupInterface objects to not rely on the Drupal Core behavior, as it was before the bug was introduce.
+1 for the "Markup::create(Html::escape())" instead of the simple "Html::escape()", it does the job, but there are probably other places to tweak.
Comment #4
duaelfrAs the titles are supposed to be translatables, the t() method call can be the solution because it returns a MarkupInterface compatible object.
Instead of escaping the translated string, which is considered safe as it's been through locale_string_is_safe(), we should escape the label before translating.
Please, find an attached patch for all the existing field_group plugins.
Comment #5
steven jones commentedHere's a patch that allows me to pop HTML into the title of my HTML element. Mainly because I need this and needed somewhere to host the patch.
This should probably be a new plugin in a new module somewhere.
Comment #6
steven jones commentedActually, that patch was wrong sorry.
Comment #8
duaelfr@Steven Jones you really should open a new issue because you're probably not the only one that would need to put HTML in the groups titles.
(and, you should not pollute this issue posting new, incomplete, patches as it could confuse the maintainers)
Comment #9
tobiberlinI tried patch from https://www.drupal.org/node/2822299#comment-11789150 as well as from https://www.drupal.org/node/2822299#comment-11838595 - but with both patches applied the field group title is not translated anymore.
Comment #10
duaelfr@tobiberlin as the strings are given to the translation engine after having been sanitized, it's possible that you have to re-translate them in the UI. Can you try to check in the translation UI if the strings are there, please?
Comment #11
tobiberlinI just created a new field group (HTML element) to check. I find the title of my field group in the translataion UI and can add the translated string but in frontend it does not change in my case. I tried cache rebuilding, visiting the page in English and German but nothing changes - the title of the field group remains English
Comment #12
sutharsan commentedI propose a radically different approach: #2846617: Do not translate field group labels using interface translation.
This issue only solves double escaping, but still strings get translated. Labels that have translated interface strings, still get translated with strings from a different context (the interface).
Comment #13
duaelfr@Sutharsan That's interesting. I think we can close this issue as duplicate as yours also solve the problem.
Comment #14
james.williamsRemoving translation may be an option, but that's not really the answer for this ticket. Whether a group title should be translatable or not ought to be a separate discussion. First, a solution should be found that doesn't change the translatability, but avoids double-escaped HTML in group titles.
Comment #15
screon commentedPatch from #4 works for me!
Comment #16
duaelfr#14: the related issue is not about removing translations, it's about removing translations from the "interface translations". In D8, we have a brand new Config Translation module in the Core that should already allow to translate field group labels. In fact, there is nothing right now in field_group to interface with this module and that's what should be changed. Finally, this issue could be commited right now to fix the double-escapment issue but it might be a temporary workaround.
Comment #17
james.williams@DuaelFr yes, I totally agree :-) Translation needs resolving, and double-escaping needs resolving. But resolving one does not automatically resolve the other, so decisions need making about either and/or both.
Comment #18
duaelfrGiven the review in #15
Given my comment in #16 about this patch being a temporary workaround while there is no way to use Config Translation for field groups
I think the solution in #4 needs to be pushed as a temporary fix for this issue then, when Core is ready, we'll be able to remove translations to rely on Config Translations.
I rerolled the #4 patch to ensure it can be applied so let's review it one last time :)
Comment #19
james.williamsI guess I'll drop objections for now.
My approach in comment 2 wrapped the existing
Html::escape($this->t($this->getLabel()))with aMarkup::create(), which meant the source string for translations didn't change, so translations wouldn't need redoing. Comment 3 agreed with that approach. But I can live with the approach of the latest patch for the sake of getting this through :-) Thanks DuaelFr for the re-roll!Comment #20
anybodyWhen testing these patches also use #2652934: Horizontal tab title is not properly retrieved from the details form element and all title html attributes are lost to fix the display of horizontal tab titles. That issue also needs review, see #15.
For me that patch was enough to make tab titles show HTML. The patch from THIS (12343286) issue was not required to make the HTML code appear.
Comment #21
benjy commentedPatch worked for me. +1
Comment #22
heddnI can be pragmatic myself. But I tend to agree with the uckyness feeling around the abuse of the translation calls.
Comment #23
james.williamsThe latest patch on #2846617: Do not translate field group labels using interface translation. now ensures field group labels are properly translatable, and addresses HTML double-escaping too. So as comment 16/18 stated this issue was a temporary workaround in the meantime whilst that wasn't possible, I don't think we need this any more. The two tickets' patches certainly conflict anyway, so let's just progress in one ticket.
Comment #24
luke adams commentedI know this issue was initially raised against the 1.0-dev branch, and is closed. I'm only adding this comment here because the proper/appropriate steps are being taken for the 3.x-dev branch and raising another issue/duplicate for this 'temporary fix' just seems cruel...
For anyone running the 8.x-3.0-beta1 branch and not able to update to 3.0-dev, this may save you some time.
I was having issues applying the #18 patch in this thread (aka, patch failed to apply) in order to maintain displaying an & in a field group label. I found the patch for field_ui.inc file specifically was the issue, line 144 became line 161 in the patch file I manually created. I have tested it by downloading the .tar from the module homepage and simply running git apply
.
Comment #25
anshu raj commentedBasically I am applying the patch for ^3.2 which is compatible with Drupal 9. If anyone running the 8.x-3.2 branch it maybe helpful.