テーマフックとモジュールフック


10

フックを適用しようとするとき、それがモジュールファイル内にあることに気づくために、

テーマのtemplate.phpファイル、またはモジュールのフックに実装できるフックを知る方法はありますか?


4
一般に、テーマでフックをオーバーライドするために使用できない場合、それは正当な理由があります。テーマは、モジュールの提供するコンテンツと機能の表示に関連するコードにのみ使用してください。機能またはコンテンツを追加/削除/変更するコードは通常、モジュール内にある必要があります。また、テーマを変更すると、template.phpで行ったカスタマイズがすべて失われるため、テーマを変更した場合に維持したい変更をモジュールに追加したいということも考慮してください。
rooby

回答:


11

一般的に言って、テーマによって実装できるのは、変更フックのみです。つまり、hook_form_alter()andのような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コアでは、Drupal 8ではテーマフックは呼び出されません。

これは、Drupalコアフック、およびほとんどのサードパーティモジュールで使用されるすべてのフックに有効です。フックがテーマによって実装されていることを確認し、それを呼び出すのはモジュール次第です。これは、ビューモジュールが行うことです。

  // 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では、テーマ内の変更フックは、テーマが同じリクエストで(つまり、を呼び出すことによってtheme())初期化されている場合にのみ呼び出されます。初期化されていない場合、どのテーマの変更フックも実行されません。
zwirbeltier

@zwirbeltierテーマフックは、ページのレンダリングに使用されるテーマに対して呼び出されます。theme()ページに使用されるテーマは変更されませんが、データをレンダリングする関数を呼び出します。たとえば、ガーランドからミネリにテーマを変更することはありません。
kiamlaluno

@kiamlaluno:のコードdrupal_alter()を見るdrupal_theme_initialize()と、以前に呼び出された場合、テーマの変更フックのみを呼び出すことがわかります。そうでなければ、アクティブなテーマは(まだ)ないため、呼び出されるフックはありません。少なくともD7 drupal_theme_initialize()では、リクエストで初めて呼び出されるときに保証はありません。
zwirbeltier

@zwirbeltierページがレンダリングされるときに、Drupalからのテーマセットはすでに初期化されています。モジュールが適切な関数を呼び出さずにページのテーマを設定する場合、それを初期化するのはモジュールの責任です。
kiamlaluno
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.