Extending EPT Settings form
Create new EPT Settings form class
I heard from many programmers worries about number of settings for EPT modules: DOM Box, background, borders, classes, etc. These programmers implied that content editors will be confused or in another way will be encouraged to do drastically different paragraphs, margins, backgrounds. Some projects needs flexibility and more settings for content editors, but some projects have pretty strict story books with components. For this case we need to change our EPT Settings field widget.
Also if you create a new EPT module and attached javascript plugin with options, you will need to use own EPT settings widget with setting fields for these options.
EPT Core module has EptSettingsDefaultWidget class for EPT Settings field widget. It contains DOM Box, background and all other settings. Let's start to create a new class EptSettingsSimpleWidget (I will put it in EPT Core module). It will contain only three settings Width, Spacing (for margin below paragraph).
Create a new file:
/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;
/**
* Plugin implementation of the 'ept_settings_simple' widget.
*
* @FieldWidget(
* id = "ept_settings_simple",
* label = @Translation("EPT simple paragraph settings"),
* 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;
}
}
We will extend our basic settings class EptSettingsDefaultWidget. In annotation comment @FieldWidget we will name our widget id = "ept_settings_simple" and label = @Translation("EPT Simple settings")
/**
* Plugin implementation of the 'ept_settings_simple' widget.
*
* @FieldWidget(
* id = "ept_settings_simple",
* label = @Translation("EPT simple paragraph settings"),
* field_types = {
* "ept_settings"
* }
* )
*/
We also have two method formElement(), massageFormValues(). You can leave massageFormValues() as it is. Drupal will automatically serialize all settings in one field field_ept_settings. So it doesn't matter how many settings you have, they will store as serialized array and you need only specify settings fields with Form API:
https://www.drupal.org/docs/drupal-apis/form-api
In formElement(), we will define setting fields. Let's hide DOM Box and border settings:
/**
* {@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;
}
If you apply new field widget for one of your EPT paragraph types:

You will see smaller settings form:

Now we will remove background settings too. If you need background settings and don't need all other settings, you can extend EptSettingsDefaultWidget class and create own field widget. Here is example how to make EPT Settings small as possible.
...
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']);
...
Our form is already have only two settings:

It's remaining only to add Spacing field for adding margin to the bottom. We will use additional classes and CSS to organize spacings:
spacing-none
,
spacing-sm
,
spacing-md
,
spacing-lg
,
spacing-xl
,
spacing-xxl
Maybe you will need for larger list of spacing, feel free to extend EptSettingsSimpleWidget class and create own field widget class from it as we did with EptSettingsDefaultWidget class.
$element['ept_settings']['design_options']['other_settings']['spacing'] = [
'#type' => 'select',
'#title' => $this->t('Background Image Style'),
'#options' => [
'spacing-none' => $this->t('None'),
'spacing-sm' => $this->t('Small'),
'spacing-md' => $this->t('Medium'),
'spacing-lg' => $this->t('Large'),
'spacing-xl' => $this->t('Extra Large'),
'spacing-xxl' => $this->t('Double Extra Large'),
],
'#default_value' => $items[$delta]->ept_settings['design_options']['other_settings']['spacing'] ?? 'spacing-none',
];
Now I see three ways to add styles for our block:
1. Override block template and set spacing there as block class.
2. Generate styles on fly and include them as custom CSS styles for each paragraph.
3. Add class with javascript by generating custom javascript for each EPT paragraph.
4. Override list of classes in template_preprocess_block() function.
All of this approaches will work, but I think it will be easier to use template_process_paragraph() function. At least we already have ept_core_preprocess_block() function in ebt_core.module file. Let's use it:
...
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'];
}
...


Now we pass Spacing field keys as class names and we will use CSS to define value for margins based on these classes:
/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;
}
You can override values in your custom CSS file, for example using any class from content or body tag:
body .spacing-sm {
margin-bottom: 15px;
}
And you can override list of spacings in your custom class for EBT settings field widget.
That's it, now you can choose between DOM Box and plain select box for setting margins for your EBT blocks.
Feel free to ask about EBT modules on Drupal.org or contact form: