Field API Drupal 8 - Собственные форматтеры и виджеты

11.03.2014
Share on FacebookShare on TwitterShare on GooglePlusShare on Linkedin
Автор:

В Drupal 8 кардинально изменился процесс создания собственных форматтеров и виджетов. Если в Drupal 7 это можно было сделать с помощью хуков, то в новой версии этот процесс больше похож на написание Ctools плагинов. Далее в этом блоге мы расскажем почему. 

В Drupal 8 вместо хуков появились методы классов, и это фактически означает, что главный файл модуля .module может быть даже пустым. Применение классов предусматривает наследование. Например, это четко можно заметить в ядре восьмерки (image форматтер наследует file форматтер). Далее, рассмотрим создание собственного форматтера для поля.

Сначала веб разработчику нужно создать папку для плагинов в модуле, теперь все они (форматтер, виджеты и др.) размещаются в отдельных файлах. Путь будет примерно таким:

example_module/lib/Drupal/example_module/Plugin/field/FieldFormatter/ExampleFormatter.php

Большое количество директорий является неизменным атрибутом стандарта PSR-0. На drupal.org существует целая тема, посвященная обсуждению этого, а также подобного ему стандарта PSR-4 и их актуальности.

В Drupal 7 создание собственного форматтера начиналось с hook_field_formatter_info() - в новой же версии большинство (если не все) инфо-хуки заменены аннотациями. В данном случае используется аннотационный класс \Drupal\ field\ Annotation\ FieldFormatter. Приведем пример плагин-стайл форматтера:


Далее нужно использовать 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, которые категоризируют и группируют файлы в процессе разработки.

1 vote, Rating: 5
Share on FacebookShare on TwitterShare on GooglePlusShare on Linkedin

Также по теме

1

Продолжая рассмотрение возможностей модуля Panels, в этом блоге речь пойдет о создании собственного контекста с помощью Chaos tool suite.

2

Поддержка транзакций появилась уже в Drupal 7, включая те базы данных, которые самостоятельно их не поддерживают. Давайте рассмотрим как правильно их использовать,...

3

Модуль Migrate позволяет импортировать содержимое сайта в Drupal из других источников. Узнайте как установить и настроить этот инструмент для корректной работы.

4

В этой статье речь пойдёт о том, как установить ядро Drupal 8 как сабмодуль. Мы не будем рассматривать само понятие сабмодулей, их преимущества/недостатки, а лишь покажем в деталях, как подобную...

5

Не так давно мы рассматривали, как создать ctools тип контента для модуля Panels. На этот раз пришел черед другого...

Need a quote? Let's discuss the project

Are you looking for someone to help you with your Drupal Web Development needs? Let’s get in touch and discuss the requirements of your project. We would love to hear from you.

Join the people who have already subscribed!

Want to be aware of important and interesting things happening? We will inform you about new blog posts on Drupal development, design, QA testing and more, as well news about Drupal events.

No charge. Unsubscribe anytime