diff --git a/core/modules/layout_builder/layout_builder.module b/core/modules/layout_builder/layout_builder.module index cf1fcc9..57166dd 100644 --- a/core/modules/layout_builder/layout_builder.module +++ b/core/modules/layout_builder/layout_builder.module @@ -417,3 +417,58 @@ function layout_builder_theme_suggestions_field_alter(&$suggestions, array $vari } return $suggestions; } + +/** + * Move the layout builder element out of the form array. + * + * Layout builders can end up containing forms which would break the + * functionality of the layout builder form being rendered. To avoid this we + * mode the layout_builder element out of the form array onto an attribute so + * it can be rendered safely later by template_preprocess_form__layout_builder. + * + * We do this in a prerender so that the usual form alter hooks can change the + * layout builder element in the usual way. + * + * @param array $element + */ +function layout_builder_layout_builder_form_pre_render(array $element) { + if (!empty($element['#layout_builder_key'])) { + $element['#layout_builder_element'] = $element[$element['#layout_builder_key']]; + unset($element[$element['#layout_builder_key']]); + } + + return $element; +} + +/** + * Implements hook_theme_suggestions_form_alter(). + */ +function layout_builder_theme_suggestions_form_alter(array &$suggestions, $variables) { + // If the layout_builder_element has been removed from the form and stored in + // the #layout_builder_element attribute then use a different theme hook for + // the form. + if (!empty($variables['element']['#layout_builder_element'])) { + $suggestions[] = 'form__layout_builder'; + } +} + +/** + * Preprocess hook for the form__layout_builder template. + * + * @param $variables + */ +function template_preprocess_form__layout_builder(&$variables) { + $variables['layout_builder'] = isset($variables['element']['#layout_builder_element']) ? drupal_render($variables['element']['#layout_builder_element']) : ''; +} + +/** + * Implements hook_theme(). + */ +function layout_builder_theme() { + return [ + 'form__layout_builder' => [ + 'base hook' => 'form', + 'render element' => 'element', + ], + ]; +} diff --git a/core/modules/layout_builder/src/Form/DefaultsEntityForm.php b/core/modules/layout_builder/src/Form/DefaultsEntityForm.php index 8fb71c5..a24da80 100644 --- a/core/modules/layout_builder/src/Form/DefaultsEntityForm.php +++ b/core/modules/layout_builder/src/Form/DefaultsEntityForm.php @@ -81,6 +81,14 @@ public function getBaseFormId() { */ public function buildForm(array $form, FormStateInterface $form_state, SectionStorageInterface $section_storage = NULL) { $form['#attributes']['class'][] = 'layout-builder-form'; + + // Add a pre_render that will remove the 'layout_builder' from the form output + // to be rendered separately by form--layout-builder.html.twig + $form['#pre_render'] = [ + 'layout_builder_layout_builder_form_pre_render', + ]; + $form['#layout_builder_key'] = 'layout_builder'; + $form['layout_builder'] = [ '#type' => 'layout_builder', '#section_storage' => $section_storage, diff --git a/core/modules/layout_builder/src/Form/OverridesEntityForm.php b/core/modules/layout_builder/src/Form/OverridesEntityForm.php index 29f940b..16ed9ac 100644 --- a/core/modules/layout_builder/src/Form/OverridesEntityForm.php +++ b/core/modules/layout_builder/src/Form/OverridesEntityForm.php @@ -104,6 +104,13 @@ public function buildForm(array $form, FormStateInterface $form_state, SectionSt // https://www.drupal.org/node/2942975 is resolved. $form[OverridesSectionStorage::FIELD_NAME]['#access'] = TRUE; + // Add a pre_render that will remove the 'layout_builder' from the form output + // to be rendered separately by form--layout-builder.html.twig + $form['#pre_render'] = [ + 'layout_builder_layout_builder_form_pre_render', + ]; + $form['#layout_builder_key'] = OverridesSectionStorage::FIELD_NAME; + $form['layout_builder_message'] = $this->buildMessage($section_storage->getContextValue('entity'), $section_storage); return $form; } diff --git a/core/modules/layout_builder/templates/form--layout-builder.html.twig b/core/modules/layout_builder/templates/form--layout-builder.html.twig new file mode 100644 index 0000000..6ff115f --- /dev/null +++ b/core/modules/layout_builder/templates/form--layout-builder.html.twig @@ -0,0 +1,16 @@ +{# +/** + * @file + * Theme override for a 'form' element. + * + * Available variables + * - attributes: A list of HTML attributes for the wrapper element. + * - children: The child elements of the form. + * + * @see template_preprocess_form() + */ +#} +
+{{ layout_builder }} diff --git a/core/themes/stable/templates/form/form--layout-builder.html.twig b/core/themes/stable/templates/form/form--layout-builder.html.twig new file mode 100644 index 0000000..6ff115f --- /dev/null +++ b/core/themes/stable/templates/form/form--layout-builder.html.twig @@ -0,0 +1,16 @@ +{# +/** + * @file + * Theme override for a 'form' element. + * + * Available variables + * - attributes: A list of HTML attributes for the wrapper element. + * - children: The child elements of the form. + * + * @see template_preprocess_form() + */ +#} + +{{ layout_builder }}