diff --git a/ds.module b/ds.module
index c4c42120..3fcb9fec 100644
--- a/ds.module
+++ b/ds.module
@@ -497,17 +497,19 @@ function ds_preprocess_ds_layout(&$variables) {
   }
 
   // Create region variables based on the layout settings.
-  foreach ($layout_settings['wrappers'] as $region_name => $wrapper) {
-    // @todo remove from D9, This is deprecated
-    $variables[$region_name . '_classes'] = !empty($layout_settings['classes'][$region_name]) ? ' ' . implode(' ', $layout_settings['classes'][$region_name]) : '';
-    // The new way of doing stuff is creating an attributes object.
-    if (!empty($layout_settings['classes'][$region_name])) {
-      $variables[$region_name . '_attributes'] = new Attribute(['class' => $layout_settings['classes'][$region_name]]);
+  if (!empty($layout_settings['wrappers']) && is_array($layout_settings['wrappers'])) {
+    foreach ($layout_settings['wrappers'] as $region_name => $wrapper) {
+      // @todo remove from D9, This is deprecated
+      $variables[$region_name . '_classes'] = !empty($layout_settings['classes'][$region_name]) ? ' ' . implode(' ', $layout_settings['classes'][$region_name]) : '';
+      // The new way of doing stuff is creating an attributes object.
+      if (!empty($layout_settings['classes'][$region_name])) {
+        $variables[$region_name . '_attributes'] = new Attribute(['class' => $layout_settings['classes'][$region_name]]);
+      }
+      else {
+        $variables[$region_name . '_attributes'] = new Attribute();
+      }
+      $variables[$region_name . '_wrapper'] = !empty($layout_settings['wrappers'][$region_name]) ? $layout_settings['wrappers'][$region_name] : 'div';
     }
-    else {
-      $variables[$region_name . '_attributes'] = new Attribute();
-    }
-    $variables[$region_name . '_wrapper'] = !empty($layout_settings['wrappers'][$region_name]) ? $layout_settings['wrappers'][$region_name] : 'div';
   }
 
   // Add a layout wrapper.
diff --git a/includes/field_ui.inc b/includes/field_ui.inc
index f0ae68e2..77c4db36 100644
--- a/includes/field_ui.inc
+++ b/includes/field_ui.inc
@@ -11,6 +11,7 @@ use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
 use Drupal\Core\Entity\Entity\EntityViewDisplay;
 use Drupal\Core\Form\FormState;
 use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Messenger\MessengerInterface;
 use Drupal\Core\Plugin\PluginFormInterface;
 use Drupal\Core\Render\Element;
 use Drupal\Core\Url;
@@ -428,7 +429,7 @@ function ds_field_ui_layouts_save($form, FormStateInterface $form_state) {
     $record['layout']['settings']['attributes'] = '';
     $record['layout']['settings']['link_attribute'] = FALSE;
     $record['layout']['settings']['link_custom'] = '';
-    $fields = _ds_sort_fields($form_state->getValue('fields'), 'weight');
+    $fields = _ds_sort_fields((array) $form_state->getValue('fields'), 'weight');
     foreach ($fields as $field_key => $field) {
 
       // Ignore new fieldgroup, new field or existing field.
@@ -455,7 +456,7 @@ function ds_field_ui_layouts_save($form, FormStateInterface $form_state) {
   elseif (!empty($layout)) {
     $save_display = TRUE;
 
-    $fields = _ds_sort_fields($form_state->getValue('fields'), 'weight');
+    $fields = _ds_sort_fields((array) $form_state->getValue('fields'), 'weight');
 
     foreach ($fields as $key => $field) {
       // Make sure to hide hidden fields.
@@ -1134,6 +1135,80 @@ function _ds_field_ui_fields($entity_type, $bundle, $view_mode, array &$form, Fo
   $field_settings = $form['#ds_layout']['fields'];
   $form['#field_settings'] = $field_settings;
 
+  if (empty($form['fields'])) {
+    // EntityDisplayFormBase doesn't add the fields table and field_ui library
+    // when there are no fields.  Since DS needs those, we add them.
+    $form['#attached']['library'][] = 'field_ui/drupal.field_ui';
+    $form['fields'] = [
+      '#type' => 'field_ui_table',
+      '#weight' => -101,
+      '#header' => [
+        t('Field'),
+        t('Weight'),
+        t('Parent'),
+        t('Region'),
+        t('Label'),
+        ['data' => t('Format'), 'colspan' => 3],
+      ],
+      '#regions' => [],
+      '#attributes' => [
+        'class' => ['field-ui-overview'],
+        'id' => 'field-display-overview',
+      ],
+      '#tabledrag' => [
+        [
+          'action' => 'order',
+          'relationship' => 'sibling',
+          'group' => 'field-weight',
+        ],
+        [
+          'action' => 'match',
+          'relationship' => 'parent',
+          'group' => 'field-parent',
+          'subgroup' => 'field-parent',
+          'source' => 'field-name',
+        ],
+        [
+          'action' => 'match',
+          'relationship' => 'parent',
+          'group' => 'field-region',
+          'subgroup' => 'field-region',
+          'source' => 'field-name',
+        ],
+      ],
+    ];
+
+    // Check for the 'There are no fields yet added. You can add new fields on
+    // the Manage fields page.' warning message. We really don't need it.
+    $warnings = \Drupal::messenger()->messagesByType(MessengerInterface::TYPE_WARNING);
+    if (count($warnings) == 1) {
+      \Drupal::messenger()->deleteByType(MessengerInterface::TYPE_WARNING);
+    }
+
+    // In overviews involving nested rows from contributed modules (i.e
+    // field_group), the 'plugin type' selects can trigger a series of changes
+    // in child rows. The #ajax behavior is therefore not attached directly to
+    // the selects, but triggered by the client-side script through a hidden
+    // #ajax 'Refresh' button. A hidden 'refresh_rows' input tracks the name of
+    // affected rows.
+    $form['refresh_rows'] = ['#type' => 'hidden'];
+    $form['refresh'] = [
+      '#type' => 'submit',
+      '#value' => t('Refresh'),
+      '#op' => 'refresh_table',
+      '#submit' => ['::multistepSubmit'],
+      '#ajax' => [
+        'callback' => '::multistepAjax',
+        'wrapper' => 'field-display-overview-wrapper',
+        'effect' => 'fade',
+        // The button stays hidden, so we hide the Ajax spinner too. Ad-hoc
+        // spinners will be added manually by the client-side script.
+        'progress' => 'none',
+      ],
+      '#attributes' => ['class' => ['visually-hidden']],
+    ];
+
+  }
   $table = &$form['fields'];
   $form['#ds_fields'] = [];
 
@@ -1449,6 +1524,7 @@ function ds_field_row_form_format_summary_construct(&$table, $key, FormStateInte
  */
 function _ds_sort_fields(array $a, $subkey) {
   $c = [];
+  $b = [];
   foreach ($a as $k => $v) {
     if (isset($v[$subkey])) {
       $b[$k] = $v[$subkey];
