diff --git a/core/lib/Drupal/Core/Entity/ContentEntityForm.php b/core/lib/Drupal/Core/Entity/ContentEntityForm.php index 14e910d..3cd9e51 100644 --- a/core/lib/Drupal/Core/Entity/ContentEntityForm.php +++ b/core/lib/Drupal/Core/Entity/ContentEntityForm.php @@ -100,17 +100,6 @@ protected function getBundleEntity() { * {@inheritdoc} */ public function form(array $form, FormStateInterface $form_state) { - - if ($this->showRevisionUi()) { - // Advanced tab must be the first, because other fields rely on that. - if (!isset($form['advanced'])) { - $form['advanced'] = [ - '#type' => 'vertical_tabs', - '#weight' => 99, - ]; - } - } - $form = parent::form($form, $form_state); // Content entity forms do not use the parent's #after_build callback @@ -387,13 +376,12 @@ protected function addRevisionableFormFields(array &$form) { // Add a log field if the "Create new revision" option is checked, or if the // current user has the ability to check that option. + // @todo Convert to a field group. $form['revision_information'] = [ '#type' => 'details', '#title' => $this->t('Revision information'), // Open by default when "Create new revision" is checked. '#open' => $new_revision_default, - '#group' => 'advanced', - '#weight' => 20, '#access' => $new_revision_default || $this->entity->get($entity_type->getKey('revision'))->access('update'), '#optional' => TRUE, '#attributes' => [ diff --git a/core/lib/Drupal/Core/Entity/EntityDisplayBase.php b/core/lib/Drupal/Core/Entity/EntityDisplayBase.php index b6c73e5..d9370f0 100644 --- a/core/lib/Drupal/Core/Entity/EntityDisplayBase.php +++ b/core/lib/Drupal/Core/Entity/EntityDisplayBase.php @@ -163,18 +163,16 @@ protected function init() { if (!isset($this->content[$name]) && !isset($this->hidden[$name])) { // Extra fields are visible by default unless they explicitly say so. if (!isset($definition['visible']) || $definition['visible'] == TRUE) { - $this->content[$name] = array( - 'weight' => $definition['weight'] - ); + $definition += ['region' => $default_region]; + $this->content[$name] = [ + 'weight' => $definition['weight'], + 'region' => $definition['region'], + ]; } else { $this->hidden[$name] = TRUE; } } - // Ensure extra fields have a 'region'. - if (isset($this->content[$name])) { - $this->content[$name] += ['region' => $default_region]; - } } // Fill in defaults for fields. diff --git a/core/lib/Drupal/Core/Render/Element/Actions.php b/core/lib/Drupal/Core/Render/Element/Actions.php index 1f94466..ca9ff6d 100644 --- a/core/lib/Drupal/Core/Render/Element/Actions.php +++ b/core/lib/Drupal/Core/Render/Element/Actions.php @@ -35,8 +35,12 @@ public function getInfo() { // @todo Move this to #pre_render. array($class, 'preRenderActionsDropbutton'), array($class, 'processActions'), + array($class, 'processGroup'), array($class, 'processContainer'), ), + '#pre_render' => array( + array($class, 'preRenderGroup'), + ), '#weight' => 100, '#theme_wrappers' => array('container'), ); diff --git a/core/modules/book/book.module b/core/modules/book/book.module index ecccb74..efdd44a 100644 --- a/core/modules/book/book.module +++ b/core/modules/book/book.module @@ -127,6 +127,25 @@ function book_node_links_alter(array &$links, NodeInterface $node, array &$conte } /** + * Implements hook_entity_extra_field_info(). + */ +function book_entity_extra_field_info() { + $extra = []; + $description = t('Book module element'); + foreach (array_keys(\Drupal::service('entity_type.bundle.info')->getBundleInfo('node')) as $bundle) { + // @todo Convert to a field group. + $extra['node'][$bundle]['form']['book'] = [ + 'label' => t('Book outline'), + 'description' => $description, + 'weight' => 10, + 'region' => 'advanced', + ]; + } + + return $extra; +} + +/** * Implements hook_form_BASE_FORM_ID_alter() for \Drupal\node\NodeForm. * * Adds the book form element to the node form. diff --git a/core/modules/book/src/BookManager.php b/core/modules/book/src/BookManager.php index 60754be..1205806 100644 --- a/core/modules/book/src/BookManager.php +++ b/core/modules/book/src/BookManager.php @@ -159,12 +159,11 @@ public function addFormElements(array $form, FormStateInterface $form_state, Nod if ($form_state->hasValue('book')) { $node->book = $form_state->getValue('book'); } + // @todo Convert to a field group. $form['book'] = array( '#type' => 'details', '#title' => $this->t('Book outline'), - '#weight' => 10, '#open' => !$collapsed, - '#group' => 'advanced', '#attributes' => array( 'class' => array('book-outline-form'), ), diff --git a/core/modules/comment/src/Plugin/Field/FieldWidget/CommentWidget.php b/core/modules/comment/src/Plugin/Field/FieldWidget/CommentWidget.php index 818226d..67aa977 100644 --- a/core/modules/comment/src/Plugin/Field/FieldWidget/CommentWidget.php +++ b/core/modules/comment/src/Plugin/Field/FieldWidget/CommentWidget.php @@ -58,7 +58,7 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen // If the advanced settings tabs-set is available (normally rendered in the // second column on wide-resolutions), place the field as a details element // in this tab-set. - if (isset($form['advanced'])) { + if ($entity->getEntityType()->showRevisionUi()) { // Get default value from the field. $field_default_values = $this->fieldDefinition->getDefaultValue($entity); @@ -70,7 +70,6 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen // Open the details when the selected value is different to the stored // default values for the field. '#open' => ($items->status != $field_default_values[0]['status']), - '#group' => 'advanced', '#attributes' => array( 'class' => array('comment-' . Html::getClass($entity->getEntityTypeId()) . '-settings-form'), ), diff --git a/core/modules/content_translation/content_translation.module b/core/modules/content_translation/content_translation.module index 70413d9..a3d7725 100644 --- a/core/modules/content_translation/content_translation.module +++ b/core/modules/content_translation/content_translation.module @@ -355,9 +355,11 @@ function content_translation_entity_extra_field_info() { foreach (\Drupal::entityManager()->getDefinitions() as $entity_type => $info) { foreach ($bundle_info_service->getBundleInfo($entity_type) as $bundle => $bundle_info) { if (\Drupal::service('content_translation.manager')->isEnabled($entity_type, $bundle)) { - $extra[$entity_type][$bundle]['form']['translation'] = array( + // @todo Convert to a field group. + $extra[$entity_type][$bundle]['form']['content_translation'] = array( 'label' => t('Translation'), 'description' => t('Translation settings'), + 'region' => 'advanced', 'weight' => 10, ); } diff --git a/core/modules/content_translation/src/ContentTranslationHandler.php b/core/modules/content_translation/src/ContentTranslationHandler.php index c155069..4c6778c 100644 --- a/core/modules/content_translation/src/ContentTranslationHandler.php +++ b/core/modules/content_translation/src/ContentTranslationHandler.php @@ -377,6 +377,7 @@ public function entityFormAlter(array &$form, FormStateInterface $form_state, En // We need to display the translation tab only when there is at least one // translation available or a new one is about to be created. if ($new_translation || $has_translations) { + // @todo Convert to a field group. $form['content_translation'] = array( '#type' => 'details', '#title' => t('Translation'), @@ -386,10 +387,8 @@ public function entityFormAlter(array &$form, FormStateInterface $form_state, En '#multilingual' => TRUE, ); - if (isset($form['advanced'])) { + if ($entity->getEntityType()->showRevisionUi()) { $form['content_translation'] += array( - '#group' => 'advanced', - '#weight' => 100, '#attributes' => array( 'class' => array('entity-translation-options'), ), diff --git a/core/modules/field_layout/field_layout.install b/core/modules/field_layout/field_layout.install index 5956bf1..c0f3bbc 100644 --- a/core/modules/field_layout/field_layout.install +++ b/core/modules/field_layout/field_layout.install @@ -14,6 +14,8 @@ * Implements hook_install(). */ function field_layout_install() { + module_set_weight('field_layout', 20); + // Ensure each entity display has a layout. $entity_save = function (EntityDisplayWithLayoutInterface $entity) { $entity->ensureLayout()->save(); diff --git a/core/modules/field_layout/src/Form/FieldLayoutEntityDisplayFormTrait.php b/core/modules/field_layout/src/Form/FieldLayoutEntityDisplayFormTrait.php index 043e5c7..304831b 100644 --- a/core/modules/field_layout/src/Form/FieldLayoutEntityDisplayFormTrait.php +++ b/core/modules/field_layout/src/Form/FieldLayoutEntityDisplayFormTrait.php @@ -31,10 +31,12 @@ public function getRegions() { $layout_definition = $this->layoutPluginManager->getDefinition($this->getEntity()->getLayoutId()); foreach ($layout_definition->getRegions() as $name => $region) { - $regions[$name] = [ - 'title' => $region['label'], - 'message' => $this->t('No field is displayed.'), - ]; + if (empty($region['hidden'])) { + $regions[$name] = [ + 'title' => $region['label'], + 'message' => $this->t('No field is displayed.'), + ]; + } } $regions['hidden'] = [ diff --git a/core/modules/menu_ui/menu_ui.module b/core/modules/menu_ui/menu_ui.module index 92254c2..cc2ec7e 100644 --- a/core/modules/menu_ui/menu_ui.module +++ b/core/modules/menu_ui/menu_ui.module @@ -257,6 +257,24 @@ function menu_ui_get_menu_link_defaults(NodeInterface $node) { } /** + * Implements hook_entity_extra_field_info(). + */ +function menu_ui_entity_extra_field_info() { + $extra = []; + $description = t('Menu UI module element'); + foreach (array_keys(\Drupal::service('entity_type.bundle.info')->getBundleInfo('node')) as $bundle) { + $extra['node'][$bundle]['form']['menu'] = [ + 'label' => t('Menu settings'), + 'description' => $description, + 'weight' => -2, + 'region' => 'advanced', + ]; + } + + return $extra; +} + +/** * Implements hook_form_BASE_FORM_ID_alter() for \Drupal\node\NodeForm. * * Adds menu item fields to the node form. @@ -295,12 +313,10 @@ function menu_ui_form_node_form_alter(&$form, FormStateInterface $form_state) { '#title' => t('Menu settings'), '#access' => \Drupal::currentUser()->hasPermission('administer menu'), '#open' => (bool) $defaults['id'], - '#group' => 'advanced', '#attached' => array( 'library' => array('menu_ui/drupal.menu_ui'), ), '#tree' => TRUE, - '#weight' => -2, '#attributes' => array('class' => array('menu-link-form')), ); $form['menu']['enabled'] = array( diff --git a/core/modules/node/node.info.yml b/core/modules/node/node.info.yml index 9b53d58..a4f091d 100644 --- a/core/modules/node/node.info.yml +++ b/core/modules/node/node.info.yml @@ -6,4 +6,5 @@ version: VERSION core: 8.x configure: entity.node_type.collection dependencies: + - field_layout - text diff --git a/core/modules/node/node.layouts.yml b/core/modules/node/node.layouts.yml new file mode 100644 index 0000000..66710be --- /dev/null +++ b/core/modules/node/node.layouts.yml @@ -0,0 +1,14 @@ +node_form: + label: 'Node form' + template: templates/layout--node-edit-form + library: node/form + category: 'Columns: 2' + default_region: content + regions: + content: + label: Content + advanced: + label: Advanced + footer: + label: Footer + hidden: true diff --git a/core/modules/node/node.module b/core/modules/node/node.module index d3a83e0..f2a40f7 100644 --- a/core/modules/node/node.module +++ b/core/modules/node/node.module @@ -337,6 +337,7 @@ function node_add_body_field(NodeTypeInterface $type, $label = 'Body') { ->setComponent('body', array( 'type' => 'text_textarea_with_summary', )) + ->setLayoutId('node_form') ->save(); // Assign display settings for the 'default' and 'teaser' view modes. @@ -376,6 +377,22 @@ function node_entity_extra_field_info() { 'weight' => 100, 'visible' => TRUE, ); + // @todo Convert to a field group. + $extra['node'][$bundle->id()]['form']['author'] = [ + 'label' => t('Authoring information'), + 'description' => $description, + 'weight' => 90, + 'region' => 'advanced', + 'visible' => TRUE, + ]; + // @todo Convert to a field group. + $extra['node'][$bundle->id()]['form']['options'] = [ + 'label' => t('Promotion options'), + 'description' => $description, + 'weight' => 95, + 'region' => 'advanced', + 'visible' => TRUE, + ]; } return $extra; diff --git a/core/modules/node/src/NodeForm.php b/core/modules/node/src/NodeForm.php index bb58377..3f4cc1a 100644 --- a/core/modules/node/src/NodeForm.php +++ b/core/modules/node/src/NodeForm.php @@ -97,20 +97,17 @@ public function form(array $form, FormStateInterface $form_state) { $form = parent::form($form, $form_state); - $form['advanced']['#attributes']['class'][] = 'entity-meta'; - // Node author information for administrators. + // @todo Convert to a field group. $form['author'] = array( '#type' => 'details', '#title' => t('Authoring information'), - '#group' => 'advanced', '#attributes' => array( 'class' => array('node-form-author'), ), '#attached' => array( 'library' => array('node/drupal.node'), ), - '#weight' => 90, '#optional' => TRUE, ); @@ -123,17 +120,16 @@ public function form(array $form, FormStateInterface $form_state) { } // Node options for administrators. + // @todo Convert to a field group. $form['options'] = array( '#type' => 'details', '#title' => t('Promotion options'), - '#group' => 'advanced', '#attributes' => array( 'class' => array('node-form-options'), ), '#attached' => array( 'library' => array('node/drupal.node'), ), - '#weight' => 95, '#optional' => TRUE, ); @@ -145,8 +141,6 @@ public function form(array $form, FormStateInterface $form_state) { $form['sticky']['#group'] = 'options'; } - $form['#attached']['library'][] = 'node/form'; - $form['#entity_builders']['update_status'] = '::updateStatus'; return $form; @@ -178,6 +172,7 @@ function updateStatus($entity_type_id, NodeInterface $node, array $form, FormSta */ protected function actions(array $form, FormStateInterface $form_state) { $element = parent::actions($form, $form_state); + $element['#group'] = 'footer'; $node = $this->entity; $preview_mode = $node->type->entity->getPreviewMode(); diff --git a/core/modules/node/templates/layout--node-edit-form.html.twig b/core/modules/node/templates/layout--node-edit-form.html.twig new file mode 100644 index 0000000..3e2097d --- /dev/null +++ b/core/modules/node/templates/layout--node-edit-form.html.twig @@ -0,0 +1,31 @@ +{# +/** + * @file + * Default theme implementation to display a two-column layout. + * + * Available variables: + * - content: The content for this layout. + * - attributes: HTML attributes for the layout