Change the position of the meta data panel on the node form with Drupal 8

a car in a narrow street

Content metadata (menu settings, comment settings, publishing options, URL path parameters, publication information, etc.) are displayed by default on the node form in a side panel. This has the advantage of giving immediate visibility on these options while writing its content.

For example, our form below provides an overview of content and metadata.

Création d'une page

But there are use cases where the lateral position of this information is detrimental to the general ergonomics, because reducing the space available for the node form. This can be the case, for example, if you use the Field Group module to structure and group the information to be entered (in the form of vertical tabs for example), and even more if you use the paragraphs also organized with the Field group module.

For example, below our form has a place so small that it becomes difficult to exploit unless you have a 32-inch screen.

Création d'une article

No need here for a Drupal expert. Let's find out how we can make the position of these metadata customizable according to the needs and general ergonomics of the Drupal 8 project.

We will act at the level of the theme of administration. To do this, you will need to create an administration sub-theme that will be based on an administration theme you have chosen (the default theme seven, or the excellent theme Adminimal).

After creating your sub-theme (we've titled it bo here), you'll have a file structure that looks like this

bo
├── bo.info.yml
├── bo.libraries.yml
├── bo.theme
├── config
│   ├── install
│   │   ├── block.block.bo_breadcrumbs.yml
│   │   ├── block.block.bo_content.yml
│   │   ├── block.block.bo_help.yml
│   │   ├── block.block.bo_local_actions.yml
│   │   ├── block.block.bo_messages.yml
│   │   ├── block.block.bo_page_title.yml
│   │   ├── block.block.bo_primary_local_tasks.yml
│   │   ├── block.block.bo_secondary_local_tasks.yml
│   │   └── bo.settings.yml
│   └── schema
│       └── bo.schema.yml
├── css
│   ├── node_meta.css
│   ├── node_meta.css.map
│   ├── style.css
│   └── style.css.map
├── js
│   └── bo.js
├── less
│   ├── node_meta.less
│   └── style.less
└── theme-settings.php

We will need these particular files

  • bo.libraries.yml to declare our library and load the file node_meta.css to provide some css rules.
  • bo.theme to alter form for editing and creating content
  • theme-settings.php to provide configuration options at our sub-theme of administration

Make the metadata position parametrizable

We start by providing configuration options from the administration sub-theme. The general idea is to provide a configuration form that will look like the below capture, form that will allow us to set the position of the metadata panel according to the content types. If you have different business logic then you can of course provide these options based on it and not the content types.

formulaire de configuration au niveau du thème

To provide this configuration form, we will alter, with the theme-settings.php file, the theme settings editing form to add these options.

<?php

use Drupal\node\Entity\NodeType;
use Drupal\Core\Form\FormStateInterface;

function bo_form_system_theme_settings_alter(&$form, FormStateInterface &$form_state) {

  $form['bo_settings'] = array(
    '#type' => 'fieldset',
    '#title' => t('BO Theme Settings'),
    '#collapsible' => FALSE,
    '#collapsed' => FALSE,
  );

  $form['bo_settings']['tabs'] = array(
    '#type' => 'vertical_tabs',
    '#default_tab' => 'basic_tab',
  );
  
  $form['bo_settings']['basic_tab']['basic_settings'] = array(
    '#type' => 'details',
    '#title' => t('Basic Settings'),
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
    '#group' => 'tabs',
  );

  $form['bo_settings']['basic_tab']['basic_settings']['node_form_meta'] = array(
    '#type' => 'item',
    '#markup' => '<div class="theme-settings-title">'.t("Node form meta block position").'</div>',
  );
  
  $form['bo_settings']['basic_tab']['basic_settings']['node_form_meta'] = array(
    '#type' => 'checkbox',
    '#title' => t('Display block meta as vertical tabs'),
    '#description'   => t('Use the checkbox to display the node meta block as vertical tabs and under the main node form.'),
    '#default_value' => theme_get_setting('node_form_meta', 'bo'),
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
  );

  $options = array_map(function (NodeType $nodeType) { return $nodeType->label(); }, NodeType::loadMultiple());
  $default_value = theme_get_setting('node_form_meta_types', 'bo');
  $form['bo_settings']['basic_tab']['basic_settings']['node_form_meta_types'] = array(
    '#type' => 'checkboxes',
    '#title' => t('Select the content types'),
    '#description'   => t('Select the content type on which display the node meta block as vertical tabs and under the main node form.'),
    '#default_value' => $default_value ? array_filter($default_value) : [],
    '#options' => $options,
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
    '#states' => [
      'visible' => [
        ':input[name="node_form_meta"]' => ['checked' => TRUE],
      ],
    ]
  );

}

Alter the node form

Once these options are configured, we can now alter the node form from the bo.theme file.

/**
 * Implements hook_form_alter().
 */
function bo_form_node_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  // Set advanced settings in node form as verticals tabs.
  if (theme_get_setting('node_form_meta', 'bo')) {
    /** @var \Drupal\node\NodeInterface $node */
    $node = $form_state->getFormObject()->getEntity();
    $types_enabled = theme_get_setting('node_form_meta_types', 'bo') ? array_filter(theme_get_setting('node_form_meta_types', 'bo')): [];
    if (in_array($node->bundle(), $types_enabled)) {
      $form['advanced']['#type'] = 'vertical_tabs';
      $form['meta']['#type'] = 'details';
      $form['meta']['#title'] = t('Informations');
      $form['#attached']['library'][] = 'bo/node_meta';
    }
  }
}

