diff --git a/core/composer.json b/core/composer.json index 53ab8fa..8b6f62f 100644 --- a/core/composer.json +++ b/core/composer.json @@ -104,6 +104,7 @@ "drupal/image": "self.version", "drupal/inline_form_errors": "self.version", "drupal/language": "self.version", + "drupal/layout_plugin": "self.version", "drupal/link": "self.version", "drupal/locale": "self.version", "drupal/minimal": "self.version", diff --git a/core/core.services.yml b/core/core.services.yml index 53c545c..d1223e9 100644 --- a/core/core.services.yml +++ b/core/core.services.yml @@ -586,9 +586,6 @@ services: plugin.manager.block: class: Drupal\Core\Block\BlockManager parent: default_plugin_manager - plugin.manager.layout: - class: Drupal\Core\Layout\Plugin\LayoutPluginManager - arguments: ['@container.namespaces', '@cache.discovery', '@module_handler', '@theme_handler'] plugin.manager.field.field_type: class: Drupal\Core\Field\FieldTypePluginManager arguments: ['@container.namespaces', '@cache.discovery', '@module_handler', '@typed_data_manager'] diff --git a/core/config/schema/core.layout.schema.yml b/core/modules/layout_plugin/config/schema/layout_plugin.schema.yml similarity index 83% rename from core/config/schema/core.layout.schema.yml rename to core/modules/layout_plugin/config/schema/layout_plugin.schema.yml index 604c5b8..45fcee2 100644 --- a/core/config/schema/core.layout.schema.yml +++ b/core/modules/layout_plugin/config/schema/layout_plugin.schema.yml @@ -1,6 +1,5 @@ layout.settings: type: mapping - mapping: { } layout.settings.*: type: layout.settings diff --git a/core/modules/layout_plugin/layout_plugin.info.yml b/core/modules/layout_plugin/layout_plugin.info.yml new file mode 100644 index 0000000..7058dca --- /dev/null +++ b/core/modules/layout_plugin/layout_plugin.info.yml @@ -0,0 +1,6 @@ +name: 'Layout Plugin' +type: module +description: 'Provides a way for modules or themes to register layouts.' +package: Core (Experimental) +version: VERSION +core: 8.x diff --git a/core/modules/layout_plugin/layout_plugin.module b/core/modules/layout_plugin/layout_plugin.module new file mode 100644 index 0000000..dda97c2 --- /dev/null +++ b/core/modules/layout_plugin/layout_plugin.module @@ -0,0 +1,28 @@ +' . t('About') . ''; + $output .= '

' . t('Layout Plugin allows modules or themes to register layouts, and for other modules to list the available layouts and render them.') . '

'; + $output .= '

' . t('For more information, see the online documentation for the Layout Plugin module.', [':layout-plugin-documentation' => 'https://www.drupal.org/node/2619128']) . '

