diff --git a/core/includes/theme.inc b/core/includes/theme.inc index 0becb4ef68..b11e35bfb8 100644 --- a/core/includes/theme.inc +++ b/core/includes/theme.inc @@ -1529,7 +1529,10 @@ function template_preprocess_install_page(&$variables) { */ function template_preprocess_region(&$variables) { // Create the $content variable that templates expect. - $variables['content'] = $variables['elements']['#children']; + $variables['content'] = []; + foreach (Element::children($variables['elements']) as $key) { + $variables['content'][$key] = $variables['elements'][$key]; + } $variables['region'] = $variables['elements']['#region']; } diff --git a/core/lib/Drupal/Core/Render/MainContent/HtmlRenderer.php b/core/lib/Drupal/Core/Render/MainContent/HtmlRenderer.php index e8f8b5dfdc..b02849a680 100644 --- a/core/lib/Drupal/Core/Render/MainContent/HtmlRenderer.php +++ b/core/lib/Drupal/Core/Render/MainContent/HtmlRenderer.php @@ -270,12 +270,21 @@ protected function prepare(array $main_content, Request $request, RouteMatchInte $page += $page_display->build(); } - // $page is now fully built. Find all non-empty page regions, and add a - // theme wrapper function that allows them to be consistently themed. + // $page is now fully built. Find all non-empty page regions, and set a + // #theme property that allows them to be consistently themed. $regions = $this->themeManager->getActiveTheme()->getRegions(); foreach ($regions as $region) { if (!empty($page[$region])) { - $page[$region]['#theme_wrappers'][] = 'region'; + // On most pages, every $page[$region] is an array of block render + // arrays, keyed by block ID. However, in some rare cases (e.g. + // BatchController:batchPage) a render array with #type="page" is + // created manually and $page[$region] may already have a #type or + // #theme property. To avoid breaking this render array when we set the + // #theme="region" property, wrap it in an element "region_content". + if (isset($page[$region]['#type']) || isset($page[$region]['#theme'])) { + $page[$region] = ['region_content' => $page[$region]]; + } + $page[$region]['#theme'] = 'region'; $page[$region]['#region'] = $region; } } diff --git a/core/modules/system/templates/region.html.twig b/core/modules/system/templates/region.html.twig index 219e14b0a4..201e42176c 100644 --- a/core/modules/system/templates/region.html.twig +++ b/core/modules/system/templates/region.html.twig @@ -4,7 +4,10 @@ * Default theme implementation to display a region. * * Available variables: - * - content: The content for this region, typically blocks. + * - content: The content for this region, typically blocks. Use {{ content }} + * to print them all, or print a subset such as {{ content.page_title }}. + * Use {{ content|without('page_title') }} to temporarily suppress the + * printing of a given child element. * - attributes: HTML attributes for the region
. * - region: The name of the region variable as defined in the theme's * .info.yml file. diff --git a/core/modules/system/tests/src/Functional/Render/RegionContentRenderTest.php b/core/modules/system/tests/src/Functional/Render/RegionContentRenderTest.php new file mode 100644 index 0000000000..aa8b3fafb6 --- /dev/null +++ b/core/modules/system/tests/src/Functional/Render/RegionContentRenderTest.php @@ -0,0 +1,66 @@ + [ + 'label' => 'I am first', + 'weight' => '0', + ], + 'second' => [ + 'label' => 'I am second', + 'weight' => '1', + ], + 'special' => [ + 'label' => 'I am special', + 'weight' => '2', + ], + ]; + + // Place the test blocks in the header. + foreach ($test_blocks as $id => $test_block) { + $this->drupalPlaceBlock('system_powered_by_block', [ + 'region' => 'header', + 'id' => $id, + 'label' => $test_block['label'], + 'weight' => $test_block['weight'], + ]); + } + + // Test if the blocks are placed correctly in the region template. See + // core/modules/system/tests/themes/test_theme_region_content/templates/region--header.html.twig + $this->drupalGet(''); + $assert = $this->assertSession(); + $assert->elementExists('css', '#wrapper-special #block-special'); + $assert->elementExists('css', '#wrapper-the-rest #block-first'); + $assert->elementExists('css', '#wrapper-the-rest #block-second'); + $assert->elementNotExists('css', '#wrapper-the-rest #block-special'); + $assert->elementNotExists('css', '#wrapper-special #block-first'); + $assert->elementNotExists('css', '#wrapper-special #block-second'); + } + +} diff --git a/core/modules/system/tests/themes/test_theme_region_content/templates/region--header.html.twig b/core/modules/system/tests/themes/test_theme_region_content/templates/region--header.html.twig new file mode 100644 index 0000000000..9516b5e992 --- /dev/null +++ b/core/modules/system/tests/themes/test_theme_region_content/templates/region--header.html.twig @@ -0,0 +1,8 @@ +{% if content %} +
+ {{ content.special }} +
+
+ {{ content|without('special') }} +
+{% endif %} diff --git a/core/modules/system/tests/themes/test_theme_region_content/test_theme_region_content.info.yml b/core/modules/system/tests/themes/test_theme_region_content/test_theme_region_content.info.yml new file mode 100644 index 0000000000..4bb1bf6c7c --- /dev/null +++ b/core/modules/system/tests/themes/test_theme_region_content/test_theme_region_content.info.yml @@ -0,0 +1,5 @@ +name: 'Region content test' +type: theme +description: 'Theme to test the rendering of blocks in a region template.' +version: VERSION +base theme: stark diff --git a/core/profiles/demo_umami/themes/umami/templates/classy/layout/region.html.twig b/core/profiles/demo_umami/themes/umami/templates/classy/layout/region.html.twig index 95e71cec37..20ab315e9f 100644 --- a/core/profiles/demo_umami/themes/umami/templates/classy/layout/region.html.twig +++ b/core/profiles/demo_umami/themes/umami/templates/classy/layout/region.html.twig @@ -4,7 +4,10 @@ * Theme override to display a region. * * Available variables: - * - content: The content for this region, typically blocks. + * - content: The content for this region, typically blocks. Use {{ content }} + * to print them all, or print a subset such as {{ content.page_title }}. + * Use {{ content|without('page_title') }} to temporarily suppress the + * printing of a given child element. * - attributes: HTML attributes for the region
. * - region: The name of the region variable as defined in the theme's * .info.yml file. diff --git a/core/themes/claro/templates/classy/layout/region.html.twig b/core/themes/claro/templates/classy/layout/region.html.twig index 95e71cec37..20ab315e9f 100644 --- a/core/themes/claro/templates/classy/layout/region.html.twig +++ b/core/themes/claro/templates/classy/layout/region.html.twig @@ -4,7 +4,10 @@ * Theme override to display a region. * * Available variables: - * - content: The content for this region, typically blocks. + * - content: The content for this region, typically blocks. Use {{ content }} + * to print them all, or print a subset such as {{ content.page_title }}. + * Use {{ content|without('page_title') }} to temporarily suppress the + * printing of a given child element. * - attributes: HTML attributes for the region
. * - region: The name of the region variable as defined in the theme's * .info.yml file. diff --git a/core/themes/claro/templates/region--breadcrumb.html.twig b/core/themes/claro/templates/region--breadcrumb.html.twig index a66f43131d..e35f51cc8b 100644 --- a/core/themes/claro/templates/region--breadcrumb.html.twig +++ b/core/themes/claro/templates/region--breadcrumb.html.twig @@ -4,7 +4,10 @@ * Theme override to display a breadcrumb region. * * Available variables: - * - content: The content for this region, typically blocks. + * - content: The content for this region, typically blocks. Use {{ content }} + * to print them all, or print a subset such as {{ content.page_title }}. + * Use {{ content|without('page_title') }} to temporarily suppress the + * printing of a given child element. * - attributes: HTML attributes for the region
. * - region: The name of the region variable as defined in the theme's * .info.yml file. diff --git a/core/themes/olivero/templates/layout/region--breadcrumb.html.twig b/core/themes/olivero/templates/layout/region--breadcrumb.html.twig index 5dbd5d45ff..6fb2017416 100644 --- a/core/themes/olivero/templates/layout/region--breadcrumb.html.twig +++ b/core/themes/olivero/templates/layout/region--breadcrumb.html.twig @@ -4,7 +4,10 @@ * Olivero's theme override to display the breadcrumb region. * * Available variables: - * - content: The content for this region, typically blocks. + * - content: The content for this region, typically blocks. Use {{ content }} + * to print them all, or print a subset such as {{ content.page_title }}. + * Use {{ content|without('page_title') }} to temporarily suppress the + * printing of a given child element. * - attributes: HTML attributes for the region
. * - region: The name of the region variable as defined in the theme's * .info.yml file. diff --git a/core/themes/olivero/templates/layout/region--content-above.html.twig b/core/themes/olivero/templates/layout/region--content-above.html.twig index e50082ea39..01812cdc80 100644 --- a/core/themes/olivero/templates/layout/region--content-above.html.twig +++ b/core/themes/olivero/templates/layout/region--content-above.html.twig @@ -4,7 +4,10 @@ * Olivero's theme override to display the content above region. * * Available variables: - * - content: The content for this region, typically blocks. + * - content: The content for this region, typically blocks. Use {{ content }} + * to print them all, or print a subset such as {{ content.page_title }}. + * Use {{ content|without('page_title') }} to temporarily suppress the + * printing of a given child element. * - attributes: HTML attributes for the region
. * - region: The name of the region variable as defined in the theme's * .info.yml file. diff --git a/core/themes/olivero/templates/layout/region--content-below.html.twig b/core/themes/olivero/templates/layout/region--content-below.html.twig index c0f9ed29e5..d8e856c65a 100644 --- a/core/themes/olivero/templates/layout/region--content-below.html.twig +++ b/core/themes/olivero/templates/layout/region--content-below.html.twig @@ -4,7 +4,10 @@ * Olivero's theme override to display the content below region. * * Available variables: - * - content: The content for this region, typically blocks. + * - content: The content for this region, typically blocks. Use {{ content }} + * to print them all, or print a subset such as {{ content.page_title }}. + * Use {{ content|without('page_title') }} to temporarily suppress the + * printing of a given child element. * - attributes: HTML attributes for the region
. * - region: The name of the region variable as defined in the theme's * .info.yml file. diff --git a/core/themes/olivero/templates/layout/region--content.html.twig b/core/themes/olivero/templates/layout/region--content.html.twig index 7f86b58103..21556bcc1b 100644 --- a/core/themes/olivero/templates/layout/region--content.html.twig +++ b/core/themes/olivero/templates/layout/region--content.html.twig @@ -4,7 +4,10 @@ * Olivero's theme override to display the content region. * * Available variables: - * - content: The content for this region, typically blocks. + * - content: The content for this region, typically blocks. Use {{ content }} + * to print them all, or print a subset such as {{ content.page_title }}. + * Use {{ content|without('page_title') }} to temporarily suppress the + * printing of a given child element. * - attributes: HTML attributes for the region
. * - region: The name of the region variable as defined in the theme's * .info.yml file. diff --git a/core/themes/olivero/templates/layout/region--footer-bottom.html.twig b/core/themes/olivero/templates/layout/region--footer-bottom.html.twig index 36ffd885f9..978b8d5c57 100644 --- a/core/themes/olivero/templates/layout/region--footer-bottom.html.twig +++ b/core/themes/olivero/templates/layout/region--footer-bottom.html.twig @@ -4,7 +4,10 @@ * Olivero's theme override to display the footer bottom region. * * Available variables: - * - content: The content for this region, typically blocks. + * - content: The content for this region, typically blocks. Use {{ content }} + * to print them all, or print a subset such as {{ content.page_title }}. + * Use {{ content|without('page_title') }} to temporarily suppress the + * printing of a given child element. * - attributes: HTML attributes for the region
. * - region: The name of the region variable as defined in the theme's * .info.yml file. diff --git a/core/themes/olivero/templates/layout/region--footer-top.html.twig b/core/themes/olivero/templates/layout/region--footer-top.html.twig index 8baaf31405..a09ec7d6a6 100644 --- a/core/themes/olivero/templates/layout/region--footer-top.html.twig +++ b/core/themes/olivero/templates/layout/region--footer-top.html.twig @@ -4,7 +4,10 @@ * Olivero's theme override to display the footer top region. * * Available variables: - * - content: The content for this region, typically blocks. + * - content: The content for this region, typically blocks. Use {{ content }} + * to print them all, or print a subset such as {{ content.page_title }}. + * Use {{ content|without('page_title') }} to temporarily suppress the + * printing of a given child element. * - attributes: HTML attributes for the region
. * - region: The name of the region variable as defined in the theme's * .info.yml file. diff --git a/core/themes/olivero/templates/layout/region--header.html.twig b/core/themes/olivero/templates/layout/region--header.html.twig index 8ecee66336..3d8cee29d1 100644 --- a/core/themes/olivero/templates/layout/region--header.html.twig +++ b/core/themes/olivero/templates/layout/region--header.html.twig @@ -4,7 +4,10 @@ * Olivero's theme override to display the header region. * * Available variables: - * - content: The content for this region, typically blocks. + * - content: The content for this region, typically blocks. Use {{ content }} + * to print them all, or print a subset such as {{ content.page_title }}. + * Use {{ content|without('page_title') }} to temporarily suppress the + * printing of a given child element. * - attributes: HTML attributes for the region
. * - region: The name of the region variable as defined in the theme's * .info.yml file. diff --git a/core/themes/olivero/templates/layout/region--highlighted.html.twig b/core/themes/olivero/templates/layout/region--highlighted.html.twig index 6c42936807..f8b2c90b00 100644 --- a/core/themes/olivero/templates/layout/region--highlighted.html.twig +++ b/core/themes/olivero/templates/layout/region--highlighted.html.twig @@ -4,7 +4,10 @@ * Olivero's theme override to display the content region. * * Available variables: - * - content: The content for this region, typically blocks. + * - content: The content for this region, typically blocks. Use {{ content }} + * to print them all, or print a subset such as {{ content.page_title }}. + * Use {{ content|without('page_title') }} to temporarily suppress the + * printing of a given child element. * - attributes: HTML attributes for the region
. * - region: The name of the region variable as defined in the theme's * .info.yml file. diff --git a/core/themes/olivero/templates/layout/region--primary-menu.html.twig b/core/themes/olivero/templates/layout/region--primary-menu.html.twig index 32ade151fe..e0310cf513 100644 --- a/core/themes/olivero/templates/layout/region--primary-menu.html.twig +++ b/core/themes/olivero/templates/layout/region--primary-menu.html.twig @@ -4,7 +4,10 @@ * Olivero's theme override to display the header region. * * Available variables: - * - content: The content for this region, typically blocks. + * - content: The content for this region, typically blocks. Use {{ content }} + * to print them all, or print a subset such as {{ content.page_title }}. + * Use {{ content|without('page_title') }} to temporarily suppress the + * printing of a given child element. * - attributes: HTML attributes for the region
. * - region: The name of the region variable as defined in the theme's * .info.yml file. diff --git a/core/themes/olivero/templates/layout/region--secondary-menu.html.twig b/core/themes/olivero/templates/layout/region--secondary-menu.html.twig index ce7312194f..2ca6515f5e 100644 --- a/core/themes/olivero/templates/layout/region--secondary-menu.html.twig +++ b/core/themes/olivero/templates/layout/region--secondary-menu.html.twig @@ -4,7 +4,10 @@ * Olivero's theme override to display the header region. * * Available variables: - * - content: The content for this region, typically blocks. + * - content: The content for this region, typically blocks. Use {{ content }} + * to print them all, or print a subset such as {{ content.page_title }}. + * Use {{ content|without('page_title') }} to temporarily suppress the + * printing of a given child element. * - attributes: HTML attributes for the region
. * - region: The name of the region variable as defined in the theme's * .info.yml file. diff --git a/core/themes/olivero/templates/layout/region--sidebar.html.twig b/core/themes/olivero/templates/layout/region--sidebar.html.twig index a3f88864f9..da61a31107 100644 --- a/core/themes/olivero/templates/layout/region--sidebar.html.twig +++ b/core/themes/olivero/templates/layout/region--sidebar.html.twig @@ -4,7 +4,10 @@ * Olivero's theme override to display the sidebar region. * * Available variables: - * - content: The content for this region, typically blocks. + * - content: The content for this region, typically blocks. Use {{ content }} + * to print them all, or print a subset such as {{ content.page_title }}. + * Use {{ content|without('page_title') }} to temporarily suppress the + * printing of a given child element. * - attributes: HTML attributes for the region
. * - region: The name of the region variable as defined in the theme's * .info.yml file. diff --git a/core/themes/olivero/templates/layout/region--social.html.twig b/core/themes/olivero/templates/layout/region--social.html.twig index 6f3cf69740..f47e948cbb 100644 --- a/core/themes/olivero/templates/layout/region--social.html.twig +++ b/core/themes/olivero/templates/layout/region--social.html.twig @@ -4,7 +4,10 @@ * Olivero's theme override to display the social region. * * Available variables: - * - content: The content for this region, typically blocks. + * - content: The content for this region, typically blocks. Use {{ content }} + * to print them all, or print a subset such as {{ content.page_title }}. + * Use {{ content|without('page_title') }} to temporarily suppress the + * printing of a given child element. * - attributes: HTML attributes for the region
. * - region: The name of the region variable as defined in the theme's * .info.yml file. diff --git a/core/themes/olivero/templates/layout/region.html.twig b/core/themes/olivero/templates/layout/region.html.twig index 651a0112a5..cf04369f61 100644 --- a/core/themes/olivero/templates/layout/region.html.twig +++ b/core/themes/olivero/templates/layout/region.html.twig @@ -4,7 +4,10 @@ * Olivero's theme override to display a region. * * Available variables: - * - content: The content for this region, typically blocks. + * - content: The content for this region, typically blocks. Use {{ content }} + * to print them all, or print a subset such as {{ content.page_title }}. + * Use {{ content|without('page_title') }} to temporarily suppress the + * printing of a given child element. * - attributes: HTML attributes for the region
. * - region: The name of the region variable as defined in the theme's * .info.yml file. diff --git a/core/themes/stable9/templates/layout/region.html.twig b/core/themes/stable9/templates/layout/region.html.twig index e5e36d0741..2f78982582 100644 --- a/core/themes/stable9/templates/layout/region.html.twig +++ b/core/themes/stable9/templates/layout/region.html.twig @@ -4,7 +4,10 @@ * Theme override to display a region. * * Available variables: - * - content: The content for this region, typically blocks. + * - content: The content for this region, typically blocks. Use {{ content }} + * to print them all, or print a subset such as {{ content.page_title }}. + * Use {{ content|without('page_title') }} to temporarily suppress the + * printing of a given child element. * - attributes: HTML attributes for the region
. * - region: The name of the region variable as defined in the theme's * .info.yml file. diff --git a/core/themes/starterkit_theme/templates/layout/region.html.twig b/core/themes/starterkit_theme/templates/layout/region.html.twig index 95e71cec37..20ab315e9f 100644 --- a/core/themes/starterkit_theme/templates/layout/region.html.twig +++ b/core/themes/starterkit_theme/templates/layout/region.html.twig @@ -4,7 +4,10 @@ * Theme override to display a region. * * Available variables: - * - content: The content for this region, typically blocks. + * - content: The content for this region, typically blocks. Use {{ content }} + * to print them all, or print a subset such as {{ content.page_title }}. + * Use {{ content|without('page_title') }} to temporarily suppress the + * printing of a given child element. * - attributes: HTML attributes for the region
. * - region: The name of the region variable as defined in the theme's * .info.yml file.