There you go ! Note that we load the library bo/node_meta to provide some css override. For the snippet to be complete, you will find the node_meta.css file below.

.node-form .entity-meta details[open] {
  background-image: none;
}
.node-form .entity-meta__header,
.node-form .entity-meta details {
  border-top: 0 none transparent;
  border-bottom: 0 none transparent;
}
.node-form .entity-meta__header:first-child,
.node-form .entity-meta details:first-child {
  border-top-color: transparent;
}
@media screen and (min-width: 768px) {
  .node-form .layout-region-node-main,
  .node-form .layout-region-node-footer {
    float: inherit;
    /* LTR */
    width: 100%;
    padding-right: 0;
    /* LTR */
    box-sizing: border-box;
  }
  .node-form [dir="rtl"] .layout-region-node-main,
  .node-form [dir="rtl"] .layout-region-node-footer {
    float: inherit;
    padding-left: 0;
    padding-right: 0;
  }
  .node-form .layout-region-node-secondary {
    float: inherit;
    /* LTR */
    width: 100%;
  }
  .node-form [dir="rtl"] .layout-region-node-secondary {
    float: inherit;
  }
}

You may need to overload this library if your admin theme differs somewhat. In this case from your theme, you can add these few lines in the my_theme.info.yml file of your admin theme to overload this library.

libraries-override:
  # Replace an entire library.
  bo/node_meta: my_theme/node_meta

Where my_theme/node_meta will be your own library loading the relevant css file.

And all this allows us to position this content metadata panel according to our needs, allowing us to benefit from all the available width of the browser to improve user comfort.

Création d'un article

 

Note that this snippet is only useful if you are using the seven admin theme, or another admin theme that extends Seven (such as the adminimal theme for example). Indeed, by default this metadata panel is displayed under the main form in the form of vertical tabs. It's the Seven theme that override the display of this panel. If you do not use Seven, you should not need these snippets. Or maybe but then to do the opposite.

What if we made a module?

It is after several similar alterations on different content types that I wanted to make these options configurable. And it was while writing this blog post following a discussion during the DrupalCamp Lannion, that the idea of a small module Meta position, proposing this feature and making unnecessary this override at the level of the administration theme, came to me. This small module is very simple, but can be useful to everyone. Anyway it is a need that I meet very often, for which I will not need any more to alter the admin theme. The interest also lies for the site builders / webmasters, allowing a fine configuration in a few clicks from the configuration interface.

As we say, little brooks make great rivers.

 

Ajouter un commentaire