diff --git a/core/lib/Drupal/Core/Render/ElementInfoManager.php b/core/lib/Drupal/Core/Render/ElementInfoManager.php index 015e3900bd3..da4ed76f18c 100644 --- a/core/lib/Drupal/Core/Render/ElementInfoManager.php +++ b/core/lib/Drupal/Core/Render/ElementInfoManager.php @@ -65,6 +65,7 @@ class ElementInfoManager extends DefaultPluginManager implements ElementInfoMana $this->cacheTagInvalidator = $cache_tag_invalidator; parent::__construct('Element', $namespaces, $module_handler, 'Drupal\Core\Render\Element\ElementInterface', 'Drupal\Core\Render\Annotation\RenderElement'); + $this->alterInfo('element_plugin'); } /** diff --git a/core/lib/Drupal/Core/Render/theme.api.php b/core/lib/Drupal/Core/Render/theme.api.php index 32ff6774af0..af1392a12d7 100644 --- a/core/lib/Drupal/Core/Render/theme.api.php +++ b/core/lib/Drupal/Core/Render/theme.api.php @@ -810,6 +810,24 @@ function hook_element_info_alter(array &$info) { } } +/** + * Alter Element plugin definitions. + * + * Whenever possible, hook_element_info_alter() should be used to alter the + * default properties of an element type. Use this hook only when the plugin + * definition itself needs to be altered. + * + * @param array $definitions + * An array of Element plugin definitions. + * + * @see \Drupal\Core\Render\ElementInfoManager + * @see \Drupal\Core\Render\Element\ElementInterface + */ +function hook_element_plugin_alter(array &$definitions) { + // Use a custom class for the LayoutBuilder element. + $definitions['layout_builder']['class'] = '\Drupal\mymodule\Element\MyLayoutBuilderElement'; +} + /** * Perform necessary alterations to the JavaScript before it is presented on * the page. diff --git a/core/modules/system/tests/modules/element_info_test/element_info_test.module b/core/modules/system/tests/modules/element_info_test/element_info_test.module index 58ebc889e2a..74e47241376 100644 --- a/core/modules/system/tests/modules/element_info_test/element_info_test.module +++ b/core/modules/system/tests/modules/element_info_test/element_info_test.module @@ -14,6 +14,15 @@ function element_info_test_element_info_alter(array &$info) { $info['number']['#pre_render'][] = 'element_info_test_element_pre_render'; } +/** + * Implements hook_element_plugin_alter(). + */ +function element_info_test_element_plugin_alter(array &$definitions) { + if (\Drupal::state()->get('hook_element_plugin_alter:remove_weight', FALSE)) { + unset($definitions['weight']); + } +} + /** * {@inheritdoc} * diff --git a/core/tests/Drupal/KernelTests/Core/Render/Element/PluginAlterTest.php b/core/tests/Drupal/KernelTests/Core/Render/Element/PluginAlterTest.php new file mode 100644 index 00000000000..c121e4fb7c5 --- /dev/null +++ b/core/tests/Drupal/KernelTests/Core/Render/Element/PluginAlterTest.php @@ -0,0 +1,34 @@ +container->get('plugin.manager.element_info'); + $this->assertArrayHasKey('weight', $info_manager->getDefinitions()); + + // @see element_info_test_element_plugin_alter() + $this->container->get('state')->set('hook_element_plugin_alter:remove_weight', TRUE); + // The definition will be cached. + $this->assertArrayHasKey('weight', $info_manager->getDefinitions()); + + // Clearing the caches removes the definition. + $info_manager->clearCachedDefinitions(); + $this->assertArrayNotHasKey('weight', $info_manager->getDefinitions()); + } + +}