Encodera

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

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

Оглавление

Хуки

Хук — место в ядре или чужом модуле, куда ваш модуль может добавить свой код. Drupal в определённый момент — перед сохранением материала, перед выводом формы — спрашивает все включённые модули, хотят ли они вмешаться. Так поведение сайта меняют, не правя чужие файлы.

Где пишут хуки

Хук — обычная функция в файле blog.module в корне папки модуля. Файл появился в уроке о шаблонах: функция blog_theme() в нём — тоже хук. Имя функции строится по правилу «имя модуля, подчёркивание, имя хука».

Первый хук

Хук hook_entity_presave вызывается перед сохранением любой сущности. Уберём лишние пробелы в заголовках статей:

// web/modules/custom/blog/blog.module
 
use Drupal\Core\Entity\EntityInterface;
use Drupal\node\NodeInterface;
 
/**
 * Implements hook_entity_presave().
 */
function blog_entity_presave(EntityInterface $entity): void
{
    if ($entity instanceof NodeInterface && $entity->bundle() === 'article') {
        $entity->setTitle(trim($entity->getTitle()));
    }
}

Слово hook в названии заменено именем модуля: hook_entity_presave стал blog_entity_presave. Выполните drush cr, создайте статью с пробелами в начале заголовка — после сохранения их не будет. Комментарий Implements hook_… — принятое соглашение, оно помогает искать хуки в коде.

Изменение чужой формы

Хук hook_form_alter вызывается перед выводом каждой формы сайта:

// web/modules/custom/blog/blog.module
 
use Drupal\Core\Form\FormStateInterface;
 
/**
 * Implements hook_form_alter().
 */
function blog_form_alter(array &$form, FormStateInterface $form_state, string $form_id): void
{
    if ($form_id === 'node_article_form') {
        $form['title']['widget'][0]['value']['#description'] = t('Не длиннее 60 знаков.');
    }
}

Под полем заголовка на форме создания статьи /node/add/article появится подсказка. Массив формы приходит по ссылке — знак & перед $form, — поэтому хук меняет его на месте и ничего не возвращает. Идентификатор формы виден в её HTML-коде, в атрибуте id тега form, только с дефисами вместо подчёркиваний.

Частые хуки

ХукКогда вызывается
hook_theme()Объявление своих шаблонов
hook_form_alter()Перед выводом любой формы
hook_form_FORM_ID_alter()Перед выводом одной конкретной формы
hook_entity_presave()Перед сохранением сущности
hook_entity_insert(), hook_entity_update()После создания и после изменения
hook_entity_delete()После удаления
hook_preprocess_HOOK()Перед выводом шаблона: подготовка переменных
hook_page_attachments()Подключение библиотек ко всем страницам
hook_cron()При запуске планировщика

Заглавные буквы в названии заменяют конкретным значением: hook_form_FORM_ID_alter для формы статьи — это blog_form_node_article_form_alter.

Где искать хуки

Все хуки ядра описаны в файлах с окончанием .api.php, например web/core/lib/Drupal/Core/Entity/entity.api.php. В них перечислены аргументы и приведён пример. Эти файлы не выполняются, они служат документацией.

Хуки в классах

Начиная с Drupal 11.1 хук можно написать методом класса с атрибутом — без файла blog.module:

// web/modules/custom/blog/src/Hook/BlogHooks.php
namespace Drupal\blog\Hook;
 
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Hook\Attribute\Hook;
 
class BlogHooks
{
    #[Hook('entity_presave')]
    public function entityPresave(EntityInterface $entity): void
    {
        // тот же код, что в функции
    }
}

Класс лежит в папке src/Hook, а имя хука указано в атрибуте без слова hook_. В Drupal 10 этот способ не работает, поэтому в курсе используются функции — они работают в обеих версиях.

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

Опечатка в имени функции не вызывает ошибки: blog_from_alter вместо blog_form_alter — допустимая функция PHP, которую просто никто не вызовет. Если хук «не срабатывает», сверьте имя по буквам и выполните drush cr: список хуков каждого модуля хранится в кеше, и новую функцию Drupal увидит только после его очистки.

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

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