Problem/Motivation
Tab titles containing special characters such as "&" are rendered as literal "&" in the browser instead of the intended character. The issue is a double HTML-encoding chain in QuickTabs.php.
Steps to reproduce
1. Create a Quicktabs instance with a tab title that contains an ampersand, e.g. Meetings & Events.
2. Place the block on a page and view it.
3. Observe the tab label renders as "Meetings & Events" instead of "Meetings & Events".
Proposed resolution
Remove the t('@title', ...) wrapper (stored tab titles are not translatable strings) and wrap the Xss::filter() result in Markup::create() so that Link::fromTextAndUrl() recognizes it as already-sanitized HTML. Also add the required "use Drupal\Core\Render\Markup;" statement.
User interface changes
Tab titles with special characters (&, <, >, quotes) will now render correctly instead of showing escaped HTML entities.
| Comment | File | Size | Author |
|---|---|---|---|
| #2 | 3588550-2-tab-title-double-encoding.patch | 780 bytes | lucuella |
| Screenshot 2026-05-05 at 3.59.49 PM.png | 117.12 KB | lucuella |
Issue fork quicktabs-3588550
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
lucuella commentedAttaching patch against 4.1.0. The fix removes the
t('@title', [...])wrapper that was causing the first encoding pass, and wraps theXss::filter()result inMarkup::create()soLink::fromTextAndUrl()does not escape it a second time.Comment #3
lucuella commentedComment #4
joelpittetMoving to the dev branch. We really should see the patch in an MR.
This also feels like deja vu, maybe I fixed this already in dev? Currently doesn't apply. It should have been fixed in #3545740: Tab Title HTML encoding issue
If it's still an issue please let me know and we can re-open this.
Comment #6
joelpittetI'm still seeing this actually, darn re-opening. Need to move to an MR
Comment #7
joelpittetThank you @lucuella there was indeed a missing spot that wasn't fixed by the other issue. I will commit the fix and a regression test in a moment.
Comment #10
joelpittetThis is interesting, I am getting an AI to do the fix, but I am very familiar with double escaping as I was heavily involved in this part of Drupal 8 development more than a decade ago! See #1825952: Turn on twig autoescape by default for creds.
It first tried to flatten the label to a string, render it with
PlainTextOutputfrom HTML then concatinate it... but you don't need to flatten or change it to not HTML, just let the pre-existingMarkupInterfaceobject keep holding on and pass that to an @param... it will recognize it's already been "marked safe" and not double escape it. As soon as you flatten it, it will rightly lose trust./rant
Comment #11
joelpittetOn the other hand it finds things I can't...
Wrap the grouping tab title in
Markup::create()so Link does not re-encode theXss::filter()output (e.g. "&" -> "&amp;"). Add the missingviews.style.quicktabsconfig schema and a functional regression test.