Issue #3420983 by sorlov, godotislate, alexpott, quietone, kim.pepper, larowlan, mstrelan: Convert Layout plugin discovery to attributes
parent
74a6dce280
commit
091483c1f1
|
@ -0,0 +1,111 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Core\Layout\Attribute;
|
||||
|
||||
use Drupal\Component\Plugin\Attribute\Plugin;
|
||||
use Drupal\Core\StringTranslation\TranslatableMarkup;
|
||||
use Drupal\Core\Layout\LayoutDefault;
|
||||
use Drupal\Core\Layout\LayoutDefinition;
|
||||
|
||||
/**
|
||||
* Defines a Layout attribute object.
|
||||
*
|
||||
* Layouts are used to define a list of regions and then output render arrays
|
||||
* in each of the regions, usually using a template.
|
||||
*
|
||||
* Plugin Namespace: Plugin\Layout
|
||||
*
|
||||
* @see \Drupal\Core\Layout\LayoutInterface
|
||||
* @see \Drupal\Core\Layout\LayoutDefault
|
||||
* @see \Drupal\Core\Layout\LayoutPluginManager
|
||||
* @see plugin_api
|
||||
*/
|
||||
#[\Attribute(\Attribute::TARGET_CLASS)]
|
||||
class Layout extends Plugin {
|
||||
|
||||
/**
|
||||
* Any additional properties and values.
|
||||
*
|
||||
* @see \Drupal\Core\Layout\LayoutDefinition::$additional
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public readonly array $additional;
|
||||
|
||||
/**
|
||||
* Constructs a Layout attribute.
|
||||
*
|
||||
* @param string $id
|
||||
* The plugin ID.
|
||||
* @param \Drupal\Core\StringTranslation\TranslatableMarkup|null $label
|
||||
* (optional) The human-readable name. @todo Deprecate optional label in
|
||||
* https://www.drupal.org/project/drupal/issues/3392572.
|
||||
* @param \Drupal\Core\StringTranslation\TranslatableMarkup|null $category
|
||||
* (optional) The human-readable category. @todo Deprecate optional category
|
||||
* in https://www.drupal.org/project/drupal/issues/3392572.
|
||||
* @param \Drupal\Core\StringTranslation\TranslatableMarkup|null $description
|
||||
* (optional) The description for advanced layouts.
|
||||
* @param string|null $template
|
||||
* (optional) The template file to render the layout.
|
||||
* @param string $theme_hook
|
||||
* (optional) The template hook to render the layout.
|
||||
* @param string|null $path
|
||||
* (optional) Path (relative to the module or theme) to resources like icon or template.
|
||||
* @param string|null $library
|
||||
* (optional) The asset library.
|
||||
* @param string|null $icon
|
||||
* (optional) The path to the preview image (relative to the 'path' given).
|
||||
* @param string[][]|null $icon_map
|
||||
* (optional) The icon map.
|
||||
* @param array $regions
|
||||
* (optional) An associative array of regions in this layout.
|
||||
* @param string|null $default_region
|
||||
* (optional) The default region.
|
||||
* @param class-string $class
|
||||
* (optional) The layout plugin class.
|
||||
* @param \Drupal\Core\Plugin\Context\ContextDefinitionInterface[] $context_definitions
|
||||
* (optional) The context definition.
|
||||
* @param array $config_dependencies
|
||||
* (optional) The config dependencies.
|
||||
* @param class-string|null $deriver
|
||||
* (optional) The deriver class.
|
||||
* @param mixed $additional
|
||||
* (optional) Additional properties passed in that can be used by a deriver.
|
||||
*/
|
||||
public function __construct(
|
||||
public readonly string $id,
|
||||
public readonly ?TranslatableMarkup $label = NULL,
|
||||
public readonly ?TranslatableMarkup $category = NULL,
|
||||
public readonly ?TranslatableMarkup $description = NULL,
|
||||
public readonly ?string $template = NULL,
|
||||
public readonly string $theme_hook = 'layout',
|
||||
public readonly ?string $path = NULL,
|
||||
public readonly ?string $library = NULL,
|
||||
public readonly ?string $icon = NULL,
|
||||
public readonly ?array $icon_map = NULL,
|
||||
public readonly array $regions = [],
|
||||
public readonly ?string $default_region = NULL,
|
||||
public string $class = LayoutDefault::class,
|
||||
public readonly array $context_definitions = [],
|
||||
public readonly array $config_dependencies = [],
|
||||
public readonly ?string $deriver = NULL,
|
||||
...$additional,
|
||||
) {
|
||||
// Layout definitions support arbitrary properties being passed in, which
|
||||
// are stored in the 'additional' property in LayoutDefinition. The variadic
|
||||
// 'additional' parameter here saves arbitrary parameters passed into the
|
||||
// 'additional' property in this attribute class. The 'additional' property
|
||||
// gets passed to the LayoutDefinition constructor in ::get().
|
||||
// @see \Drupal\Core\Layout\LayoutDefinition::$additional
|
||||
// @see \Drupal\Core\Layout\LayoutDefinition::get()
|
||||
$this->additional = $additional;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get(): LayoutDefinition {
|
||||
return new LayoutDefinition(parent::get());
|
||||
}
|
||||
|
||||
}
|
|
@ -132,7 +132,7 @@ class LayoutDefinition extends PluginDefinition implements PluginDefinitionInter
|
|||
* LayoutDefinition constructor.
|
||||
*
|
||||
* @param array $definition
|
||||
* An array of values from the annotation.
|
||||
* An array of values from the attribute.
|
||||
*/
|
||||
public function __construct(array $definition) {
|
||||
// If there are context definitions in the plugin definition, they should
|
||||
|
|
|
@ -2,16 +2,16 @@
|
|||
|
||||
namespace Drupal\Core\Layout;
|
||||
|
||||
use Drupal\Component\Annotation\Plugin\Discovery\AnnotationBridgeDecorator;
|
||||
use Drupal\Component\Plugin\Discovery\AttributeBridgeDecorator;
|
||||
use Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException;
|
||||
use Drupal\Core\Cache\CacheBackendInterface;
|
||||
use Drupal\Core\Extension\ModuleHandlerInterface;
|
||||
use Drupal\Core\Extension\ThemeHandlerInterface;
|
||||
use Drupal\Core\Plugin\DefaultPluginManager;
|
||||
use Drupal\Core\Plugin\Discovery\AnnotatedClassDiscovery;
|
||||
use Drupal\Core\Plugin\Discovery\AttributeDiscoveryWithAnnotations;
|
||||
use Drupal\Core\Plugin\Discovery\ContainerDerivativeDiscoveryDecorator;
|
||||
use Drupal\Core\Plugin\Discovery\YamlDiscoveryDecorator;
|
||||
use Drupal\Core\Layout\Annotation\Layout;
|
||||
use Drupal\Core\Layout\Attribute\Layout;
|
||||
use Drupal\Core\Plugin\FilteredPluginManagerTrait;
|
||||
use Drupal\Core\StringTranslation\TranslatableMarkup;
|
||||
|
||||
|
@ -43,7 +43,7 @@ class LayoutPluginManager extends DefaultPluginManager implements LayoutPluginMa
|
|||
* The theme handler to invoke the alter hook with.
|
||||
*/
|
||||
public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler, ThemeHandlerInterface $theme_handler) {
|
||||
parent::__construct('Plugin/Layout', $namespaces, $module_handler, LayoutInterface::class, Layout::class);
|
||||
parent::__construct('Plugin/Layout', $namespaces, $module_handler, LayoutInterface::class, Layout::class, 'Drupal\Core\Layout\Annotation\Layout');
|
||||
$this->themeHandler = $theme_handler;
|
||||
|
||||
$type = $this->getType();
|
||||
|
@ -70,13 +70,13 @@ class LayoutPluginManager extends DefaultPluginManager implements LayoutPluginMa
|
|||
*/
|
||||
protected function getDiscovery() {
|
||||
if (!$this->discovery) {
|
||||
$discovery = new AnnotatedClassDiscovery($this->subdir, $this->namespaces, $this->pluginDefinitionAnnotationName, $this->additionalAnnotationNamespaces);
|
||||
$discovery = new AttributeDiscoveryWithAnnotations($this->subdir, $this->namespaces, $this->pluginDefinitionAttributeName, $this->pluginDefinitionAnnotationName, $this->additionalAnnotationNamespaces);
|
||||
$discovery = new YamlDiscoveryDecorator($discovery, 'layouts', $this->moduleHandler->getModuleDirectories() + $this->themeHandler->getThemeDirectories());
|
||||
$discovery
|
||||
->addTranslatableProperty('label')
|
||||
->addTranslatableProperty('description')
|
||||
->addTranslatableProperty('category');
|
||||
$discovery = new AnnotationBridgeDecorator($discovery, $this->pluginDefinitionAnnotationName);
|
||||
$discovery = new AttributeBridgeDecorator($discovery, $this->pluginDefinitionAttributeName);
|
||||
$discovery = new ContainerDerivativeDiscoveryDecorator($discovery);
|
||||
$this->discovery = $discovery;
|
||||
}
|
||||
|
|
|
@ -2,26 +2,27 @@
|
|||
|
||||
namespace Drupal\field_layout_test\Plugin\Layout;
|
||||
|
||||
use Drupal\Core\Layout\Attribute\Layout;
|
||||
use Drupal\Core\Layout\LayoutDefault;
|
||||
use Drupal\Core\StringTranslation\TranslatableMarkup;
|
||||
|
||||
/**
|
||||
* Provides an annotated layout plugin for field_layout tests.
|
||||
*
|
||||
* @Layout(
|
||||
* id = "test_layout_content_and_footer",
|
||||
* label = @Translation("Test plugin: Content and Footer"),
|
||||
* category = @Translation("Layout test"),
|
||||
* description = @Translation("Test layout"),
|
||||
* regions = {
|
||||
* "content" = {
|
||||
* "label" = @Translation("Content Region")
|
||||
* },
|
||||
* "footer" = {
|
||||
* "label" = @Translation("Footer Region")
|
||||
* }
|
||||
* },
|
||||
* )
|
||||
* Provides a Layout plugin for field_layout tests.
|
||||
*/
|
||||
#[Layout(
|
||||
id: 'test_layout_content_and_footer',
|
||||
label: new TranslatableMarkup('Test plugin: Content and Footer'),
|
||||
category: new TranslatableMarkup('Layout test'),
|
||||
description: new TranslatableMarkup('Test layout'),
|
||||
regions: [
|
||||
"content" => [
|
||||
"label" => new TranslatableMarkup("Content Region"),
|
||||
],
|
||||
"footer" => [
|
||||
"label" => new TranslatableMarkup("Footer Region"),
|
||||
],
|
||||
],
|
||||
)]
|
||||
class TestLayoutContentFooter extends LayoutDefault {
|
||||
|
||||
}
|
||||
|
|
|
@ -2,31 +2,32 @@
|
|||
|
||||
namespace Drupal\field_layout_test\Plugin\Layout;
|
||||
|
||||
use Drupal\Core\Layout\Attribute\Layout;
|
||||
use Drupal\Core\Layout\LayoutDefault;
|
||||
use Drupal\Core\StringTranslation\TranslatableMarkup;
|
||||
|
||||
/**
|
||||
* Provides an annotated layout plugin for field_layout tests.
|
||||
*
|
||||
* @Layout(
|
||||
* id = "test_layout_main_and_footer",
|
||||
* label = @Translation("Test plugin: Main and Footer"),
|
||||
* category = @Translation("Layout test"),
|
||||
* description = @Translation("Test layout"),
|
||||
* regions = {
|
||||
* "main" = {
|
||||
* "label" = @Translation("Main Region")
|
||||
* },
|
||||
* "footer" = {
|
||||
* "label" = @Translation("Footer Region")
|
||||
* }
|
||||
* },
|
||||
* config_dependencies = {
|
||||
* "module" = {
|
||||
* "layout_discovery",
|
||||
* },
|
||||
* },
|
||||
* )
|
||||
* Provides an attributed layout plugin for field_layout tests.
|
||||
*/
|
||||
#[Layout(
|
||||
id: 'test_layout_main_and_footer',
|
||||
label: new TranslatableMarkup('Test plugin: Main and Footer'),
|
||||
category: new TranslatableMarkup('Layout test'),
|
||||
description: new TranslatableMarkup('Test layout'),
|
||||
regions: [
|
||||
"main" => [
|
||||
"label" => new TranslatableMarkup("Main Region"),
|
||||
],
|
||||
"footer" => [
|
||||
"label" => new TranslatableMarkup("Footer Region"),
|
||||
],
|
||||
],
|
||||
config_dependencies: [
|
||||
"module" => [
|
||||
"layout_discovery",
|
||||
],
|
||||
],
|
||||
)]
|
||||
class TestLayoutMainFooter extends LayoutDefault {
|
||||
|
||||
/**
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
*
|
||||
* By default, the Layout Builder access check requires the 'configure any
|
||||
* layout' permission. Individual section storage plugins may override this by
|
||||
* setting the 'handles_permission_check' annotation key to TRUE. Any section
|
||||
* setting the 'handles_permission_check' attribute key to TRUE. Any section
|
||||
* storage plugin that uses 'handles_permission_check' must provide its own
|
||||
* complete routing access checking to avoid any access bypasses.
|
||||
*
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
|
||||
namespace Drupal\layout_builder\Plugin\Layout;
|
||||
|
||||
use Drupal\Core\Layout\Attribute\Layout;
|
||||
use Drupal\Core\Layout\LayoutDefault;
|
||||
use Drupal\Core\StringTranslation\TranslatableMarkup;
|
||||
|
||||
/**
|
||||
* Provides a layout plugin that produces no output.
|
||||
|
@ -13,11 +15,11 @@ use Drupal\Core\Layout\LayoutDefault;
|
|||
*
|
||||
* @internal
|
||||
* This layout plugin is intended for internal use by Layout Builder only.
|
||||
*
|
||||
* @Layout(
|
||||
* id = "layout_builder_blank",
|
||||
* )
|
||||
*/
|
||||
#[Layout(
|
||||
id: 'layout_builder_blank',
|
||||
label: new TranslatableMarkup('Blank'),
|
||||
)]
|
||||
class BlankLayout extends LayoutDefault {
|
||||
|
||||
/**
|
||||
|
|
|
@ -2,19 +2,22 @@
|
|||
|
||||
namespace Drupal\layout_builder_test\Plugin\Layout;
|
||||
|
||||
use Drupal\Core\Layout\Attribute\Layout;
|
||||
use Drupal\Core\Layout\LayoutDefault;
|
||||
use Drupal\Core\StringTranslation\TranslatableMarkup;
|
||||
|
||||
/**
|
||||
* @Layout(
|
||||
* id = "layout_builder_test_plugin",
|
||||
* label = @Translation("Layout Builder Test Plugin"),
|
||||
* regions = {
|
||||
* "main" = {
|
||||
* "label" = @Translation("Main Region")
|
||||
* }
|
||||
* },
|
||||
* )
|
||||
* The Layout Builder Test Plugin.
|
||||
*/
|
||||
#[Layout(
|
||||
id: 'layout_builder_test_plugin',
|
||||
label: new TranslatableMarkup('Layout Builder Test Plugin'),
|
||||
regions: [
|
||||
"main" => [
|
||||
"label" => new TranslatableMarkup("Main Region"),
|
||||
],
|
||||
],
|
||||
)]
|
||||
class LayoutBuilderTestPlugin extends LayoutDefault {
|
||||
|
||||
/**
|
||||
|
|
|
@ -3,21 +3,22 @@
|
|||
namespace Drupal\layout_builder_test\Plugin\Layout;
|
||||
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Layout\Attribute\Layout;
|
||||
use Drupal\Core\Layout\LayoutDefault;
|
||||
use Drupal\Core\StringTranslation\TranslatableMarkup;
|
||||
|
||||
/**
|
||||
* Layout plugin without a label configuration.
|
||||
*
|
||||
* @Layout(
|
||||
* id = "layout_without_label",
|
||||
* label = @Translation("Layout Without Label"),
|
||||
* regions = {
|
||||
* "main" = {
|
||||
* "label" = @Translation("Main Region")
|
||||
* }
|
||||
* },
|
||||
* )
|
||||
*/
|
||||
#[Layout(
|
||||
id: 'layout_without_label',
|
||||
label: new TranslatableMarkup('Layout Without Label'),
|
||||
regions: [
|
||||
"main" => [
|
||||
"label" => new TranslatableMarkup("Main Region"),
|
||||
],
|
||||
],
|
||||
)]
|
||||
class LayoutWithoutLabel extends LayoutDefault {
|
||||
|
||||
/**
|
||||
|
|
|
@ -2,22 +2,26 @@
|
|||
|
||||
namespace Drupal\layout_builder_test\Plugin\Layout;
|
||||
|
||||
use Drupal\Core\Layout\Attribute\Layout;
|
||||
use Drupal\Core\Layout\LayoutDefault;
|
||||
use Drupal\Core\Plugin\Context\EntityContextDefinition;
|
||||
use Drupal\Core\StringTranslation\TranslatableMarkup;
|
||||
|
||||
/**
|
||||
* @Layout(
|
||||
* id = "layout_builder_test_context_aware",
|
||||
* label = @Translation("Layout Builder Test: Context Aware"),
|
||||
* regions = {
|
||||
* "main" = {
|
||||
* "label" = @Translation("Main Region")
|
||||
* }
|
||||
* },
|
||||
* context_definitions = {
|
||||
* "user" = @ContextDefinition("entity:user")
|
||||
* }
|
||||
* )
|
||||
* The TestContextAwareLayout Class.
|
||||
*/
|
||||
#[Layout(
|
||||
id: 'layout_builder_test_context_aware',
|
||||
label: new TranslatableMarkup('Layout Builder Test: Context Aware'),
|
||||
regions: [
|
||||
"main" => [
|
||||
"label" => new TranslatableMarkup("Main Region"),
|
||||
],
|
||||
],
|
||||
context_definitions: [
|
||||
"user" => new EntityContextDefinition("entity:user"),
|
||||
],
|
||||
)]
|
||||
class TestContextAwareLayout extends LayoutDefault {
|
||||
|
||||
/**
|
||||
|
|
|
@ -3,23 +3,24 @@
|
|||
namespace Drupal\layout_test\Plugin\Layout;
|
||||
|
||||
use Drupal\Component\Plugin\DependentPluginInterface;
|
||||
use Drupal\Core\Layout\Attribute\Layout;
|
||||
use Drupal\Core\Layout\LayoutDefault;
|
||||
use Drupal\Core\StringTranslation\TranslatableMarkup;
|
||||
|
||||
/**
|
||||
* Provides a plugin that contains config dependencies.
|
||||
*
|
||||
* @Layout(
|
||||
* id = "layout_test_dependencies_plugin",
|
||||
* label = @Translation("Layout plugin (with dependencies)"),
|
||||
* category = @Translation("Layout test"),
|
||||
* description = @Translation("Test layout"),
|
||||
* regions = {
|
||||
* "main" = {
|
||||
* "label" = @Translation("Main Region")
|
||||
* }
|
||||
* }
|
||||
* )
|
||||
*/
|
||||
#[Layout(
|
||||
id: 'layout_test_dependencies_plugin',
|
||||
label: new TranslatableMarkup('Layout plugin (with dependencies)'),
|
||||
category: new TranslatableMarkup('Layout test'),
|
||||
description: new TranslatableMarkup('Test layout'),
|
||||
regions: [
|
||||
"main" => [
|
||||
"label" => new TranslatableMarkup("Main Region"),
|
||||
],
|
||||
],
|
||||
)]
|
||||
class LayoutTestDependenciesPlugin extends LayoutDefault implements DependentPluginInterface {
|
||||
|
||||
/**
|
||||
|
|
|
@ -3,25 +3,26 @@
|
|||
namespace Drupal\layout_test\Plugin\Layout;
|
||||
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Layout\Attribute\Layout;
|
||||
use Drupal\Core\Layout\LayoutDefault;
|
||||
use Drupal\Core\Plugin\PluginFormInterface;
|
||||
use Drupal\Core\StringTranslation\TranslatableMarkup;
|
||||
|
||||
/**
|
||||
* The plugin that handles the default layout template.
|
||||
*
|
||||
* @Layout(
|
||||
* id = "layout_test_plugin",
|
||||
* label = @Translation("Layout plugin (with settings)"),
|
||||
* category = @Translation("Layout test"),
|
||||
* description = @Translation("Test layout"),
|
||||
* template = "templates/layout-test-plugin",
|
||||
* regions = {
|
||||
* "main" = {
|
||||
* "label" = @Translation("Main Region")
|
||||
* }
|
||||
* }
|
||||
* )
|
||||
*/
|
||||
#[Layout(
|
||||
id: 'layout_test_plugin',
|
||||
label: new TranslatableMarkup('Layout plugin (with settings)'),
|
||||
category: new TranslatableMarkup('Layout test'),
|
||||
description: new TranslatableMarkup('Test layout'),
|
||||
template: "templates/layout-test-plugin",
|
||||
regions: [
|
||||
"main" => [
|
||||
"label" => new TranslatableMarkup("Main Region"),
|
||||
],
|
||||
],
|
||||
)]
|
||||
class LayoutTestPlugin extends LayoutDefault implements PluginFormInterface {
|
||||
|
||||
/**
|
||||
|
|
|
@ -4,6 +4,7 @@ declare(strict_types=1);
|
|||
|
||||
namespace Drupal\Tests\Core\Layout;
|
||||
|
||||
use Composer\Autoload\ClassLoader;
|
||||
use Drupal\Component\Plugin\Derivative\DeriverBase;
|
||||
use Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException;
|
||||
use Drupal\Core\Cache\CacheBackendInterface;
|
||||
|
@ -20,6 +21,8 @@ use Drupal\Tests\UnitTestCase;
|
|||
use org\bovigo\vfs\vfsStream;
|
||||
use Prophecy\Argument;
|
||||
|
||||
// cspell:ignore lorem, ipsum, consectetur, adipiscing
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\Core\Layout\LayoutPluginManager
|
||||
* @group Layout
|
||||
|
@ -91,6 +94,9 @@ class LayoutPluginManagerTest extends UnitTestCase {
|
|||
$this->cacheBackend = $this->prophesize(CacheBackendInterface::class);
|
||||
|
||||
$namespaces = new \ArrayObject(['Drupal\Core' => vfsStream::url('root/core/lib/Drupal/Core')]);
|
||||
$class_loader = new ClassLoader();
|
||||
$class_loader->addPsr4("Drupal\\Core\\", vfsStream::url("root/core/lib/Drupal/Core"));
|
||||
$class_loader->register(TRUE);
|
||||
$this->layoutPluginManager = new LayoutPluginManager($namespaces, $this->cacheBackend->reveal(), $this->moduleHandler->reveal(), $this->themeHandler->reveal());
|
||||
}
|
||||
|
||||
|
@ -103,6 +109,7 @@ class LayoutPluginManagerTest extends UnitTestCase {
|
|||
'module_a_provided_layout',
|
||||
'theme_a_provided_layout',
|
||||
'plugin_provided_layout',
|
||||
'plugin_provided_by_annotation_layout',
|
||||
];
|
||||
|
||||
$layout_definitions = $this->layoutPluginManager->getDefinitions();
|
||||
|
@ -172,6 +179,8 @@ class LayoutPluginManagerTest extends UnitTestCase {
|
|||
$this->assertEquals($expected_regions, $regions);
|
||||
$this->assertInstanceOf(TranslatableMarkup::class, $regions['top']['label']);
|
||||
$this->assertInstanceOf(TranslatableMarkup::class, $regions['bottom']['label']);
|
||||
// Check that arbitrary property value gets set correctly.
|
||||
$this->assertSame('ipsum', $layout_definition->get('lorem'));
|
||||
|
||||
$core_path = '/core/lib/Drupal/Core';
|
||||
$layout_definition = $this->layoutPluginManager->getDefinition('plugin_provided_layout');
|
||||
|
@ -198,6 +207,37 @@ class LayoutPluginManagerTest extends UnitTestCase {
|
|||
$regions = $layout_definition->getRegions();
|
||||
$this->assertEquals($expected_regions, $regions);
|
||||
$this->assertInstanceOf(TranslatableMarkup::class, $regions['main']['label']);
|
||||
// Check that arbitrary property value gets set correctly.
|
||||
$this->assertSame('adipiscing', $layout_definition->get('consectetur'));
|
||||
|
||||
$layout_definition = $this->layoutPluginManager->getDefinition('plugin_provided_by_annotation_layout');
|
||||
$this->assertSame('plugin_provided_by_annotation_layout', $layout_definition->id());
|
||||
$this->assertEquals('Layout by annotation plugin', $layout_definition->getLabel());
|
||||
$this->assertEquals('Columns: 2', $layout_definition->getCategory());
|
||||
$this->assertEquals('Test layout provided by annotated plugin', $layout_definition->getDescription());
|
||||
$this->assertInstanceOf(TranslatableMarkup::class, $layout_definition->getLabel());
|
||||
$this->assertInstanceOf(TranslatableMarkup::class, $layout_definition->getCategory());
|
||||
$this->assertInstanceOf(TranslatableMarkup::class, $layout_definition->getDescription());
|
||||
$this->assertSame('plugin-provided-annotation-layout', $layout_definition->getTemplate());
|
||||
$this->assertSame($core_path, $layout_definition->getPath());
|
||||
$this->assertNull($layout_definition->getLibrary());
|
||||
$this->assertSame('plugin_provided_annotation_layout', $layout_definition->getThemeHook());
|
||||
$this->assertSame("$core_path/templates", $layout_definition->getTemplatePath());
|
||||
$this->assertSame('core', $layout_definition->getProvider());
|
||||
$this->assertSame('left', $layout_definition->getDefaultRegion());
|
||||
$this->assertSame('Drupal\Core\Plugin\Layout\TestAnnotationLayout', $layout_definition->getClass());
|
||||
$expected_regions = [
|
||||
'left' => [
|
||||
'label' => new TranslatableMarkup('Left Region', [], ['context' => 'layout_region']),
|
||||
],
|
||||
'right' => [
|
||||
'label' => new TranslatableMarkup('Right Region', [], ['context' => 'layout_region']),
|
||||
],
|
||||
];
|
||||
$regions = $layout_definition->getRegions();
|
||||
$this->assertEquals($expected_regions, $regions);
|
||||
$this->assertInstanceOf(TranslatableMarkup::class, $regions['left']['label']);
|
||||
$this->assertInstanceOf(TranslatableMarkup::class, $regions['right']['label']);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -243,6 +283,12 @@ EOS;
|
|||
'template' => 'plugin-provided-layout',
|
||||
'path' => "$core_path/templates",
|
||||
],
|
||||
'plugin_provided_annotation_layout' => [
|
||||
'render element' => 'content',
|
||||
'base hook' => 'layout',
|
||||
'template' => 'plugin-provided-annotation-layout',
|
||||
'path' => "$core_path/templates",
|
||||
],
|
||||
];
|
||||
$theme_implementations = $this->layoutPluginManager->getThemeImplementations();
|
||||
$this->assertEquals($expected, $theme_implementations);
|
||||
|
@ -264,10 +310,12 @@ EOS;
|
|||
* @covers ::getSortedDefinitions
|
||||
*/
|
||||
public function testGetSortedDefinitions() {
|
||||
// Sorted by category first, then label.
|
||||
$expected = [
|
||||
'module_a_provided_layout',
|
||||
'plugin_provided_layout',
|
||||
'theme_a_provided_layout',
|
||||
'plugin_provided_by_annotation_layout',
|
||||
];
|
||||
|
||||
$layout_definitions = $this->layoutPluginManager->getSortedDefinitions();
|
||||
|
@ -286,6 +334,7 @@ EOS;
|
|||
],
|
||||
'Columns: 2' => [
|
||||
'theme_a_provided_layout',
|
||||
'plugin_provided_by_annotation_layout',
|
||||
],
|
||||
];
|
||||
|
||||
|
@ -315,7 +364,9 @@ module_a_provided_layout:
|
|||
label: Top region
|
||||
bottom:
|
||||
label: Bottom region
|
||||
lorem: ipsum
|
||||
module_a_derived_layout:
|
||||
label: 'Invalid provider derived layout'
|
||||
deriver: \Drupal\Tests\Core\Layout\LayoutDeriver
|
||||
invalid_provider: true
|
||||
EOS;
|
||||
|
@ -338,23 +389,52 @@ EOS;
|
|||
$plugin_provided_layout = <<<'EOS'
|
||||
<?php
|
||||
namespace Drupal\Core\Plugin\Layout;
|
||||
use Drupal\Core\Layout\Attribute\Layout;
|
||||
use Drupal\Core\Layout\LayoutDefault;
|
||||
use Drupal\Core\StringTranslation\TranslatableMarkup;
|
||||
/**
|
||||
* The TestLayout Class.
|
||||
*/
|
||||
#[Layout(
|
||||
id: 'plugin_provided_layout',
|
||||
label: new TranslatableMarkup('Layout plugin'),
|
||||
category: new TranslatableMarkup('Columns: 1'),
|
||||
description: new TranslatableMarkup('Test layout'),
|
||||
path: "core/lib/Drupal/Core",
|
||||
template: "templates/plugin-provided-layout",
|
||||
regions: [
|
||||
"main" => [
|
||||
"label" => new TranslatableMarkup("Main Region", [], ["context" => "layout_region"]),
|
||||
],
|
||||
],
|
||||
consectetur: 'adipiscing',
|
||||
)]
|
||||
class TestLayout extends LayoutDefault {}
|
||||
EOS;
|
||||
$plugin_provided_by_annotation_layout = <<<'EOS'
|
||||
<?php
|
||||
namespace Drupal\Core\Plugin\Layout;
|
||||
use Drupal\Core\Layout\LayoutDefault;
|
||||
/**
|
||||
* @Layout(
|
||||
* id = "plugin_provided_layout",
|
||||
* label = @Translation("Layout plugin"),
|
||||
* category = @Translation("Columns: 1"),
|
||||
* description = @Translation("Test layout"),
|
||||
* id = "plugin_provided_by_annotation_layout",
|
||||
* label = @Translation("Layout by annotation plugin"),
|
||||
* category = @Translation("Columns: 2"),
|
||||
* description = @Translation("Test layout provided by annotated plugin"),
|
||||
* path = "core/lib/Drupal/Core",
|
||||
* template = "templates/plugin-provided-layout",
|
||||
* template = "templates/plugin-provided-annotation-layout",
|
||||
* default_region = "left",
|
||||
* regions = {
|
||||
* "main" = {
|
||||
* "label" = @Translation("Main Region", context = "layout_region")
|
||||
* "left" = {
|
||||
* "label" = @Translation("Left Region", context = "layout_region")
|
||||
* },
|
||||
* "right" = {
|
||||
* "label" = @Translation("Right Region", context = "layout_region")
|
||||
* }
|
||||
* }
|
||||
* )
|
||||
*/
|
||||
class TestLayout extends LayoutDefault {}
|
||||
class TestAnnotationLayout extends LayoutDefault {}
|
||||
EOS;
|
||||
vfsStream::setup('root');
|
||||
vfsStream::create([
|
||||
|
@ -379,6 +459,7 @@ EOS;
|
|||
'Plugin' => [
|
||||
'Layout' => [
|
||||
'TestLayout.php' => $plugin_provided_layout,
|
||||
'TestAnnotationLayout.php' => $plugin_provided_by_annotation_layout,
|
||||
],
|
||||
],
|
||||
],
|
||||
|
|
Loading…
Reference in New Issue