В Drupal 11.3 произошла важная, но не сразу заметная смена подхода к theming‑слою: классические процедурные preprocess‑функции вида template_preprocess_* были помечены как устаревшие. Это касается и template_preprocess_media(), который многие годы использовался для подготовки переменных в шаблоне media.html.twig.
Формально код продолжает работать, но начиная с 11.3 он считается deprecated и будет полностью удалён в Drupal 12. Это означает, что при разработке новых проектов и при рефакторинге старых стоит переходить на современный механизм — атрибутные хуки.
Почему template_preprocess_media() устарел
Исторически Drupal автоматически находил preprocess‑функции по имени (template_preprocess_node, template_preprocess_media и т. д.). Такой механизм был простым, но плохо масштабировался, не поддерживал DI и выбивался из общей объектно‑ориентированной архитектуры, к которой Drupal последовательно шёл последние годы.
В Drupal 11.3 core перешёл на явную регистрацию хуков через PHP‑атрибуты. Старые template_preprocess_* оставлены лишь как временные прокси и помечены как устаревшие.
Проще говоря: полагаться на них дальше нельзя.
Современная замена: атрибутный preprocess_media
Новый подход предполагает размещение логики в классе внутри модуля, в пространстве имён Drupal\<module>\Hook, и использование атрибута #[Hook].
Минимальные требования:
- код должен быть в модуле, не в теме;
- класс должен лежать в
src/Hook; - имя хука указывается строго как
preprocess_media.
Пример реализации
Ниже — рабочий пример атрибутного preprocess‑хука для media, который добавляет в шаблон переменную styled_url для image‑media в определённом view mode.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
<?php namespace Drupal\m_tweaks\Hook; use Drupal\Core\Hook\Attribute\Hook; class ThemeHooks { #[Hook('preprocess_media')] public function preprocessMedia(array &$variables): void { $media = $variables['media'] ?? NULL; $view_mode = $variables['view_mode']; if ($media && $media->bundle() == 'image') { $styled_url = NULL; if ($view_mode == '3_4_large') { $image_style = \Drupal::entityTypeManager() ->getStorage('image_style') ->load('uncropped_960w_webp'); if ($image_style) { $file = $media->field_media_image->entity; $styled_url = $image_style->buildUrl($file->getFileUri()); } } $variables['styled_url'] = $styled_url; } } } |
В данном хуке я вычисляю для media типа image дополнительный URL со стилем картинки uncropped_960w_webp. Значение сохраняется в переменной шаблона styled_url.
На что обратить внимание
Во‑первых, в контексте примера, Media — это не файл. Методов вроде getFileUri() у media‑entity не существует, путь к файлу всегда получается через source‑field (field_media_image в примере выше).
Во‑вторых, атрибутные хуки подхватываются только после полной пересборки контейнера. После добавления класса обязательно выполнить drush cr.
В‑третьих, на текущий момент (Drupal 11.3) theme registry по‑прежнему остаётся процедурным. Атрибуты — это новый слой, который постепенно вытесняет старый, но ещё не везде работает без оговорок. Тем не менее для preprocess‑хуков они уже применимы и поддерживаются core.
Если в коде всё ещё используется template_preprocess_media(), это явный сигнал к рефакторингу. В Drupal 11.3 корректный путь — атрибутный #[Hook('preprocess_media')] в классе модуля. Такой код лучше вписывается в архитектуру Drupal, легче расширяется и безболезненно переживёт переход на Drupal 12.