Далі веб розробнику потрібно використати hook_field_formatter_settings_form() - тепер це FormatterInterface::settingsForm(). Фактично це так і залишилась простою формою. Єдине, що можна підкреслити, це те, що налаштування форматтера доступні викликом $this->getSetting(‘settings_key’). Також зміни торкнулися і таких хуків, як hook_field_formatter_prepare_view() - тепер вони виглядають так: FormatterInterface::prepareView() та hook_field_formatter_view() - FormatterInterface::viewElements(). Крім того, методи тепер отримають значення поля як об’єкта \Drupal\Core\Field\FieldItemListInterface - раніше це був простий масив $items. Більше про це можна прочитати в темі Drupal 8 Entity API.
Що ж стосується хуків-альтерів, то вони залишилися незмінними - hook_field_formatter_settings_summary_alter(), hook_field_formatter_info_alter() та hook_field_formatter_settings_form_alter().
Наступним кроком буде створення власного віджету. Тут роботи буде дещо більше, ніж при написанні форматтера. Раніше цей процес відбувався за допомогою 4-х хуків. Тепер його перенесено у методи в класах із використанням нового Plugin API. Так як і у прикладі зі створенням форматтера,hook_field_widget_info() перекочував у анотацію. Створимо файл example_module/lib/Drupal/example_module/Plugin/field/FieldWidget/ExampleWidget.php, який є аналогією до форматтера та звичайно приклад:
<?php
/**
* Plugin implementation of the 'example_widget' widget
*
* @FieldWidget(
* id = "example_widget",
* label = @Translation("Example widget"),
* field_types = {
* "text",
* "text_long"
* },
* settings = {
* "size" = "600",
* }
* )
*/
class ExampleWidget extends WidgetBase { }
Саме поняття “instance” тепер зникає; налаштування, описані в анотації, можна витягнути з $this->getSetting('settings_key') або $this->getSettings() без вказівки ключа. Якщо потрібно звернутись до інших властивостей поля, то можна скористатися методом $this->getFieldDefinition(), який вертає об’єкт \Drupal\Core\Entity\Field\FieldDefinitionInterface. Даний інтерфейс об’єднує те, що раніше розділялось і називалось $field та $instance. Наведемо приклад WidgetInterface::settingsForm():
<?php
/**
* {@inheritdoc}
*/
public function settingsForm(array $form, array &$form_state) {
$element = array();
$element['size'] = array(
'#type' => 'number',
'#title' => t('Size of textfield'),
'#default_value' => $this->getSetting('size'),
'#required' => TRUE,
'#min' => 1,
);
return $element;
}
hook_field_widget_form() стає WidgetInterface::formElement():
<?php
/**
* {@inheritdoc}
*/
public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, array &$form_state) {
$main_widget = $element + array(
'#type' => 'textfield',
'#default_value' => isset($items[$delta]->value) ? $items[$delta]->value : NULL,
'#size' => $this->getSetting('size'),
'#placeholder' => $this->getSetting('placeholder'),
'#maxlength' => $this->getSetting('max_length'),
'#attributes' => array('class' => array('text-full')),
);
if ($this->getSetting('text_processing')) {
$element = $main_widget;
$element['#type'] = 'text_format';
$element['#format'] = isset($items[$delta]->format) ? $items[$delta]->format : NULL;
$element['#base_type'] = $main_widget['#type'];
}
else {
$element['value'] = $main_widget;
}
return $element;
}
Крім того, hook_field_widget_error() було замінено на WidgetInterface::errorElement(). Також додалося декілька нових методів, таких як WidgetInterface::settingsSummary() та WidgetInterface::massageFormValues(). Інформацію про них можна прочитати на drupal.org.
Отже, можна зробити висновок, що новий Plugin API є доволі зручним інструментом для написання власного функціоналу, а саме віджетів і форматтерів. Сама будова Field API в Drupal 8 є доволі схожою до старішої версії, але уже помітний чіткий вплив об’єктно-орієнтованого програмування та PSR-0 тобто чітка розмежованість файлів по директоріях відповідно до так званих namespaces, що категоризує та групує файли у процесі розробки.