'; + return $output; + } +} + +/** + * Implements hook_theme(). + */ +function layout_plugin_theme($existing, $type, $theme, $path) { + return \Drupal::service('plugin.manager.layout_plugin')->getThemeImplementations(); +} diff --git a/core/modules/layout_plugin/layout_plugin.services.yml b/core/modules/layout_plugin/layout_plugin.services.yml new file mode 100644 index 0000000..74225de --- /dev/null +++ b/core/modules/layout_plugin/layout_plugin.services.yml @@ -0,0 +1,4 @@ +services: + plugin.manager.layout_plugin: + class: Drupal\layout_plugin\LayoutPluginManager + arguments: ['@container.namespaces', '@cache.discovery', '@module_handler', '@theme_handler'] diff --git a/core/lib/Drupal/Core/Layout/Annotation/Layout.php b/core/modules/layout_plugin/src/Annotation/Layout.php similarity index 60% rename from core/lib/Drupal/Core/Layout/Annotation/Layout.php rename to core/modules/layout_plugin/src/Annotation/Layout.php index 2493935..437877b 100644 --- a/core/lib/Drupal/Core/Layout/Annotation/Layout.php +++ b/core/modules/layout_plugin/src/Annotation/Layout.php @@ -1,6 +1,6 @@ LayoutDefault::class, + ]; + + /** + * LayoutPluginManager constructor. * * @param \Traversable $namespaces * An object that implements \Traversable which contains the root paths @@ -37,20 +50,9 @@ class LayoutPluginManager extends DefaultPluginManager implements LayoutPluginMa * The theme handle to invoke the alter hook with. */ public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler, ThemeHandlerInterface $theme_handler) { - $plugin_interface = 'Drupal\Core\Layout\Plugin\LayoutInterface'; - $plugin_definition_annotation_name = 'Drupal\Core\Layout\Annotation\Layout'; - parent::__construct("Plugin/Layout", $namespaces, $module_handler, $plugin_interface, $plugin_definition_annotation_name); - $discovery = $this->getDiscovery(); - $this->discovery = new YamlDiscoveryDecorator($discovery, 'layouts', $module_handler->getModuleDirectories() + $theme_handler->getThemeDirectories()); + parent::__construct('Plugin/Layout', $namespaces, $module_handler, LayoutInterface::class, Layout::class); $this->themeHandler = $theme_handler; - $this->defaults += array( - 'type' => 'page', - // Used for plugins defined in layouts.yml that do not specify a class - // themselves. - 'class' => 'Drupal\Core\Layout\Plugin\LayoutDefault', - ); - $this->setCacheBackend($cache_backend, 'layout'); $this->alterInfo('layout'); } @@ -65,6 +67,17 @@ protected function providerExists($provider) { /** * {@inheritdoc} */ + protected function getDiscovery() { + if (!$this->discovery) { + $discovery = parent::getDiscovery(); + $this->discovery = new YamlDiscoveryDecorator($discovery, 'layouts', $this->moduleHandler->getModuleDirectories() + $this->themeHandler->getThemeDirectories()); + } + return $this->discovery; + } + + /** + * {@inheritdoc} + */ public function processDefinition(&$definition, $plugin_id) { parent::processDefinition($definition, $plugin_id); @@ -82,24 +95,16 @@ public function processDefinition(&$definition, $plugin_id) { } $definition['path'] = !empty($definition['path']) ? $base_path . '/' . $definition['path'] : $base_path; - // Add a dependency on the provider of the library. - if (!empty($definition['library'])) { - list ($library_provider, ) = explode('/', $definition['library']); - if ($this->moduleHandler->moduleExists($library_provider)) { - $definition['dependencies'] = ['module' => [$library_provider]]; - } - elseif ($this->themeHandler->themeExists($library_provider)) { - $definition['dependencies'] = ['theme' => [$library_provider]]; - } + // Either a theme or a template must be defined. + if (empty($definition['template']) && empty($definition['theme'])) { + throw new InvalidPluginDefinitionException($plugin_id); } - // Add the path to the icon filename. - if (!empty($definition['icon'])) { - $definition['icon'] = $definition['path'] . '/' . $definition['icon']; + if (empty($definition['template'])) { + $definition['template'] = strtr($definition['theme'], '_', '-'); + $definition['template_path'] = $definition['path']; } - - // If 'template' is set, then we'll derive 'template_path' and 'theme'. - if (!empty($definition['template'])) { + elseif (empty($definition['theme'])) { $template_parts = explode('/', $definition['template']); $definition['template'] = array_pop($template_parts); @@ -109,64 +114,21 @@ public function processDefinition(&$definition, $plugin_id) { $definition['template_path'] .= '/' . implode('/', $template_parts); } } - - // Generate the 'region_names' key from the 'regions' key. - $definition['region_names'] = array(); - if (!empty($definition['regions']) && is_array($definition['regions'])) { - foreach ($definition['regions'] as $region_id => $region_definition) { - $definition['region_names'][$region_id] = $region_definition['label']; - } - } - } - - /** - * {@inheritdoc} - */ - public function getLayoutOptions(array $params = []) { - $group_by_category = !empty($params['group_by_category']); - $plugins = $group_by_category ? $this->getGroupedDefinitions() : ['default' => $this->getDefinitions()]; - $categories = $group_by_category ? $this->getCategories() : ['default']; - - // Go through each category, sort it, and get just the labels out. - $options = array(); - foreach ($categories as $category) { - // Convert from a translation to a real string. - $category = (string) $category; - - // Sort the category. - $plugins[$category] = $this->getSortedDefinitions($plugins[$category]); - - // Put only the label in the options array. - foreach ($plugins[$category] as $id => $plugin) { - $options[$category][$id] = $plugin['label']; - } - } - - return $group_by_category ? $options : $options['default']; } /** * {@inheritdoc} */ public function getThemeImplementations() { - $plugins = $this->getDefinitions(); - - $theme_registry = []; - foreach ($plugins as $id => $definition) { - if (!empty($definition['template']) && !empty($definition['theme'])) { - $theme_registry[$definition['theme']] = [ - 'template' => $definition['template'], - 'path' => $definition['template_path'], - 'variables' => array( - 'content' => [], - 'settings' => [], - 'layout' => [], - ), - ]; - } + $hooks = []; + foreach ($this->getDefinitions() as $layout_definition) { + $hooks[$layout_definition['theme']] = [ + 'render element' => 'content', + 'template' => $layout_definition['template'], + 'path' => $layout_definition['template_path'], + ]; } - - return $theme_registry; + return $hooks; } } diff --git a/core/lib/Drupal/Core/Layout/Plugin/LayoutPluginManagerInterface.php b/core/modules/layout_plugin/src/LayoutPluginManagerInterface.php similarity index 32% rename from core/lib/Drupal/Core/Layout/Plugin/LayoutPluginManagerInterface.php rename to core/modules/layout_plugin/src/LayoutPluginManagerInterface.php index 7ee292a..11cb9bf 100644 --- a/core/lib/Drupal/Core/Layout/Plugin/LayoutPluginManagerInterface.php +++ b/core/modules/layout_plugin/src/LayoutPluginManagerInterface.php @@ -1,33 +1,16 @@ pluginDefinition['label']; - } - - /** - * Gets the optional description for advanced layouts. - * - * @return string|NULL - * The layout description. - */ - public function getDescription() { - return isset($this->pluginDefinition['description']) ? $this->pluginDefinition['description'] : NULL; - } - - /** - * Gets the human-readable category. - * - * @return string - * The human-readable category. - */ - public function getCategory() { - return $this->pluginDefinition['category']; - } - - /** - * Gets human-readable list of regions keyed by machine name. - * - * @return string[] - * An array of human-readable region names keyed by machine name. - */ - public function getRegionNames() { - return $this->pluginDefinition['region_names']; - } - - /** - * Gets information on regions keyed by machine name. - * - * @return array - * An array of information on regions keyed by machine name. - */ - public function getRegionDefinitions() { - return $this->pluginDefinition['regions']; - } - - /** - * Gets the path to resources like icon or template. - * - * @return string|NULL - * The path relative to the Drupal root. - */ - public function getBasePath() { - return isset($this->pluginDefinition['path']) ? $this->pluginDefinition['path'] : NULL; - } - - /** - * Gets the path to the preview image. - * - * This can optionally be used in the user interface to show the layout of - * regions visually. - * - * @return string|NULL - * The path to preview image file. - */ - public function getIconFilename() { - return isset($this->pluginDefinition['icon']) ? $this->pluginDefinition['icon'] : NULL; - } - - /** - * Get the asset library. - * - * @return string|NULL - * The asset library. - */ - public function getLibrary() { - return isset($this->pluginDefinition['library']) ? $this->pluginDefinition['library'] : NULL; - } - - /** - * Gets the theme hook used to render this layout. - * - * @return string|NULL - * Theme hook. + * {@inheritdoc} */ - public function getThemeHook() { - return isset($this->pluginDefinition['theme']) ? $this->pluginDefinition['theme'] : NULL; + public function __construct(array $configuration, $plugin_id, $plugin_definition) { + parent::__construct($configuration, $plugin_id, $plugin_definition); + $this->setConfiguration($configuration); } /** * {@inheritdoc} */ public function build(array $regions) { - $build['#content'] = $regions; - $build['#layout'] = $this->getPluginDefinition(); - $build['#settings'] = $this->getConfiguration(); - if ($theme = $this->getThemeHook()) { - $build['#theme'] = $theme; - } - if ($library = $this->getLibrary()) { - $build['#attached']['library'][] = $library; + $build = array_intersect_key($regions, $this->pluginDefinition['regions']); + $build['#theme'] = $this->pluginDefinition['theme']; + if (isset($this->pluginDefinition['library'])) { + $build['#attached']['library'][] = $this->pluginDefinition['library']; } return $build; } @@ -152,14 +57,14 @@ public function submitConfigurationForm(array &$form, FormStateInterface $form_s * {@inheritdoc} */ public function getConfiguration() { - return array_merge($this->defaultConfiguration(), $this->configuration); + return $this->configuration; } /** * {@inheritdoc} */ public function setConfiguration(array $configuration) { - $this->configuration = $configuration; + $this->configuration = NestedArray::mergeDeep($this->defaultConfiguration(), $configuration); } /** @@ -173,7 +78,7 @@ public function defaultConfiguration() { * {@inheritdoc} */ public function calculateDependencies() { - return isset($this->configuration['dependencies']) ? $this->configuration['dependencies'] : []; + return []; } } diff --git a/core/lib/Drupal/Core/Layout/Plugin/LayoutDefault.php b/core/modules/layout_plugin/src/Plugin/Layout/LayoutDefault.php similarity index 70% rename from core/lib/Drupal/Core/Layout/Plugin/LayoutDefault.php rename to core/modules/layout_plugin/src/Plugin/Layout/LayoutDefault.php index 355885b..462b68d 100644 --- a/core/lib/Drupal/Core/Layout/Plugin/LayoutDefault.php +++ b/core/modules/layout_plugin/src/Plugin/Layout/LayoutDefault.php @@ -1,6 +1,6 @@ 'Default', ]; } @@ -38,11 +36,10 @@ public function defaultConfiguration() { * {@inheritdoc} */ public function buildConfigurationForm(array $form, FormStateInterface $form_state) { - $configuration = $this->getConfiguration(); $form['setting_1'] = [ '#type' => 'textfield', '#title' => 'Blah', - '#default_value' => $configuration['setting_1'], + '#default_value' => $this->configuration['setting_1'], ]; return $form; } diff --git a/core/modules/system/tests/modules/layout_test/templates/layout-test-1col.html.twig b/core/modules/layout_plugin/tests/modules/layout_test/templates/layout-test-1col.html.twig similarity index 100% rename from core/modules/system/tests/modules/layout_test/templates/layout-test-1col.html.twig rename to core/modules/layout_plugin/tests/modules/layout_test/templates/layout-test-1col.html.twig diff --git a/core/modules/system/tests/modules/layout_test/templates/layout-test-2col.html.twig b/core/modules/layout_plugin/tests/modules/layout_test/templates/layout-test-2col.html.twig similarity index 100% rename from core/modules/system/tests/modules/layout_test/templates/layout-test-2col.html.twig rename to core/modules/layout_plugin/tests/modules/layout_test/templates/layout-test-2col.html.twig diff --git a/core/modules/system/tests/modules/layout_test/templates/layout-test-plugin.html.twig b/core/modules/layout_plugin/tests/modules/layout_test/templates/layout-test-plugin.html.twig similarity index 100% rename from core/modules/system/tests/modules/layout_test/templates/layout-test-plugin.html.twig rename to core/modules/layout_plugin/tests/modules/layout_test/templates/layout-test-plugin.html.twig diff --git a/core/tests/Drupal/KernelTests/Core/Layout/LayoutTest.php b/core/modules/layout_plugin/tests/src/Kernel/LayoutTest.php similarity index 66% rename from core/tests/Drupal/KernelTests/Core/Layout/LayoutTest.php rename to core/modules/layout_plugin/tests/src/Kernel/LayoutTest.php index fc8ab15..1559242 100644 --- a/core/tests/Drupal/KernelTests/Core/Layout/LayoutTest.php +++ b/core/modules/layout_plugin/tests/src/Kernel/LayoutTest.php @@ -1,25 +1,25 @@ layoutManager = $this->container->get('plugin.manager.layout'); + $this->layoutManager = $this->container->get('plugin.manager.layout_plugin'); } /** @@ -50,7 +50,7 @@ public function testLayoutDefinitions() { * @dataProvider renderLayoutData */ public function testRenderLayout($layout_id, $config, $regions, $html) { - /** @var \Drupal\Core\Layout\Plugin\LayoutInterface $layout */ + /** @var \Drupal\layout_plugin\Plugin\Layout\LayoutInterface $layout */ $layout = $this->layoutManager->createInstance($layout_id, $config); $built = $layout->build($regions); $this->render($built); @@ -61,44 +61,42 @@ public function testRenderLayout($layout_id, $config, $regions, $html) { * Data provider for testRenderLayout(). */ public function renderLayoutData() { - $data = [ - 'layout_test_1col' => [ - 'layout_test_1col', - [], - [ - 'top' => [ - '#markup' => 'This is the top', - ], - 'bottom' => [ - '#markup' => 'This is the bottom', - ], + $data['layout_test_1col'] = [ + 'layout_test_1col', + [], + [ + 'top' => [ + '#markup' => 'This is the top', + ], + 'bottom' => [ + '#markup' => 'This is the bottom', ], ], + ]; - 'layout_test_2col' => [ - 'layout_test_2col', - [], - [ - 'left' => [ - '#markup' => 'This is the left', - ], - 'right' => [ - '#markup' => 'This is the right', - ], + $data['layout_test_2col'] = [ + 'layout_test_2col', + [], + [ + 'left' => [ + '#markup' => 'This is the left', + ], + 'right' => [ + '#markup' => 'This is the right', ], ], + ]; - 'layout_test_plugin' => [ - 'layout_test_plugin', - [ - 'setting_1' => 'Config value' - ], - [ - 'main' => [ - '#markup' => 'Main region', - ], - ] + $data['layout_test_plugin'] = [ + 'layout_test_plugin', + [ + 'setting_1' => 'Config value' ], + [ + 'main' => [ + '#markup' => 'Main region', + ], + ] ]; $data['layout_test_1col'][] = <<<'EOD' diff --git a/core/modules/layout_plugin/tests/src/Unit/LayoutPluginManagerTest.php b/core/modules/layout_plugin/tests/src/Unit/LayoutPluginManagerTest.php new file mode 100644 index 0000000..9d243b0 --- /dev/null +++ b/core/modules/layout_plugin/tests/src/Unit/LayoutPluginManagerTest.php @@ -0,0 +1,120 @@ +moduleHandler = $this->prophesize(ModuleHandlerInterface::class); + $this->moduleHandler->moduleExists('layout_test')->willReturn(TRUE); + $extension = new Extension('/', 'module', 'core/modules/layout_plugin/tests/modules/layout_test/layout_test.info.yml'); + $this->moduleHandler->getModule('layout_test')->willReturn($extension); + $this->moduleHandler->getModuleDirectories()->willReturn(['layout_test' => $this->root . '/core/modules/layout_plugin/tests/modules/layout_test']); + + $this->themeHandler = $this->prophesize(ThemeHandlerInterface::class); + $this->themeHandler->getThemeDirectories()->willReturn([]); + + $this->cacheBackend = $this->prophesize(CacheBackendInterface::class); + + $this->layoutPluginManager = new LayoutPluginManager(new \ArrayObject(), $this->cacheBackend->reveal(), $this->moduleHandler->reveal(), $this->themeHandler->reveal(), $this->getStringTranslationStub()); + } + + /** + * @covers ::getDefinitions + */ + public function testGetDefinitions() { + $expected = ['layout_test_1col', 'layout_test_2col']; + + $layout_definitions = $this->layoutPluginManager->getDefinitions(); + $this->assertEquals($expected, array_keys($layout_definitions)); + } + + /** + * @covers ::getDefinition + */ + public function testGetDefinition() { + $expected = [ + 'label' => '2 column layout', + 'theme' => 'layout_test_2col', + 'provider' => 'layout_test', + 'category' => 'Layout test', + 'regions' => [ + 'left' => [ + 'label' => 'Left region', + ], + 'right' => [ + 'label' => 'Right region', + ], + ], + 'path' => 'core/modules/layout_plugin/tests/modules/layout_test', + 'template_path' => 'core/modules/layout_plugin/tests/modules/layout_test/templates', + 'template' => 'layout-test-2col', + 'library' => 'layout_test/layout_test_2col', + 'provider_type' => 'module', + 'id' => 'layout_test_2col', + 'class' => LayoutDefault::class, + ]; + $layout_definition = $this->layoutPluginManager->getDefinition('layout_test_2col'); + $this->assertEquals($expected, $layout_definition); + } + + /** + * @covers ::getThemeImplementations + */ + public function testGetThemeImplementations() { + $expected = [ + 'layout_test_1col' => [ + 'render element' => 'content', + 'template' => 'layout-test-1col', + 'path' => 'core/modules/layout_plugin/tests/modules/layout_test/templates', + ], + 'layout_test_2col' => [ + 'render element' => 'content', + 'template' => 'layout-test-2col', + 'path' => 'core/modules/layout_plugin/tests/modules/layout_test/templates', + ], + ]; + $theme_implementations = $this->layoutPluginManager->getThemeImplementations(); + $this->assertSame($expected, $theme_implementations); + } + +} diff --git a/core/modules/system/system.module b/core/modules/system/system.module index 56dfada..1f553da 100644 --- a/core/modules/system/system.module +++ b/core/modules/system/system.module @@ -224,9 +224,7 @@ function system_theme() { ), 'template' => 'entity-add-list', ), - ), - // Theme functions automatically registered for layouts. - \Drupal::service('plugin.manager.layout')->getThemeImplementations()); + )); } /** diff --git a/core/tests/Drupal/Tests/Core/Layout/LayoutPluginManagerTest.php b/core/tests/Drupal/Tests/Core/Layout/LayoutPluginManagerTest.php deleted file mode 100644 index 2dea742..0000000 --- a/core/tests/Drupal/Tests/Core/Layout/LayoutPluginManagerTest.php +++ /dev/null @@ -1,182 +0,0 @@ -root . '/modules/layout_plugin_test/src'; - - $cache_backend = $this->getMock('Drupal\Core\Cache\CacheBackendInterface'); - - $module_handler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface'); - $module_handler->method('getModuleDirectories')->willReturn(array()); - $module_handler->method('moduleExists')->willReturn(TRUE); - $extension = $this->getMockBuilder('Drupal\Core\Extension\Extension') - ->disableOriginalConstructor() - ->getMock(); - $extension->method('getPath')->willReturn('modules/layout_plugin_test'); - $module_handler->method('getModule')->willReturn($extension); - - $theme_handler = $this->getMock('Drupal\Core\Extension\ThemeHandlerInterface'); - $theme_handler->method('getThemeDirectories')->willReturn(array()); - - $plugin_manager = new LayoutPluginManager($namespaces, $cache_backend, $module_handler, $theme_handler); - - // A simple definition with only the required keys. - $definition = [ - 'label' => 'Simple layout', - 'category' => 'Test layouts', - 'theme' => 'simple_layout', - 'provider' => 'layout_plugin_test', - 'regions' => [ - 'first' => ['label' => 'First region'], - 'second' => ['label' => 'Second region'], - ], - ]; - $plugin_manager->processDefinition($definition, 'simple_layout'); - $this->assertEquals('modules/layout_plugin_test', $definition['path']); - $this->assertEquals([ - 'first' => 'First region', - 'second' => 'Second region' - ], $definition['region_names']); - - // A more complex definition. - $definition = [ - 'label' => 'Complex layout', - 'category' => 'Test layouts', - 'template' => 'complex-layout', - 'library' => 'library_module/library_name', - 'provider' => 'layout_plugin_test', - 'path' => 'layout/complex', - 'icon' => 'complex-layout.png', - 'regions' => [ - 'first' => ['label' => 'First region'], - 'second' => ['label' => 'Second region'], - ], - ]; - $plugin_manager->processDefinition($definition, 'complex_layout'); - $this->assertEquals('modules/layout_plugin_test/layout/complex', $definition['path']); - $this->assertEquals('modules/layout_plugin_test/layout/complex', $definition['template_path']); - $this->assertEquals('modules/layout_plugin_test/layout/complex/complex-layout.png', $definition['icon']); - $this->assertEquals('complex_layout', $definition['theme']); - $this->assertEquals(['module' => ['library_module']], $definition['dependencies']); - - // A layout with a template path. - $definition = [ - 'label' => 'Split layout', - 'category' => 'Test layouts', - 'template' => 'templates/split-layout', - 'provider' => 'layout_plugin_test', - 'path' => 'layouts', - 'icon' => 'images/split-layout.png', - 'regions' => [ - 'first' => ['label' => 'First region'], - 'second' => ['label' => 'Second region'], - ], - ]; - $plugin_manager->processDefinition($definition, 'split_layout'); - $this->assertEquals('modules/layout_plugin_test/layouts', $definition['path']); - $this->assertEquals('modules/layout_plugin_test/layouts/templates', $definition['template_path']); - $this->assertEquals('modules/layout_plugin_test/layouts/images/split-layout.png', $definition['icon']); - $this->assertEquals('split_layout', $definition['theme']); - } - - /** - * Test getting layout options. - * - * @covers ::getLayoutOptions - */ - public function testGetLayoutOptions() { - /** @var LayoutPluginManager|\PHPUnit_Framework_MockObject_MockBuilder $layout_manager */ - $layout_manager = $this->getMockBuilder(LayoutPluginManager::class) - ->disableOriginalConstructor() - ->setMethods(['getDefinitions']) - ->getMock(); - - $layout_manager->method('getDefinitions') - ->willReturn([ - 'simple_layout' => [ - 'label' => 'Simple layout', - 'category' => 'Test layouts', - ], - 'complex_layout' => [ - 'label' => 'Complex layout', - 'category' => 'Test layouts', - ], - ]); - - $options = $layout_manager->getLayoutOptions(); - $this->assertEquals([ - 'simple_layout' => 'Simple layout', - 'complex_layout' => 'Complex layout', - ], $options); - - $options = $layout_manager->getLayoutOptions(array('group_by_category' => TRUE)); - $this->assertEquals([ - 'Test layouts' => [ - 'simple_layout' => 'Simple layout', - 'complex_layout' => 'Complex layout', - ], - ], $options); - } - - /** - * Tests layout theme implementations. - * - * @covers ::getThemeImplementations - */ - public function testGetThemeImplementations() { - /** @var LayoutPluginManager|\PHPUnit_Framework_MockObject_MockBuilder $layout_manager */ - $layout_manager = $this->getMockBuilder(LayoutPluginManager::class) - ->disableOriginalConstructor() - ->setMethods(['getDefinitions']) - ->getMock(); - - $layout_manager->method('getDefinitions') - ->willReturn([ - // Should get template registered automatically. - 'simple_layout' => [ - 'path' => 'modules/layout_plugin_test', - 'template_path' => 'modules/layout_plugin_test/templates', - 'template' => 'simple-layout', - 'theme' => 'simple_layout', - ], - // Shouldn't get registered automatically. - 'complex_layout' => [ - 'path' => 'modules/layout_plugin_test', - 'theme' => 'complex_layout', - ], - ]); - - $theme_registry = $layout_manager->getThemeImplementations(); - $this->assertEquals([ - 'simple_layout' => [ - 'template' => 'simple-layout', - 'path' => 'modules/layout_plugin_test/templates', - 'variables' => [ - 'content' => [], - 'settings' => [], - 'layout' => [], - ], - ], - ], $theme_registry); - } - -}