Тематические хуки против модульных хуков


10

Иногда, когда я пытаюсь применить хук, просто чтобы понять, что он должен быть в файле модуля.

Есть ли способ узнать, какие хуки могут быть реализованы в файле template.php темы или в модуле?


4
Обычно, когда хук недоступен для переопределения в теме, это не зря. Темы должны быть только для кода, относящегося к отображению контента и функциональных возможностей, которые предоставляют модули. Код, который добавляет / удаляет / изменяет функциональность или контент, обычно должен находиться в модуле. Также подумайте о том, что если вы меняете темы, вы теряете любые настройки, сделанные в template.php, поэтому, если вы вносите изменения, которые вы, вероятно, захотите сохранить, если вы когда-либо меняли темы, то это определенно захочет добавить в модуль.
Роби

Ответы:


11

Вообще говоря, изменять только крючки могут быть реализованы с помощью тем, что означает , как крючки hook_form_alter()и hook_menu_alter(), или короче все те крючки, которые вызываются через drupal_alter()в Drupal 7 и ниже ( ModuleHandler()::alter()или ThemeManager::alter()в Drupal 8).

Другие хуки, которые вызываются module_invoke_all()( ModuleHandler::invokeAll()в Drupal 8), не вызываются для тем просто потому, что код не проверяет, определяет ли текущая активированная тема какой-либо хук.

  foreach (module_implements($hook) as $module) {
    $function = $module . '_' . $hook;
    if (function_exists($function)) {
      $result = call_user_func_array($function, $args);
      if (isset($result) && is_array($result)) {
        $return = array_merge_recursive($return, $result);
      }
      elseif (isset($result)) {
        $return[] = $result;
      }
    }
  }

В Drupal 8, где ModuleHandlerкласс вызывает хуки, реализованные из модулей, а ThemeManagerкласс вызывает хуки, реализованные темами, только первый класс реализует invoke()и invokeAll(). Это означает, что в Drupal 8 тема хуков не вызывается ядром Drupal.

Это справедливо для хуков ядра Drupal, и в основном всех хуков, используемых сторонними модулями. Затем модуль должен проверить, реализован ли хук темой, и вызвать его. Это то, что делает модуль Views.

  // Let modules modify the view just prior to rendering it.
  foreach (module_implements('views_pre_render') as $module) {
    $function = $module . '_views_pre_render';
    $function($this);
  }

  // Let the themes play too, because pre render is a very themey thing.
  foreach ($GLOBALS['base_theme_info'] as $base) {
    $function = $base->name . '_views_pre_render';
    if (function_exists($function)) {
      $function($this);
    }
  }
  $function = $GLOBALS['theme'] . '_views_pre_render';
  if (function_exists($function)) {
    $function($this);
  }

Для хуков, используемых сторонними модулями, вам необходимо проверить код, используемый для их вызова. Скорее всего, для тем вызываются только альтернативные хуки, но в некоторых случаях и другие хуки могут быть реализованы темами.
Имейте в виду, что в случае тем не все включенные темы проверяются на реализации ловушек, в отличие от того, что происходит с модулями. Проверяются только используемая в данный момент тема и базовые темы, как это сделано в модуле Views.


hook_entity_view_alter () не работает в темах.
dxvargas

По крайней мере, в D7 alter-hooks в темах вызываются только в том случае, если тема уже была инициализирована в том же запросе (т. Е. Путем вызова theme()). Если он не был инициализирован, никакие альтер-хуки в любой теме не будут выполняться.
zwirbeltier

@zwirbeltier Хуки тем вызываются для темы, используемой для отображения страницы. theme()не меняет тему, используемую для страницы, но вызывает функцию для визуализации данных. Это не меняет тему, например, с Гарланда на Минелли.
kiamlaluno

@kiamlaluno: Если вы посмотрите на код, drupal_alter()то увидите, что он вызывает альтер-хуки в теме, только если он drupal_theme_initialize()был вызван ранее. Если это не так, то нет активной темы (пока) и, следовательно, не вызывается хуков. По крайней мере, в D7 нет гарантии, когда drupal_theme_initialize()вызывается первый раз в запросе.
zwirbeltier

@zwirbeltier Набор тем из Drupal уже инициализируется при визуализации страницы. Если модуль устанавливает тему для страницы без вызова соответствующей функции, его обязанность - инициализировать ее.
kiamlaluno
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.