扩展 EPT 设置表单
创建新的 EPT 设置表单类
我从许多程序员那里听到对 EPT 模块设置数量的担忧:DOM 盒(DOM Box)、背景、边框、类等。这些程序员认为内容编辑可能会被这些设置搞糊涂,或者在另一种情况下被“鼓励”去做出截然不同的段落、边距、背景。一些项目需要为内容编辑提供灵活性和更多设置,但也有一些项目拥有非常严格的组件式故事手册。针对这种情况,我们需要改变我们的 EPT Settings 字段小部件(field widget)。
另外,如果你创建了一个新的 EPT 模块并附带了带选项的 JavaScript 插件,你将需要使用你自己的 EPT 设置小部件,并为这些选项提供设置字段。
EPT Core 模块提供了用于 EPT Settings 字段小部件的 EptSettingsDefaultWidget 类。它包含 DOM 盒、背景和所有其他设置。现在让我们开始创建一个新的类 EptSettingsSimpleWidget(我会把它放在 EPT Core 模块中)。它将只包含三个设置:宽度(Width)、间距(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;
/**
* 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;
}
}
我们将扩展基础设置类 EptSettingsDefaultWidget。在注解注释 @FieldWidget 中,我们将把小部件命名为 id = "ept_settings_simple",并设置 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"
* }
* )
*/
我们还实现了两个方法:formElement()
、massageFormValues()
。你可以保持 massageFormValues()
原样。Drupal 会自动将所有设置序列化到一个字段 field_ept_settings
中。因此无论你有多少设置,它们都会以序列化数组的形式存储,你只需要使用 Form API 指定设置字段即可:
https://www.drupal.org/docs/drupal-apis/form-api
在 formElement()
中,我们将定义设置字段。让我们隐藏 DOM 盒和边框设置:
/**
* {@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 Settings 尽可能小:
...
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('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',
];
现在我想到三种(实则列了四种)为我们的区块添加样式的方法:
1. 覆盖区块模板,并在其中将 spacing 作为区块类设置。
2. 动态生成样式,并将其作为每个段落的自定义 CSS 样式引入。
3. 通过为每个 EPT 段落生成自定义 JavaScript,用 JavaScript 添加类。
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 设置字段小部件类中覆盖间距列表。
就这样,现在你可以在为 EBT 区块设置外边距时,选择使用 DOM Box 或者简单的下拉选择框。
欢迎就 EBT 模块在 Drupal.org 上提问或通过联系表单联系我: