Далее нужно использовать 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, который является аналогом форматтера, и приведем пример:
Само понятие "instance" теперь исчезает; настройки, описанные в аннотации, можно извлечь из $this->getSetting('settings_key') или $this->getSettings() без указания ключа. Если нужно обратиться к другим свойствам поля, то можно воспользоваться методом $this->getFieldDefinition(), который возвращает объект \Drupal\Core\Entity\Field\FieldDefinitionInterface. Данный интерфейс объединяет то, что ранее разделялось и называлось $field и $instance. Приведем пример WidgetInterface::settingsForm():
'number',
'#title' => t('Size of textfield'),
'#default_value' => $this->getSetting('size'),
'#required' => TRUE,
'#min' => 1,
);
return $element;
}
hook_field_widget_form() становится WidgetInterface::formElement():
'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, то есть четкую разграниченность файлов по директориям в соответствии с так называемыми namespace, которые категоризируют и группируют файлы в процессе разработки.