Issue #3073053 by pivica, Primsi, unstatu, pooja saraah, smustgrave, Berdir: Theme library override can fail in when you have multiple parent themes

merge-requests/5290/head
Dave Long 2024-01-11 11:56:25 +00:00
parent 30512d2ed7
commit 528ac5740a
No known key found for this signature in database
GPG Key ID: ED52AE211E142771
6 changed files with 35 additions and 6 deletions

View File

@ -183,7 +183,8 @@ class ActiveTheme {
* Returns an array of base theme extension objects keyed by name. * Returns an array of base theme extension objects keyed by name.
* *
* The order starts with the base theme of $this and ends with the root of * The order starts with the base theme of $this and ends with the root of
* the dependency chain. * the dependency chain. For most use cases, parent themes are expected to
* be called first, so this order needs to be reversed with array_reverse()
* *
* @return \Drupal\Core\Extension\Extension[] * @return \Drupal\Core\Extension\Extension[]
*/ */

View File

@ -131,14 +131,14 @@ class ThemeInitialization implements ThemeInitializationInterface {
if ($active_theme->getEngine()) { if ($active_theme->getEngine()) {
// Include the engine. // Include the engine.
include_once $this->root . '/' . $active_theme->getOwner(); include_once $this->root . '/' . $active_theme->getOwner();
foreach ($active_theme->getBaseThemeExtensions() as $base) { foreach (array_reverse($active_theme->getBaseThemeExtensions()) as $base) {
$base->load(); $base->load();
} }
$active_theme->getExtension()->load(); $active_theme->getExtension()->load();
} }
else { else {
// include non-engine theme files // include non-engine theme files
foreach ($active_theme->getBaseThemeExtensions() as $base) { foreach (array_reverse($active_theme->getBaseThemeExtensions()) as $base) {
// Include the theme file or the engine. // Include the theme file or the engine.
if ($base->owner) { if ($base->owner) {
include_once $this->root . '/' . $base->owner; include_once $this->root . '/' . $base->owner;
@ -178,7 +178,7 @@ class ThemeInitialization implements ThemeInitializationInterface {
$values['libraries_override'] = []; $values['libraries_override'] = [];
// Get libraries overrides declared by base themes. // Get libraries overrides declared by base themes.
foreach ($base_themes as $base) { foreach (array_reverse($base_themes) as $base) {
if (!empty($base->info['libraries-override'])) { if (!empty($base->info['libraries-override'])) {
foreach ($base->info['libraries-override'] as $library => $override) { foreach ($base->info['libraries-override'] as $library => $override) {
$values['libraries_override'][$base->getPath()][$library] = $override; $values['libraries_override'][$base->getPath()][$library] = $override;

View File

@ -436,7 +436,7 @@ class ThemeManager implements ThemeManagerInterface {
} }
} }
$theme_keys = array_keys($theme->getBaseThemeExtensions()); $theme_keys = array_reverse(array_keys($theme->getBaseThemeExtensions()));
$theme_keys[] = $theme->getName(); $theme_keys[] = $theme->getName();
$functions = []; $functions = [];
foreach ($theme_keys as $theme_key) { foreach ($theme_keys as $theme_key) {

View File

@ -3,3 +3,8 @@ type: theme
description: 'Test theme which uses test_subtheme as the base theme.' description: 'Test theme which uses test_subtheme as the base theme.'
version: VERSION version: VERSION
base theme: test_subtheme base theme: test_subtheme
libraries-override:
test_basetheme/global-styling:
css:
base:
css/sub-sub-last-override.css: false

View File

@ -1485,7 +1485,7 @@ class ViewExecutable {
// @todo In the long run, it would be great to execute a view without // @todo In the long run, it would be great to execute a view without
// the theme system at all. See https://www.drupal.org/node/2322623. // the theme system at all. See https://www.drupal.org/node/2322623.
$active_theme = \Drupal::theme()->getActiveTheme(); $active_theme = \Drupal::theme()->getActiveTheme();
$themes = array_keys($active_theme->getBaseThemeExtensions()); $themes = array_reverse(array_keys($active_theme->getBaseThemeExtensions()));
$themes[] = $active_theme->getName(); $themes[] = $active_theme->getName();
// Check for already-cached output. // Check for already-cached output.

View File

@ -127,6 +127,29 @@ class LibraryDiscoveryIntegrationTest extends KernelTestBase {
} }
} }
/**
* Tests libraries overrides with multiple parent themes.
*/
public function testLibrariesOverridesMultiple() {
/** @var \Drupal\Core\Extension\ThemeInstallerInterface $theme_installer */
$theme_installer = $this->container->get('theme_installer');
$theme_installer->install(['test_basetheme']);
$theme_installer->install(['test_subtheme']);
$theme_installer->install(['test_subsubtheme']);
/** @var \Drupal\Core\Theme\ThemeInitializationInterface $theme_initializer */
$theme_initializer = $this->container->get('theme.initialization');
$active_theme = $theme_initializer->initTheme('test_subsubtheme');
$libraries_override = $active_theme->getLibrariesOverride();
$expected_order = [
'core/modules/system/tests/themes/test_basetheme',
'core/modules/system/tests/themes/test_subtheme',
'core/modules/system/tests/themes/test_subsubtheme',
];
$this->assertEquals($expected_order, array_keys($libraries_override));
}
/** /**
* Tests library assets with other ways for specifying paths. * Tests library assets with other ways for specifying paths.
*/ */