Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Плагины

Плагин — класс, который добавляет в систему ещё один вариант чего-либо: ещё один блок, ещё один способ вывести поле, ещё один фильтр текста. Блок из прошлого урока — плагин. Все плагины устроены одинаково, поэтому, поняв один вид, легко писать остальные.

Как Drupal находит плагины

У каждого вида плагинов есть три вещи:

  • папка внутри src/Plugin, где лежат классы;
  • атрибут с описанием: машинное имя, название;
  • базовый класс с методами, которые нужно реализовать.

Регистрировать плагин в файлах YAML не нужно. При drush cr Drupal просматривает папки src/Plugin всех модулей и запоминает классы с подходящим атрибутом.

Форматтер поля

Форматтер решает, как вывести значение поля. Напишем форматтер, который вместо текста статьи показывает время чтения. Его папка — src/Plugin/Field/FieldFormatter. Создайте её и файл вручную:

// web/modules/custom/blog/src/Plugin/Field/FieldFormatter/ReadingTimeFormatter.php
namespace Drupal\blog\Plugin\Field\FieldFormatter;
 
use Drupal\Core\Field\Attribute\FieldFormatter;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\FormatterBase;
use Drupal\Core\StringTranslation\TranslatableMarkup;
 
#[FieldFormatter(
    id: 'blog_reading_time',
    label: new TranslatableMarkup('Время чтения'),
    field_types: ['text_with_summary', 'text_long'],
)]
class ReadingTimeFormatter extends FormatterBase
{
    public function viewElements(FieldItemListInterface $items, $langcode): array
    {
        $elements = [];
 
        foreach ($items as $delta => $item) {
            $minutes = \Drupal::service('blog.reading_time')->minutes((string) $item->value);
 
            $elements[$delta] = [
                '#markup' => $this->t('Время чтения: @min мин.', ['@min' => $minutes]),
            ];
        }
 
        return $elements;
    }
}

В атрибуте field_types перечислены типы полей, для которых форматтер подходит: длинный текст и текст с анонсом. Метод viewElements() получает все значения поля и возвращает массив вывода для каждого. Время считает сервис blog.reading_time из урока о сервисах. Для краткости он получен статически; в настоящем коде его передают через create(), как в блоке.

Использование

Выполните drush cr и откройте «Структура → Типы материалов → Статья → Управление отображением». В строке поля Body в списке «Формат» появится вариант «Время чтения». Выберите его для режима «Анонс» и сохраните — в списке /blog под заголовком статьи вместо текста будет строка вроде «Время чтения: 3 мин.».

Атрибуты и аннотации

До Drupal 10.2 плагины описывали не атрибутами, а аннотациями — особыми комментариями над классом:

// web/modules/custom/blog/src/Plugin/Field/FieldFormatter/ReadingTimeFormatter.php
 
/**
 * @FieldFormatter(
 *   id = "blog_reading_time",
 *   label = @Translation("Время чтения"),
 *   field_types = {"text_with_summary", "text_long"}
 * )
 */
class ReadingTimeFormatter extends FormatterBase
{
}

Эта запись делает то же, что атрибут выше. В старых примерах и модулях вы встретите именно её. В Drupal 10 и 11 аннотации пока работают, но новый код пишут с атрибутами.

Виды плагинов

ПлагинПапка в src/PluginДля чего
BlockBlockБлоки
FieldFormatterField/FieldFormatterВывод значения поля
FieldWidgetField/FieldWidgetПоле ввода в форме редактирования
FieldTypeField/FieldTypeНовый тип поля
FilterFilterФильтр текстового формата
QueueWorkerQueueWorkerОбработчик очереди задач
ConditionConditionУсловие показа блоков

Заготовку любого из них создаёт Drush: drush generate показывает список, например drush generate plugin:field:formatter.

Частая ошибка

Плагин не находится, если путь к файлу не соответствует виду плагина: форматтер, положенный в src/Plugin/FieldFormatter или src/Field/FieldFormatter, Drupal не увидит — нужна именно src/Plugin/Field/FieldFormatter. Вторая причина — совпадающий id: два плагина с одним машинным именем затирают друг друга. Начинайте id с имени модуля.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.