diff --git a/core/includes/theme.inc b/core/includes/theme.inc index 2929bc2..56b711e 100644 --- a/core/includes/theme.inc +++ b/core/includes/theme.inc @@ -455,7 +455,6 @@ function _theme_process_registry(&$cache, $name, $type, $theme, $path) { 'render element' => TRUE, 'pattern' => TRUE, 'base hook' => TRUE, - 'original module' => NULL, ); $module_list = array_keys(Drupal::moduleHandler()->getModuleList()); @@ -502,12 +501,6 @@ function _theme_process_registry(&$cache, $name, $type, $theme, $path) { if (isset($cache[$hook])) { $result[$hook] += array_intersect_key($cache[$hook], $hook_defaults); } - // If this is the first implementation of this theme hook by a module, - // keep track of the module name in the registry so it can be available - // to theme() even if other modules and themes implement the same hook. - else if ($type == 'module') { - $result[$hook]['original module'] = $name; - } // The following apply only to theming hooks implemented as templates. if (isset($info['template'])) { @@ -1009,7 +1002,7 @@ function theme($hook, $variables = array()) { 'theme_hook_original' => $original_hook, ); - // Set base hook for later use. This way if e.g. '#theme' => 'node__article' + // Set base hook for later use. For example if '#theme' => 'node__article' // is called, we run hook_theme_suggestions_node_alter() rather than // hook_theme_suggestions_node__article_alter(), and also pass in the base // hook as the last parameter to the suggestions alter hooks. @@ -1020,15 +1013,15 @@ function theme($hook, $variables = array()) { $base_theme_hook = $hook; } - // Invoke theme suggestion hook for the module originally defining the theme - // hook. - if (isset($info['original module'])) { - $suggestions = (array) Drupal::moduleHandler()->invoke($info['original module'], 'theme_suggestions_' . $base_theme_hook, array($variables)); - } - else { - $suggestions = array(); + // Invoke hook_theme_suggestions_HOOK(). + $suggestions = Drupal::moduleHandler()->invokeAll('theme_suggestions_' . $base_theme_hook, array($variables)); + // If theme() was invoked with a direct theme suggestion like + // '#theme' => 'node__article', add it to the suggestions array before + // invoking suggestion alter hooks. + if (isset($info['base hook'])) { + $suggestions[] = $hook; } - // Allow theme suggestions to be altered. + // Allow suggestions to be altered via hook_theme_suggestions_HOOK_alter(). Drupal::moduleHandler()->alter('theme_suggestions_' . $base_theme_hook, $suggestions, $variables); // Check if each suggestion exists in the theme registry, and if so, @@ -1054,9 +1047,7 @@ function theme($hook, $variables = array()) { include_once DRUPAL_ROOT . '/' . $include_file; } } - // Previously we just replaced the entire $info array with $base_hook_info - // if any preprocess functions were set, but now we determine the - // suggestions first and then fire the appropriate preprocess functions. + // Replace the preprocess functions with those from the base hook. if (isset($base_hook_info['preprocess functions'])) { $info['preprocess functions'] = $base_hook_info['preprocess functions']; } diff --git a/core/modules/system/lib/Drupal/system/Tests/Theme/ThemeSuggestionsAlterTest.php b/core/modules/system/lib/Drupal/system/Tests/Theme/ThemeSuggestionsAlterTest.php index 7e2636c..1507279 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Theme/ThemeSuggestionsAlterTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Theme/ThemeSuggestionsAlterTest.php @@ -87,11 +87,13 @@ function testSpecificSuggestionsAlter() { // Test a specific theme call similar to '#theme' => 'node__article'. $this->drupalGet('theme-test/specific-suggestion-alter'); $this->assertText('Template matching the specific theme call.'); + $this->assertText('theme_test_specific_suggestions__variant', 'Specific theme call is added to the suggestions array.'); // Ensure that the base hook is used to determine the suggestion alter hook. module_enable(array('theme_suggestions_test')); $this->drupalGet('theme-test/specific-suggestion-alter'); $this->assertText('Template overridden based on suggestion alter hook determined by the base hook.'); + $this->assertTrue(strpos($this->drupalGetContent(), 'theme_test_specific_suggestions__variant') < strpos($this->drupalGetContent(), 'theme_test_specific_suggestions__variant__foo'), 'Specific theme call is added to the suggestions array before the suggestions alter hook.'); } /** diff --git a/core/modules/system/tests/themes/test_theme/templates/theme-test-specific-suggestions--variant--foo.html.twig b/core/modules/system/tests/themes/test_theme/templates/theme-test-specific-suggestions--variant--foo.html.twig index f0de75d..7e0b485 100644 --- a/core/modules/system/tests/themes/test_theme/templates/theme-test-specific-suggestions--variant--foo.html.twig +++ b/core/modules/system/tests/themes/test_theme/templates/theme-test-specific-suggestions--variant--foo.html.twig @@ -1,2 +1,5 @@ {# Output for Theme API test #} Template overridden based on suggestion alter hook determined by the base hook. + +

Theme hook suggestions: +{{ theme_hook_suggestions|join("
") }}

diff --git a/core/modules/system/tests/themes/test_theme/templates/theme-test-specific-suggestions--variant.html.twig b/core/modules/system/tests/themes/test_theme/templates/theme-test-specific-suggestions--variant.html.twig index 66edf9a..655db4e 100644 --- a/core/modules/system/tests/themes/test_theme/templates/theme-test-specific-suggestions--variant.html.twig +++ b/core/modules/system/tests/themes/test_theme/templates/theme-test-specific-suggestions--variant.html.twig @@ -1,2 +1,5 @@ {# Output for Theme API test #} Template matching the specific theme call. + +

Theme hook suggestions: +{{ theme_hook_suggestions|join("
") }}