Расширение формы настроек EPT
Создание нового класса формы настроек EPT
Я слышал от многих программистов опасения по поводу большого количества настроек для модулей EPT: DOM Box, фон, границы, классы и т.д. Эти разработчики подразумевали, что редакторы контента будут запутываться или иначе подталкиваться к созданию радикально разных абзацев, отступов, фонов. Некоторые проекты требуют гибкости и большего числа настроек для редакторов контента, а в других проектах используются достаточно строгие гайдлайны с компонентами. В таких случаях нужно изменить виджет поля настроек EPT.
Также, если вы создаёте новый модуль EPT и подключаете javascript-плагин с опциями, вам потребуется использовать собственный виджет настроек EPT с полями для этих опций.
В ядре модуля EPT есть класс EptSettingsDefaultWidget для виджета поля настроек EPT. Он включает DOM Box, фон и все остальные настройки. Давайте создадим новый класс EptSettingsSimpleWidget (я размещу его в ядре модуля EPT). В нём будут только три настройки: ширина и отступ (spacing, для отступа под абзацем).
Создайте новый файл:
/src/Plugin/Field/FieldWidget/EptSettingsSimpleWidget.php
<?php
namespace Drupal\ept_core\Plugin\Field\FieldWidget;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Component\Utility\Color;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\ept_core\Plugin\Field\FieldWidget\EptSettingsDefaultWidget;
/**
* Реализация плагина виджета 'ept_settings_simple'.
*
* @FieldWidget(
* id = "ept_settings_simple",
* label = @Translation("EPT простые настройки абзаца"),
* field_types = {
* "ept_settings"
* }
* )
*/
class EptSettingsSimpleWidget extends EptSettingsDefaultWidget {
/**
* {@inheritdoc}
*/
public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
$element = parent::formElement($items, $delta, $element, $form, $form_state);
return $element;
}
/**
* {@inheritdoc}
*/
public function massageFormValues(array $values, array $form, FormStateInterface $form_state) {
foreach ($values as &$value) {
$value += ['ept_settings' => []];
}
return $values;
}
}
Мы расширяем базовый класс настроек EptSettingsDefaultWidget. В аннотации @FieldWidget указываем id = "ept_settings_simple" и label = @Translation("EPT Simple settings").
/**
* Реализация плагина виджета 'ept_settings_simple'.
*
* @FieldWidget(
* id = "ept_settings_simple",
* label = @Translation("EPT простые настройки абзаца"),
* field_types = {
* "ept_settings"
* }
* )
*/
Также реализованы два метода formElement() и massageFormValues(). Метод massageFormValues() можно оставить как есть. Drupal автоматически сериализует все настройки в одно поле field_ept_settings, поэтому неважно, сколько настроек у вас есть — они будут храниться как сериализованный массив, и вам нужно лишь указать поля настроек через Form API:
https://www.drupal.org/docs/drupal-apis/form-api
В методе formElement() мы определим поля настроек. Спрячем настройки DOM Box и границ:
/**
* {@inheritdoc}
*/
public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
$element = parent::formElement($items, $delta, $element, $form, $form_state);
unset($element['ept_settings']['design_options']['box1']);
unset($element['ept_settings']['design_options']['other_settings']['border_color']);
unset($element['ept_settings']['design_options']['other_settings']['border_style']);
unset($element['ept_settings']['design_options']['other_settings']['border_radius']);
return $element;
}
Если вы примените новый виджет для одного из ваших типов параграфов EPT:

Вы увидите более компактную форму настроек:

Теперь уберём и настройки фона. Если вам нужны только настройки фона, а остальные не нужны — расширьте EptSettingsDefaultWidget и создайте свой виджет. Вот пример, как сделать настройки EPT максимально простыми.
...
unset($element['ept_settings']['design_options']['other_settings']['background_color']);
unset($element['ept_settings']['design_options']['other_settings']['background_media']);
unset($element['ept_settings']['design_options']['other_settings']['background_image_style']);
...
В нашей форме теперь осталось только два поля:

Осталось добавить поле Spacing для задания отступа снизу. Для этого мы используем дополнительные CSS-классы для управления отступами:
spacing-none
,
spacing-sm
,
spacing-md
,
spacing-lg
,
spacing-xl
,
spacing-xxl
Если потребуется больший список значений отступа — расширяйте EptSettingsSimpleWidget и создавайте собственный класс виджета, как мы делали с EptSettingsDefaultWidget.
$element['ept_settings']['design_options']['other_settings']['spacing'] = [
'#type' => 'select',
'#title' => $this->t('Background Image Style'),
'#options' => [
'spacing-none' => $this->t('Нет'),
'spacing-sm' => $this->t('Маленький'),
'spacing-md' => $this->t('Средний'),
'spacing-lg' => $this->t('Большой'),
'spacing-xl' => $this->t('Очень большой'),
'spacing-xxl' => $this->t('Двойной очень большой'),
],
'#default_value' => $items[$delta]->ept_settings['design_options']['other_settings']['spacing'] ?? 'spacing-none',
];
Теперь вижу три способа добавить стили для нашего блока:
1. Переопределить шаблон блока и добавить класс отступа прямо в классы блока.
2. Генерировать стили на лету и добавлять их как inline-стили для каждого параграфа.
3. Добавлять класс через javascript, генерируя отдельный скрипт для каждого параграфа EPT.
4. Переопределить список классов в функции template_preprocess_block().
Все эти подходы рабочие, но проще всего использовать функцию template_process_paragraph(). К тому же в файле ebt_core.module уже есть функция ept_core_preprocess_block(). Используем её:
...
if (!empty($ept_settings[0]['ept_settings']['design_options']['other_settings']['spacing'])) {
$variables['attributes']['class'][] = $ept_settings[0]['ept_settings']['design_options']['other_settings']['spacing'];
}
...


Теперь мы передаём ключи поля Spacing как имена классов, и с помощью CSS задаём нужные значения отступов для этих классов:
/ebt_core/scss/ept_core.scss
.spacing-sm {
margin-bottom: 10px;
}
.spacing-md {
margin-bottom: 20px;
}
.spacing-lg {
margin-bottom: 30px;
}
.spacing-xl {
margin-bottom: 40px;
}
.spacing-xxl {
margin-bottom: 50px;
}
Вы можете переопределять эти значения в своём CSS, например так, используя любой класс из контента или body:
body .spacing-sm {
margin-bottom: 15px;
}
Также можно переопределить список вариантов отступа в своём классе виджета настроек EBT.
Вот и всё, теперь вы можете выбирать между DOM Box и простым select для задания отступов для ваших EBT-блоков.
Если есть вопросы по модулям EBT — задавайте их на Drupal.org или через контактную форму: