Problem/Motivation
Core issue #3178202 renders page regions with '#theme' => 'region' instead of adding region to #theme_wrappers. Core's region preprocess then sets $variables['content'] to an array of the region's block render arrays, keyed by block ID.
Bootstrap's Region preprocess plugin overwrites that variable with $variables['elements']['#children']. With #theme, the renderer initialises #children to '' before the template runs, so content becomes empty and every region renders nothing. On core 11.4.8 with the core MR applied, Bootstrap rendered 0 regions on every page tested.
Steps to reproduce
- Core 11.x, with Bootstrap 8.x-3.x as the default theme.
- Apply the MR from #3178202.
- Visit any page: no regions render.
Proposed resolution
Stop overwriting content in Region::preprocessVariables();.
Help region: when content is an array, render it first, and add the alert classes and icon only if it isn't empty.
In both region templates, render content once and print the wrapper only when the trimmed output isn't empty (the pattern core's draft change record suggests).
This works on core both before and after #3178202, with no core version check. On current core it makes no difference: content is the same string Bootstrap was copying.
5.0.x is not affected. 8.x-4.x has the same code and gets the same fix.
Generated with the help of an LLM.
| Comment | File | Size | Author |
|---|---|---|---|
| #15 | bootstrap-region-escaped-3628721-15.patch | 1.64 KB | fenstrat |
Issue fork bootstrap-3628721
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
philltran commentedComment #5
philltran commentedMade an MR each for the 8.3.x and 8.4.x branches.
Comment #6
joseph.olstadComment #10
joseph.olstadComment #11
joseph.olstadComment #13
mprell commentedAfter updating to 8.x-3.42 (which includes this change), every region renders as escaped HTML. Block markup and any Twig debug comments show up on the page as literal text.
Environment:
- Drupal core 10.6.18
- Twig 3.30.0
- Bootstrap 8.x-3.42
- PHP 8.3 (Pantheon)
I've tested on two different sites, using Bootstrap's unmodified region.html.twig, and got the same results with Bootstrap and a Bootstrap sub theme. Error does not occur when switching to other themes.
Comment #14
aitala commentedI basically had the same issue as in #13
Eric
Comment #15
fenstratConfirming #13 and #14. 3.42 escapes every region on Drupal 10.6.18.
Cause: {% set rendered = content|render %}. On current core, region content is the Markup from #children. TwigExtension::renderVar() only returns MarkupInterface objects unchanged since #2334319, which is in 11.2.5+ but not 10.x. On earlier core it returns (string) $arg, so {{ rendered }} is autoescaped. That's why it passed on 11.4.8. Affected: 10.6 and 11.2.0–11.2.4, all within the theme's ^10.5 || ^11.2 support. CI doesn't set OPT_IN_TEST_PREVIOUS_MAJOR, so D10 isn't tested.
Fix: capture instead of using the filter. It renders once and the result stays safe on all core versions, with or without #3178202:
{% set rendered %}{{ content }}{% endset %}This contribution was developed with AI assistance throughout the process. I reviewed the change, understand it, and take responsibility for its correctness.
Comment #17
joseph.olstadhmm , I didn't notice this on Drupal 11.3.x, however I will test this.
Comment #18
joseph.olstadTested, was same before and after for me with Drupal 11.3
https://www.drupal.org/project/bootstrap/releases/8.x-3.43