diff --git a/core/modules/field_layout/config/schema/field_layout.schema.yml b/core/modules/field_layout/config/schema/field_layout.schema.yml index 3b53b3f..185fb4e 100644 --- a/core/modules/field_layout/config/schema/field_layout.schema.yml +++ b/core/modules/field_layout/config/schema/field_layout.schema.yml @@ -6,7 +6,7 @@ core.entity_form_display.*.*.*.third_party.field_layout: field_layout.third_party_settings: type: mapping - label: 'Per view mode field layout settings' + label: 'Per-view-mode field layout settings' mapping: id: type: string diff --git a/core/modules/field_layout/field_layout.install b/core/modules/field_layout/field_layout.install index 6f94674..5956bf1 100644 --- a/core/modules/field_layout/field_layout.install +++ b/core/modules/field_layout/field_layout.install @@ -8,15 +8,15 @@ use Drupal\Core\Cache\Cache; use Drupal\Core\Entity\Entity\EntityFormDisplay; use Drupal\Core\Entity\Entity\EntityViewDisplay; -use Drupal\Core\Entity\EntityInterface; +use Drupal\field_layout\Display\EntityDisplayWithLayoutInterface; /** * Implements hook_install(). */ function field_layout_install() { - // Save each entity display in order to trigger ::preSave(). - $entity_save = function (EntityInterface $entity) { - $entity->save(); + // Ensure each entity display has a layout. + $entity_save = function (EntityDisplayWithLayoutInterface $entity) { + $entity->ensureLayout()->save(); }; array_map($entity_save, EntityViewDisplay::loadMultiple()); array_map($entity_save, EntityFormDisplay::loadMultiple()); @@ -24,3 +24,19 @@ function field_layout_install() { // Invalidate the render cache since all content will now have a layout. Cache::invalidateTags(['rendered']); } + +/** + * Implements hook_uninstall(). + */ +function field_layout_uninstall() { + // Reset each entity display to use the one-column layout to best approximate + // the absence of layouts. + $entity_save = function (EntityDisplayWithLayoutInterface $entity) { + $entity->setLayoutId('layout_onecol')->save(); + }; + array_map($entity_save, EntityViewDisplay::loadMultiple()); + array_map($entity_save, EntityFormDisplay::loadMultiple()); + + // Invalidate the render cache since all content will no longer have a layout. + Cache::invalidateTags(['rendered']); +} diff --git a/core/modules/field_layout/field_layout.layouts.yml b/core/modules/field_layout/field_layout.layouts.yml index 2852708..7f51a69 100644 --- a/core/modules/field_layout/field_layout.layouts.yml +++ b/core/modules/field_layout/field_layout.layouts.yml @@ -1,17 +1,18 @@ -field_layout_onecol: +# @todo Move to layout_discovery in https://www.drupal.org/node/2840832. +layout_onecol: label: 'One column' path: layouts/onecol - template: field-layout--onecol + template: layout--onecol category: 'Columns: 1' default_region: content regions: content: label: Content -field_layout_twocol: +layout_twocol: label: 'Two column' path: layouts/twocol - template: field-layout--twocol - library: field_layout/drupal.field_layout.twocol + template: layout--twocol + library: field_layout/drupal.layout.twocol category: 'Columns: 2' default_region: left regions: diff --git a/core/modules/field_layout/field_layout.libraries.yml b/core/modules/field_layout/field_layout.libraries.yml index d87df5e..aafe7ee 100644 --- a/core/modules/field_layout/field_layout.libraries.yml +++ b/core/modules/field_layout/field_layout.libraries.yml @@ -1,4 +1,4 @@ -drupal.field_layout.twocol: +drupal.layout.twocol: version: VERSION css: layout: diff --git a/core/modules/field_layout/field_layout.module b/core/modules/field_layout/field_layout.module index e076ca7..5a5fa11 100644 --- a/core/modules/field_layout/field_layout.module +++ b/core/modules/field_layout/field_layout.module @@ -51,7 +51,7 @@ function field_layout_entity_type_alter(array &$entity_types) { function field_layout_entity_view_alter(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display) { if ($display instanceof EntityDisplayWithLayoutInterface) { \Drupal::classResolver()->getInstanceFromDefinition(FieldLayoutBuilder::class) - ->build($build, $display, 'view'); + ->buildView($build, $display); } } @@ -63,7 +63,7 @@ function field_layout_form_alter(&$form, FormStateInterface $form_state, $form_i if ($form_object instanceof ContentEntityFormInterface && $display = $form_object->getFormDisplay($form_state)) { if ($display instanceof EntityDisplayWithLayoutInterface) { \Drupal::classResolver()->getInstanceFromDefinition(FieldLayoutBuilder::class) - ->build($form, $display, 'form'); + ->buildForm($form, $display); } } } diff --git a/core/modules/field_layout/layouts/onecol/field-layout--onecol.html.twig b/core/modules/field_layout/layouts/onecol/layout--onecol.html.twig similarity index 66% rename from core/modules/field_layout/layouts/onecol/field-layout--onecol.html.twig rename to core/modules/field_layout/layouts/onecol/layout--onecol.html.twig index cce4893..69fed03 100644 --- a/core/modules/field_layout/layouts/onecol/field-layout--onecol.html.twig +++ b/core/modules/field_layout/layouts/onecol/layout--onecol.html.twig @@ -1,7 +1,7 @@ {# /** * @file - * Default theme implementation to display a one column layout. + * Default theme implementation to display a one-column layout. * * Available variables: * - content: The content for this layout. @@ -12,12 +12,12 @@ #} {% set classes = [ -'field-layout--onecol', +'layout--onecol', ] %} {% if content %} -
+
{{ content }}
diff --git a/core/modules/field_layout/layouts/twocol/field-layout--twocol.html.twig b/core/modules/field_layout/layouts/twocol/layout--twocol.html.twig similarity index 61% rename from core/modules/field_layout/layouts/twocol/field-layout--twocol.html.twig rename to core/modules/field_layout/layouts/twocol/layout--twocol.html.twig index 4dffc01..8e54d30 100644 --- a/core/modules/field_layout/layouts/twocol/field-layout--twocol.html.twig +++ b/core/modules/field_layout/layouts/twocol/layout--twocol.html.twig @@ -1,7 +1,7 @@ {# /** * @file - * Default theme implementation to display a two column layout. + * Default theme implementation to display a two-column layout. * * Available variables: * - content: The content for this layout. @@ -12,16 +12,16 @@ #} {% set classes = [ -'field-layout--twocol', +'layout--twocol', ] %} {% if content %} -
+
{{ content.left }}
-
+
{{ content.right }}
diff --git a/core/modules/field_layout/layouts/twocol/twocol.layout.css b/core/modules/field_layout/layouts/twocol/twocol.layout.css index 8e2f623..78a447d 100644 --- a/core/modules/field_layout/layouts/twocol/twocol.layout.css +++ b/core/modules/field_layout/layouts/twocol/twocol.layout.css @@ -1,14 +1,14 @@ -.field-layout--twocol { +.layout--twocol { display: flex; flex-wrap: wrap; justify-content: space-between; } -.field-layout--twocol > .field-layout-region { +.layout--twocol > .layout-region { flex: 0 1 50%; max-width: 50%; } -.field-layout--twocol > .field-layout-region--left { +.layout--twocol > .layout-region--left { max-width: calc(50% - 10px); margin-right: 10px; } diff --git a/core/modules/field_layout/src/Display/EntityDisplayWithLayoutInterface.php b/core/modules/field_layout/src/Display/EntityDisplayWithLayoutInterface.php index 54a2d52..3bee65e 100644 --- a/core/modules/field_layout/src/Display/EntityDisplayWithLayoutInterface.php +++ b/core/modules/field_layout/src/Display/EntityDisplayWithLayoutInterface.php @@ -64,4 +64,15 @@ public function setLayout(LayoutInterface $layout); */ public function getLayout(); + /** + * Ensures this entity has a layout. + * + * @param string $default_layout_id + * (optional) The layout ID to use as a default. Defaults to + * 'layout_onecol'. + * + * @return $this + */ + public function ensureLayout($default_layout_id = 'layout_onecol'); + } diff --git a/core/modules/field_layout/src/Entity/FieldLayoutEntityDisplayTrait.php b/core/modules/field_layout/src/Entity/FieldLayoutEntityDisplayTrait.php index 201881e..91cf936 100644 --- a/core/modules/field_layout/src/Entity/FieldLayoutEntityDisplayTrait.php +++ b/core/modules/field_layout/src/Entity/FieldLayoutEntityDisplayTrait.php @@ -7,6 +7,10 @@ /** * Provides shared code for entity displays. + * + * Both EntityViewDisplay and EntityFormDisplay must maintain their parent + * hierarchy, while being identically enhanced by Field Layout. This trait + * contains the code they both share. */ trait FieldLayoutEntityDisplayTrait { @@ -41,6 +45,17 @@ public function getLayoutSettings() { * Implements \Drupal\field_layout\Display\EntityDisplayWithLayoutInterface::setLayoutId(). */ public function setLayoutId($layout_id, array $layout_settings = []) { + if ($this->getLayoutId() !== $layout_id) { + // @todo Devise a mechanism for mapping old regions to new ones in + // https://www.drupal.org/node/2796877. + $new_region = $this->getLayoutDefinition($layout_id)->getDefaultRegion(); + foreach ($this->getComponents() as $name => $component) { + if (isset($component['region']) && !isset($layout_regions[$component['region']])) { + $component['region'] = $new_region; + $this->setComponent($name, $component); + } + } + } $this->setThirdPartySetting('field_layout', 'id', $layout_id); $this->setThirdPartySetting('field_layout', 'settings', $layout_settings); return $this; @@ -73,27 +88,21 @@ protected function init() { * Overrides \Drupal\Core\Entity\EntityDisplayBase::preSave(). */ public function preSave(EntityStorageInterface $storage) { - $this->ensureLayout(); - parent::preSave($storage); // Ensure the plugin configuration is updated. Once layouts are no longer // stored as third party settings, this will be handled by the code in // \Drupal\Core\Config\Entity\ConfigEntityBase::preSave() that handles // \Drupal\Core\Entity\EntityWithPluginCollectionInterface. - $this->setLayout($this->getLayout()); + if ($this->getLayoutId()) { + $this->setLayout($this->getLayout()); + } } /** - * Ensures this entity has a layout. - * - * @param string $default_layout_id - * (optional) The layout ID to use as a default. Defaults to - * 'field_layout_onecol'. - * - * @return $this + * {@inheritdoc} */ - protected function ensureLayout($default_layout_id = 'field_layout_onecol') { + public function ensureLayout($default_layout_id = 'layout_onecol') { if (!$this->getLayoutId()) { $this->setLayoutId($default_layout_id); } @@ -104,9 +113,9 @@ protected function ensureLayout($default_layout_id = 'field_layout_onecol') { /** * Overrides \Drupal\Core\Entity\EntityDisplayBase::calculateDependencies(). * - * @todo Remove once https://www.drupal.org/node/2821191 is resolved. - * * @see \Drupal\Core\Plugin\PluginDependencyTrait::calculatePluginDependencies() + * + * @todo Remove once https://www.drupal.org/node/2821191 is resolved. */ public function calculateDependencies() { parent::calculateDependencies(); diff --git a/core/modules/field_layout/src/Entity/FieldLayoutEntityFormDisplay.php b/core/modules/field_layout/src/Entity/FieldLayoutEntityFormDisplay.php index a6a4f2d..c58938e 100644 --- a/core/modules/field_layout/src/Entity/FieldLayoutEntityFormDisplay.php +++ b/core/modules/field_layout/src/Entity/FieldLayoutEntityFormDisplay.php @@ -14,11 +14,10 @@ class FieldLayoutEntityFormDisplay extends EntityFormDisplay implements EntityDi /** * {@inheritdoc} - * - * This cannot be provided by the trait due to https://bugs.php.net/bug.php?id=71414 - * which is fixed in PHP 7.0.6. */ public function getDefaultRegion() { + // This cannot be provided by the trait due to + // https://bugs.php.net/bug.php?id=71414 which is fixed in PHP 7.0.6. return $this->getLayoutDefinition($this->getLayoutId())->getDefaultRegion(); } diff --git a/core/modules/field_layout/src/Entity/FieldLayoutEntityViewDisplay.php b/core/modules/field_layout/src/Entity/FieldLayoutEntityViewDisplay.php index e578686..4f0c274 100644 --- a/core/modules/field_layout/src/Entity/FieldLayoutEntityViewDisplay.php +++ b/core/modules/field_layout/src/Entity/FieldLayoutEntityViewDisplay.php @@ -14,11 +14,10 @@ class FieldLayoutEntityViewDisplay extends EntityViewDisplay implements EntityDi /** * {@inheritdoc} - * - * This cannot be provided by the trait due to https://bugs.php.net/bug.php?id=71414 - * which is fixed in PHP 7.0.6. */ public function getDefaultRegion() { + // This cannot be provided by the trait due to + // https://bugs.php.net/bug.php?id=71414 which is fixed in PHP 7.0.6. return $this->getLayoutDefinition($this->getLayoutId())->getDefaultRegion(); } diff --git a/core/modules/field_layout/src/FieldLayoutBuilder.php b/core/modules/field_layout/src/FieldLayoutBuilder.php index 1fbb53a..41582c1 100644 --- a/core/modules/field_layout/src/FieldLayoutBuilder.php +++ b/core/modules/field_layout/src/FieldLayoutBuilder.php @@ -29,7 +29,7 @@ class FieldLayoutBuilder implements ContainerInjectionInterface { protected $entityFieldManager; /** - * FieldLayoutBuilder constructor. + * Constructs a new FieldLayoutBuilder. * * @param \Drupal\Core\Layout\LayoutPluginManagerInterface $layout_plugin_manager * The layout plugin manager. @@ -59,34 +59,46 @@ public static function create(ContainerInterface $container) { * @param \Drupal\field_layout\Display\EntityDisplayWithLayoutInterface $display * The entity display holding the display options configured for the entity * components. - * @param string $display_context - * The display context, either 'form' or 'view'. If in a 'form' context, an - * alternate method will be used to render fields in their regions. */ - public function build(array &$build, EntityDisplayWithLayoutInterface $display, $display_context) { + public function buildView(array &$build, EntityDisplayWithLayoutInterface $display) { $layout_definition = $this->layoutPluginManager->getDefinition($display->getLayoutId(), FALSE); - if ($layout_definition && $fields = $this->getFields($build, $display, $display_context)) { + if ($layout_definition && $fields = $this->getFields($build, $display, 'view')) { + // Add the regions to the $build in the correct order. + $regions = array_fill_keys($layout_definition->getRegionNames(), []); + + foreach ($fields as $name => $field) { + // Move the field from the top-level of $build into a region-specific + // section. + $regions[$field['region']][$name] = $build[$name]; + unset($build[$name]); + } + $build['field_layout'] = $display->getLayout()->build($regions); + } + } + + /** + * Applies the layout to an entity form. + * + * @param array $build + * A renderable array representing the entity content or form. + * @param \Drupal\field_layout\Display\EntityDisplayWithLayoutInterface $display + * The entity display holding the display options configured for the entity + * components. + */ + public function buildForm(array &$build, EntityDisplayWithLayoutInterface $display) { + $layout_definition = $this->layoutPluginManager->getDefinition($display->getLayoutId(), FALSE); + if ($layout_definition && $fields = $this->getFields($build, $display, 'form')) { // Add the regions to the $build in the correct order. $fill = []; - if ($display_context === 'form') { - $fill['#process'][] = '\Drupal\Core\Render\Element\RenderElement::processGroup'; - $fill['#pre_render'][] = '\Drupal\Core\Render\Element\RenderElement::preRenderGroup'; - } + $fill['#process'][] = '\Drupal\Core\Render\Element\RenderElement::processGroup'; + $fill['#pre_render'][] = '\Drupal\Core\Render\Element\RenderElement::preRenderGroup'; $regions = array_fill_keys($layout_definition->getRegionNames(), $fill); foreach ($fields as $name => $field) { - // If this is a form, #group can be used to relocate the fields. This + // As this is a form, #group can be used to relocate the fields. This // avoids breaking hook_form_alter() implementations by not actually // moving the field in the form structure. - if ($display_context === 'form') { - $build[$name]['#group'] = $field['region']; - } - // Otherwise, move the field from the top-level of $build into a - // region-specific section. - else { - $regions[$field['region']][$name] = $build[$name]; - unset($build[$name]); - } + $build[$name]['#group'] = $field['region']; } $build['field_layout'] = $display->getLayout()->build($regions); } diff --git a/core/modules/field_layout/src/Form/FieldLayoutEntityDisplayFormTrait.php b/core/modules/field_layout/src/Form/FieldLayoutEntityDisplayFormTrait.php index 4f6b52e..b1256fb 100644 --- a/core/modules/field_layout/src/Form/FieldLayoutEntityDisplayFormTrait.php +++ b/core/modules/field_layout/src/Form/FieldLayoutEntityDisplayFormTrait.php @@ -9,6 +9,10 @@ /** * Provides shared code for entity display forms. + * + * Both EntityViewDisplayEditForm and EntityFormDisplayEditForm must maintain + * their parent hierarchy, while being identically enhanced by Field Layout. + * This trait contains the code they both share. */ trait FieldLayoutEntityDisplayFormTrait { @@ -158,40 +162,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) { $layout_plugin->submitConfigurationForm($form['field_layouts']['settings_wrapper']['layout_settings'], SubformState::createForSubform($form['field_layouts']['settings_wrapper']['layout_settings'], $form, $form_state)); } - // If the layout is changing the regions will also change, update the - // placement of all fields. - if ($this->updateLayout($entity, $form_state)) { - // @todo Devise a mechanism for mapping old regions to new ones in - // https://www.drupal.org/node/2796877. - $new_region = $entity->getDefaultRegion(); - foreach ($form_state->getValue('fields') as $field_name => $values) { - if (($component = $entity->getComponent($field_name)) && $new_region !== 'hidden') { - $component['region'] = $new_region; - $entity->setComponent($field_name, $component); - } - else { - $entity->removeComponent($field_name); - } - } - } - } - - /** - * Updates the entity with a new layout. - * - * @param \Drupal\field_layout\Display\EntityDisplayWithLayoutInterface $entity - * The display entity. - * @param \Drupal\Core\Form\FormStateInterface $form_state - * The current form state. - * - * @return bool - * Returns TRUE if the layout has changed, FALSE if it is the same. - */ - protected function updateLayout(EntityDisplayWithLayoutInterface $entity, FormStateInterface $form_state) { - $old_layout = $entity->getLayoutId(); - $new_layout = $form_state->getValue('field_layout'); - $entity->setLayout($this->getLayout($entity, $form_state)); - return $old_layout !== $new_layout; + $entity->setLayout($layout_plugin); } /** diff --git a/core/modules/field_layout/tests/src/Functional/FieldLayoutTest.php b/core/modules/field_layout/tests/src/Functional/FieldLayoutTest.php index 35b4bdd..683ccd2 100644 --- a/core/modules/field_layout/tests/src/Functional/FieldLayoutTest.php +++ b/core/modules/field_layout/tests/src/Functional/FieldLayoutTest.php @@ -47,10 +47,10 @@ protected function setUp() { * Tests an entity type that has fields shown by default. */ public function testNodeView() { - // By default, the one column layout is used. + // By default, the one-column layout is used. $this->drupalGet('node/1'); - $this->assertSession()->elementExists('css', '.field-layout--onecol'); - $this->assertSession()->elementExists('css', '.field-layout-region--content .field--name-body'); + $this->assertSession()->elementExists('css', '.layout--onecol'); + $this->assertSession()->elementExists('css', '.layout-region--content .field--name-body'); $this->drupalGet('admin/structure/types/manage/article/display'); $this->assertEquals(['Content', 'Disabled'], $this->getRegionTitles()); diff --git a/core/modules/field_layout/tests/src/FunctionalJavascript/FieldLayoutTest.php b/core/modules/field_layout/tests/src/FunctionalJavascript/FieldLayoutTest.php index adc176f..1336a70 100644 --- a/core/modules/field_layout/tests/src/FunctionalJavascript/FieldLayoutTest.php +++ b/core/modules/field_layout/tests/src/FunctionalJavascript/FieldLayoutTest.php @@ -47,9 +47,9 @@ protected function setUp() { public function testEntityViewModes() { // By default, the field is not visible. $this->drupalGet('entity_test/1/test'); - $this->assertSession()->elementNotExists('css', '.field-layout-region--content .field--name-field-test-text'); + $this->assertSession()->elementNotExists('css', '.layout-region--content .field--name-field-test-text'); $this->drupalGet('entity_test/1'); - $this->assertSession()->elementNotExists('css', '.field-layout-region--content .field--name-field-test-text'); + $this->assertSession()->elementNotExists('css', '.layout-region--content .field--name-field-test-text'); // Change the layout for the "test" view mode. See // core.entity_view_mode.entity_test.test.yml. @@ -65,26 +65,26 @@ public function testEntityViewModes() { // Each view mode has a different layout. $this->drupalGet('entity_test/1/test'); - $this->assertSession()->elementExists('css', '.field-layout-region--content .field--name-field-test-text'); + $this->assertSession()->elementExists('css', '.layout-region--content .field--name-field-test-text'); $this->drupalGet('entity_test/1'); - $this->assertSession()->elementNotExists('css', '.field-layout-region--content .field--name-field-test-text'); + $this->assertSession()->elementNotExists('css', '.layout-region--content .field--name-field-test-text'); } /** * Tests the use of field layout for entity form displays. */ public function testEntityForm() { - // By default, the one column layout is used. + // By default, the one-column layout is used. $this->drupalGet('entity_test/manage/1/edit'); $this->assertFieldInRegion('field_test_text[0][value]', 'content'); - // The one column layout is in use. + // The one-column layout is in use. $this->drupalGet('entity_test/structure/entity_test/form-display'); $this->assertEquals(['Content', 'Disabled'], $this->getRegionTitles()); // Switch the layout to two columns. $this->click('#edit-field-layouts'); - $this->getSession()->getPage()->selectFieldOption('field_layout', 'field_layout_twocol'); + $this->getSession()->getPage()->selectFieldOption('field_layout', 'layout_twocol'); $this->assertSession()->assertWaitOnAjaxRequest(); $this->submitForm([], 'Save'); @@ -95,7 +95,7 @@ public function testEntityForm() { $this->drupalGet('entity_test/manage/1/edit'); // No fields are visible, and the regions don't display when empty. $this->assertFieldInRegion('field_test_text[0][value]', 'left'); - $this->assertSession()->elementExists('css', '.field-layout-region--left .field--name-field-test-text'); + $this->assertSession()->elementExists('css', '.layout-region--left .field--name-field-test-text'); // After a refresh the new regions are still there. $this->drupalGet('entity_test/structure/entity_test/form-display'); @@ -111,7 +111,7 @@ public function testEntityForm() { // The new layout is used. $this->drupalGet('entity_test/manage/1/edit'); - $this->assertSession()->elementExists('css', '.field-layout-region--right .field--name-field-test-text'); + $this->assertSession()->elementExists('css', '.layout-region--right .field--name-field-test-text'); $this->assertFieldInRegion('field_test_text[0][value]', 'right'); // Move the field to the right region without tabledrag. @@ -136,13 +136,13 @@ public function testEntityForm() { * Tests the use of field layout for entity view displays. */ public function testEntityView() { - // The one column layout is in use. + // The one-column layout is in use. $this->drupalGet('entity_test/structure/entity_test/display'); $this->assertEquals(['Content', 'Disabled'], $this->getRegionTitles()); // Switch the layout to two columns. $this->click('#edit-field-layouts'); - $this->getSession()->getPage()->selectFieldOption('field_layout', 'field_layout_twocol'); + $this->getSession()->getPage()->selectFieldOption('field_layout', 'layout_twocol'); $this->assertSession()->assertWaitOnAjaxRequest(); $this->submitForm([], 'Save'); @@ -151,8 +151,8 @@ public function testEntityView() { $this->drupalGet('entity_test/1'); // No fields are visible, and the regions don't display when empty. - $this->assertSession()->elementNotExists('css', '.field-layout--twocol'); - $this->assertSession()->elementNotExists('css', '.field-layout-region'); + $this->assertSession()->elementNotExists('css', '.layout--twocol'); + $this->assertSession()->elementNotExists('css', '.layout-region'); $this->assertSession()->elementNotExists('css', '.field--name-field-test-text'); // After a refresh the new regions are still there. @@ -171,8 +171,8 @@ public function testEntityView() { // The new layout is used. $this->drupalGet('entity_test/1'); - $this->assertSession()->elementExists('css', '.field-layout--twocol'); - $this->assertSession()->elementExists('css', '.field-layout-region--left .field--name-field-test-text'); + $this->assertSession()->elementExists('css', '.layout--twocol'); + $this->assertSession()->elementExists('css', '.layout-region--left .field--name-field-test-text'); // Move the field to the right region without tabledrag. $this->drupalGet('entity_test/structure/entity_test/display'); @@ -184,13 +184,13 @@ public function testEntityView() { // The updated region is used. $this->drupalGet('entity_test/1'); - $this->assertSession()->elementExists('css', '.field-layout-region--right .field--name-field-test-text'); + $this->assertSession()->elementExists('css', '.layout-region--right .field--name-field-test-text'); // The layout is still in use without Field UI. $this->container->get('module_installer')->uninstall(['field_ui']); $this->drupalGet('entity_test/1'); - $this->assertSession()->elementExists('css', '.field-layout--twocol'); - $this->assertSession()->elementExists('css', '.field-layout-region--right .field--name-field-test-text'); + $this->assertSession()->elementExists('css', '.layout--twocol'); + $this->assertSession()->elementExists('css', '.layout-region--right .field--name-field-test-text'); } /** @@ -258,7 +258,7 @@ protected function getRegionTitles() { * The machine name of the region. */ protected function assertFieldInRegion($field_selector, $region_name) { - $region_element = $this->getSession()->getPage()->find('css', ".field-layout-region--$region_name"); + $region_element = $this->getSession()->getPage()->find('css', ".layout-region--$region_name"); $this->assertNotNull($region_element); $this->assertSession()->fieldExists($field_selector, $region_element); } diff --git a/core/modules/field_layout/tests/src/Kernel/FieldLayoutEntityDisplayTest.php b/core/modules/field_layout/tests/src/Kernel/FieldLayoutEntityDisplayTest.php index edfb19b..a70ecdd 100644 --- a/core/modules/field_layout/tests/src/Kernel/FieldLayoutEntityDisplayTest.php +++ b/core/modules/field_layout/tests/src/Kernel/FieldLayoutEntityDisplayTest.php @@ -15,7 +15,7 @@ class FieldLayoutEntityDisplayTest extends KernelTestBase { /** * {@inheritdoc} */ - protected static $modules = ['layout_discovery', 'field_layout', 'entity_test', 'field_layout_test']; + protected static $modules = ['layout_discovery', 'field_layout', 'entity_test', 'field_layout_test', 'system']; /** * @covers ::preSave @@ -40,7 +40,7 @@ public function testPreSave() { 'dependencies' => [], 'third_party_settings' => [ 'field_layout' => [ - 'id' => 'field_layout_onecol', + 'id' => 'layout_onecol', 'settings' => [], ], ], @@ -73,7 +73,7 @@ public function testPreSave() { ], 'third_party_settings' => [ 'field_layout' => [ - 'id' => 'field_layout_onecol', + 'id' => 'layout_onecol', 'settings' => [], ], 'entity_test' => [ @@ -129,7 +129,10 @@ public function testPreSave() { 'content' => [ 'foo' => [ 'type' => 'visible', - 'region' => 'content', + 'region' => 'main', + 'weight' => -4, + 'settings' => [], + 'third_party_settings' => [], ], ], 'hidden' => [ @@ -172,7 +175,43 @@ public function testPreSave() { 'content' => [ 'foo' => [ 'type' => 'visible', + 'region' => 'main', + 'weight' => -4, + 'settings' => [], + 'third_party_settings' => [], + ], + ], + 'hidden' => [ + 'bar' => TRUE, + ], + ]; + + $this->assertEntityValues($expected, $entity_display); + + $expected = [ + 'langcode' => 'en', + 'status' => TRUE, + 'dependencies' => [ + 'module' => [ + 'entity_test', + ], + ], + 'third_party_settings' => [ + 'entity_test' => [ + 'foo' => 'bar', + ], + ], + 'id' => 'entity_test.entity_test.default', + 'targetEntityType' => 'entity_test', + 'bundle' => 'entity_test', + 'mode' => 'default', + 'content' => [ + 'foo' => [ + 'type' => 'visible', 'region' => 'content', + 'weight' => -4, + 'settings' => [], + 'third_party_settings' => [], ], ], 'hidden' => [ @@ -180,6 +219,9 @@ public function testPreSave() { ], ]; + $this->container->get('module_installer')->uninstall(['field_layout']); + $entity_storage = $this->container->get('entity_type.manager')->getStorage('entity_view_display'); + $entity_display = $entity_storage->load('entity_test.entity_test.default'); $this->assertEntityValues($expected, $entity_display); } diff --git a/core/modules/field_layout/tests/src/Unit/FieldLayoutBuilderTest.php b/core/modules/field_layout/tests/src/Unit/FieldLayoutBuilderTest.php index 4dd7204..5d881bc 100644 --- a/core/modules/field_layout/tests/src/Unit/FieldLayoutBuilderTest.php +++ b/core/modules/field_layout/tests/src/Unit/FieldLayoutBuilderTest.php @@ -50,8 +50,8 @@ protected function setUp() { parent::setUp(); $this->pluginDefinition = new LayoutDefinition([ - 'library' => 'field_layout/drupal.field_layout.twocol', - 'theme_hook' => 'field_layout__twocol', + 'library' => 'field_layout/drupal.layout.twocol', + 'theme_hook' => 'layout__twocol', 'regions' => [ 'left' => [ 'label' => 'Left', @@ -73,7 +73,7 @@ protected function setUp() { } /** - * @covers ::build + * @covers ::buildView * @covers ::getFields */ public function testBuildView() { @@ -107,8 +107,6 @@ public function testBuildView() { ], ]); - $display_context = 'view'; - $expected = [ 'non_configurable_field' => [ '#markup' => 'Non-configurable', @@ -122,21 +120,21 @@ public function testBuildView() { ], '#settings' => [], '#layout' => $this->pluginDefinition, - '#theme' => 'field_layout__twocol', + '#theme' => 'layout__twocol', '#attached' => [ 'library' => [ - 'field_layout/drupal.field_layout.twocol', + 'field_layout/drupal.layout.twocol', ], ], ], ]; - $this->fieldLayoutBuilder->build($build, $display->reveal(), $display_context); + $this->fieldLayoutBuilder->buildView($build, $display->reveal()); $this->assertEquals($expected, $build); $this->assertSame($expected, $build); } /** - * @covers ::build + * @covers ::buildForm * @covers ::getFields */ public function testBuildForm() { @@ -170,8 +168,6 @@ public function testBuildForm() { ], ]); - $display_context = 'form'; - $expected = [ 'test1' => [ '#markup' => 'Test1', @@ -191,23 +187,23 @@ public function testBuildForm() { ], '#settings' => [], '#layout' => $this->pluginDefinition, - '#theme' => 'field_layout__twocol', + '#theme' => 'layout__twocol', '#attached' => [ 'library' => [ - 'field_layout/drupal.field_layout.twocol', + 'field_layout/drupal.layout.twocol', ], ], ], ]; - $this->fieldLayoutBuilder->build($build, $display->reveal(), $display_context); + $this->fieldLayoutBuilder->buildForm($build, $display->reveal()); $this->assertEquals($expected, $build); $this->assertSame($expected, $build); } /** - * @covers ::build + * @covers ::buildForm */ - public function testBuildEmpty() { + public function testBuildFormEmpty() { $definitions = []; $non_configurable_field_definition = $this->prophesize(FieldDefinitionInterface::class); $non_configurable_field_definition->isDisplayConfigurable('form')->willReturn(FALSE); @@ -235,21 +231,19 @@ public function testBuildEmpty() { ], ]); - $display_context = 'form'; - $expected = [ 'non_configurable_field' => [ '#markup' => 'Non-configurable', ], ]; - $this->fieldLayoutBuilder->build($build, $display->reveal(), $display_context); + $this->fieldLayoutBuilder->buildForm($build, $display->reveal()); $this->assertSame($expected, $build); } /** - * @covers ::build + * @covers ::buildForm */ - public function testBuildNoLayout() { + public function testBuildFormNoLayout() { $this->entityFieldManager->getFieldDefinitions(Argument::any(), Argument::any())->shouldNotBeCalled(); $build = [ @@ -263,14 +257,12 @@ public function testBuildNoLayout() { $display->getLayoutSettings()->willReturn([]); $display->getComponents()->shouldNotBeCalled(); - $display_context = 'form'; - $expected = [ 'test1' => [ '#markup' => 'Test1', ], ]; - $this->fieldLayoutBuilder->build($build, $display->reveal(), $display_context); + $this->fieldLayoutBuilder->buildForm($build, $display->reveal()); $this->assertSame($expected, $build); }