Issue #2861840 by tim.plunkett, lauriii: Preprocess functions are not merged when a module registers a theme hook for a theme-provided template

8.5.x
Lee Rowlands 2018-01-06 14:40:50 +10:00
parent 71584842ea
commit 0f2bebf2e0
No known key found for this signature in database
GPG Key ID: 2B829A3DF9204DC4
8 changed files with 66 additions and 1 deletions

View File

@ -2,6 +2,7 @@
namespace Drupal\Core\Theme; namespace Drupal\Core\Theme;
use Drupal\Component\Utility\NestedArray;
use Drupal\Core\Cache\Cache; use Drupal\Core\Cache\Cache;
use Drupal\Core\Cache\CacheBackendInterface; use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\DestructableInterface; use Drupal\Core\DestructableInterface;
@ -565,10 +566,18 @@ class Registry implements DestructableInterface {
$info['preprocess functions'] = array_merge($cache[$hook]['preprocess functions'], $info['preprocess functions']); $info['preprocess functions'] = array_merge($cache[$hook]['preprocess functions'], $info['preprocess functions']);
} }
$result[$hook]['preprocess functions'] = $info['preprocess functions']; $result[$hook]['preprocess functions'] = $info['preprocess functions'];
// If a theme implementation definition provides both 'template' and
// 'function', the 'function' will be used. In this case, if the new
// result provides a 'template' value, any existing 'function' value
// must be removed for the override to be called.
if (isset($result[$hook]['template'])) {
unset($cache[$hook]['function']);
}
} }
// Merge the newly created theme hooks into the existing cache. // Merge the newly created theme hooks into the existing cache.
$cache = $result + $cache; $cache = NestedArray::mergeDeep($cache, $result);
} }
// Let themes have variable preprocessors even if they didn't register a // Let themes have variable preprocessors even if they didn't register a

View File

@ -33,6 +33,17 @@ class LayoutTest extends KernelTestBase {
$this->layoutPluginManager = $this->container->get('plugin.manager.core.layout'); $this->layoutPluginManager = $this->container->get('plugin.manager.core.layout');
} }
/**
* Tests that a layout provided by a theme has the preprocess function set.
*/
public function testThemeProvidedLayout() {
$this->container->get('theme_installer')->install(['test_layout_theme']);
$this->config('system.theme')->set('default', 'test_layout_theme')->save();
$theme_definitions = $this->container->get('theme.registry')->get();
$this->assertTrue(in_array('template_preprocess_layout', $theme_definitions['test_layout_theme']['preprocess functions']));
}
/** /**
* Test rendering a layout. * Test rendering a layout.
* *

View File

@ -0,0 +1,6 @@
name: 'Test layout theme'
type: theme
description: 'Theme for testing a theme-provided layout'
version: VERSION
base theme: classy
core: 8.x

View File

@ -0,0 +1,7 @@
test_layout_theme:
label: 'Test Layout - Theme'
category: 'Test Layout Theme'
template: templates/test-layout-theme
regions:
content:
label: Content

View File

@ -66,6 +66,10 @@ function theme_test_theme($existing, $type, $theme, $path) {
'bar' => '', 'bar' => '',
], ],
]; ];
$items['theme_test_registered_by_module'] = [
'render element' => 'content',
'base hook' => 'container',
];
return $items; return $items;
} }
@ -213,3 +217,9 @@ function theme_test_theme_suggestions_node(array $variables) {
return $suggestions; return $suggestions;
} }
/**
* Implements template_preprocess_HOOK() for theme_test_registered_by_module.
*/
function template_preprocess_theme_test_registered_by_module() {
}

View File

@ -0,0 +1,2 @@
{# Output for Theme API test #}
Template provided by theme is registered by module.

View File

@ -192,4 +192,23 @@ class RegistryTest extends KernelTestBase {
], $suggestions, 'Found expected page node suggestions.'); ], $suggestions, 'Found expected page node suggestions.');
} }
/**
* Tests theme-provided templates that are registered by modules.
*/
public function testThemeTemplatesRegisteredByModules() {
$theme_handler = \Drupal::service('theme_handler');
$theme_handler->install(['test_theme']);
$registry_theme = new Registry(\Drupal::root(), \Drupal::cache(), \Drupal::lock(), \Drupal::moduleHandler(), $theme_handler, \Drupal::service('theme.initialization'), 'test_theme');
$registry_theme->setThemeManager(\Drupal::theme());
$expected = [
'template_preprocess',
'template_preprocess_container',
'template_preprocess_theme_test_registered_by_module'
];
$registry = $registry_theme->get();
$this->assertEquals($expected, array_values($registry['theme_test_registered_by_module']['preprocess functions']));
}
} }