Parfois, lorsque j'essaie d'appliquer un hook, juste pour réaliser qu'il est censé être dans un fichier de module.
Existe-t-il un moyen de savoir quels crochets peuvent être implémentés dans le fichier template.php d'un thème ou dans un module?
Parfois, lorsque j'essaie d'appliquer un hook, juste pour réaliser qu'il est censé être dans un fichier de module.
Existe-t-il un moyen de savoir quels crochets peuvent être implémentés dans le fichier template.php d'un thème ou dans un module?
Réponses:
De manière générale, seuls les hooks alter peuvent être implémentés par des thèmes, ce qui signifie des hooks comme hook_form_alter()
et hook_menu_alter()
, ou en bref tous les hooks qui sont invoqués drupal_alter()
dans Drupal 7 et inférieurs ( ModuleHandler()::alter()
ou ThemeManager::alter()
dans Drupal 8).
D'autres hooks, qui sont invoqués par module_invoke_all()
( ModuleHandler::invokeAll()
dans Drupal 8), ne sont pas invoqués pour les thèmes simplement parce que le code ne vérifie pas si le thème actuellement activé définit un hook.
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;
}
}
}
Dans Drupal 8, où la ModuleHandler
classe invoque des hooks implémentés à partir de modules et la ThemeManager
classe invoque des hooks implémentés par des thèmes, seule la première classe implémente invoke()
et invokeAll()
. Cela signifie que dans Drupal 8, les hooks de thème ne sont pas invoqués par Drupal core.
Ceci est valable pour les hooks de base Drupal, et surtout tous les hooks utilisés par les modules tiers. Il appartient ensuite à un module de vérifier qu'un hook est également implémenté par un thème et de l'invoquer. C'est ce que fait le module Vues.
// 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);
}
Pour les hooks utilisés par des modules tiers, vous devez vérifier le code utilisé pour les appeler. Il est probable que seuls les hooks alter soient invoqués pour les thèmes, mais dans certains cas, d'autres hooks peuvent également être implémentés par les thèmes.
Gardez à l'esprit que dans le cas des thèmes, tous les thèmes activés ne sont pas vérifiés pour les implémentations de hook, contrairement à ce qui se passe avec les modules. Seuls le thème actuellement utilisé et les thèmes de base sont vérifiés, comme cela est fait à partir du module Vues.
theme()
). S'il n'a pas été initialisé, aucun crochet supplémentaire dans aucun thème ne sera exécuté.
theme()
ne change pas le thème utilisé pour la page, mais il appelle une fonction pour rendre les données. Cela ne change pas le thème, par exemple, de Garland à Minelli.
drupal_alter()
vous voyez qu'il n'invoque que des crochets alternatifs dans le thème s'il a drupal_theme_initialize()
été appelé auparavant. Si ce n'est pas le cas, il n'y a pas (encore) de thème actif et donc pas de hooks appelés. Au moins dans D7, il n'y a aucune garantie quand drupal_theme_initialize()
est appelé la première fois dans une demande.