diff --git a/core/modules/field_layout/field_layout.install b/core/modules/field_layout/field_layout.install new file mode 100644 index 0000000..6b761bc --- /dev/null +++ b/core/modules/field_layout/field_layout.install @@ -0,0 +1,32 @@ +listAll('core.entity_view_display.'), $config_factory->listAll('core.entity_form_display.')); + foreach ($config_names as $name) { + $config = $config_factory->getEditable($name); + // Build a list of all fields, and determine their region by whether they + // are hidden or not. + $field_layout = []; + $field_layout += array_fill_keys(array_keys($config->get('content')), ['region' => 'content']); + $field_layout += array_fill_keys(array_keys($config->get('hidden')), ['region' => 'hidden']); + $config + ->set('third_party_settings.field_layout.fields', $field_layout) + ->set('third_party_settings.field_layout.layout', 'default') + ->save(TRUE); + } + + // Invalidate the render cache since all content will now have a layout. + Cache::invalidateTags(['rendered']); +} diff --git a/core/modules/field_layout/field_layout.module b/core/modules/field_layout/field_layout.module index 01e6bb8..14cf931 100644 --- a/core/modules/field_layout/field_layout.module +++ b/core/modules/field_layout/field_layout.module @@ -9,6 +9,7 @@ use Drupal\Core\Entity\Display\EntityDisplayInterface; use Drupal\Core\Entity\Display\EntityViewDisplayInterface; use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Routing\RouteMatchInterface; use Drupal\field_layout\Form\FieldLayoutEntityFormDisplayEditForm; @@ -39,6 +40,43 @@ function field_layout_entity_type_alter(array &$entity_types) { } /** + * Implements hook_entity_presave(). + */ +function field_layout_entity_presave(EntityInterface $entity) { + // Whenever creating a new entity display, set the layout to default and + // initialize the field layout based on default configuration. + if ($entity instanceof EntityDisplayInterface && $entity->isNew()) { + $field_layout = []; + foreach (_field_layout_get_configurable_field_names_from_display($entity) as $name) { + $field_layout[$name]['region'] = $entity->getComponent($name) ? 'content' : 'hidden'; + } + $entity->setThirdPartySetting('field_layout', 'fields', $field_layout); + $entity->setThirdPartySetting('field_layout', 'layout', 'default'); + } +} + +/** + * Gets the names of all configurable fields for a display.array + * + * @param \Drupal\Core\Entity\Display\EntityDisplayInterface $display + * The entity display with the fields. + * + * @return string[] + * An array of field names. + */ +function _field_layout_get_configurable_field_names_from_display(EntityDisplayInterface $display) { + $entity_field_manager = \Drupal::service('entity_field.manager'); + $context = $display->get('displayContext'); + $fields = array_filter($entity_field_manager->getFieldDefinitions($display->getTargetEntityTypeId(), $display->getTargetBundle()), function(FieldDefinitionInterface $field_definition) use ($context) { + return $field_definition->isDisplayConfigurable($context); + }); + if ($context === 'view') { + $fields += $entity_field_manager->getExtraFields($display->getTargetEntityTypeId(), $display->getTargetBundle())['display']; + } + return array_keys($fields); +} + +/** * Implements hook_entity_view_alter(). */ function field_layout_entity_view_alter(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display) { diff --git a/core/modules/field_layout/tests/src/FunctionalJavascript/FieldLayoutTest.php b/core/modules/field_layout/tests/src/FunctionalJavascript/FieldLayoutTest.php index 3c81d7c..705b769 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() { * Tests the use of field layout for entity view displays. */ public function testEntityView() { + // By default, the default layout is used. $this->drupalGet('node/1'); - $this->assertSession()->elementExists('css', '.field--name-body'); - $this->assertSession()->elementNotExists('css', '.field-layout-region-left'); + $this->assertSession()->elementExists('css', '.field-layout-region-content .field--name-body'); // The default layout is in use. $this->drupalGet('admin/structure/types/manage/article/display'); @@ -64,7 +64,8 @@ public function testEntityView() { $this->assertEquals(['Left', 'Right', 'Disabled'], $this->getRegionTitles()); $this->drupalGet('node/1'); - $this->assertSession()->elementNotExists('css', '.field-layout-region-left'); + // No fields are visible, and the regions don't display when empty. + $this->assertSession()->elementNotExists('css', '.field-layout-region'); $this->assertSession()->elementNotExists('css', '.field--name-body'); // After a refresh the new regions are still there. @@ -88,6 +89,7 @@ public function testEntityView() { $this->assertSession()->assertWaitOnAjaxRequest(); $this->submitForm([], 'Save'); + // The new layout is used. $this->drupalGet('node/1'); $this->assertSession()->elementExists('css', '.field-layout-region-left .field--name-body'); }