Às vezes, quando tento aplicar um gancho, apenas para perceber que ele deveria estar em um arquivo de módulo.
Existe uma maneira de saber quais ganchos podem ser implementados no arquivo template.php de um tema ou em um módulo?
Às vezes, quando tento aplicar um gancho, apenas para perceber que ele deveria estar em um arquivo de módulo.
Existe uma maneira de saber quais ganchos podem ser implementados no arquivo template.php de um tema ou em um módulo?
Respostas:
De um modo geral, apenas os ganchos alternativos podem ser implementados por temas, o que significa ganchos como hook_form_alter()
e hook_menu_alter()
, ou, em resumo, todos os ganchos invocados drupal_alter()
no Drupal 7 e inferiores ( ModuleHandler()::alter()
ou ThemeManager::alter()
no Drupal 8).
Outros ganchos, chamados por module_invoke_all()
( ModuleHandler::invokeAll()
no Drupal 8), não são chamados para temas simplesmente porque o código não verifica se o tema atualmente ativado define algum gancho.
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;
}
}
}
No Drupal 8, onde a ModuleHandler
classe chama ganchos implementados a partir de módulos e a ThemeManager
classe chama ganchos implementados por temas, apenas a primeira classe implementa invoke()
e invokeAll()
. Isso significa que, no Drupal 8, os ganchos temáticos não são chamados, pelo núcleo do Drupal.
Isso é válido para os ganchos do núcleo Drupal e, principalmente, para todos os ganchos usados por módulos de terceiros. Cabe então a um módulo verificar se um gancho também é implementado por um tema e invocá-lo. É isso que o módulo Views faz.
// 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);
}
Para ganchos usados por módulos de terceiros, é necessário verificar o código usado para invocá-los. As chances são de que apenas ganchos alternativos sejam chamados para temas, mas em alguns casos também outros ganchos podem ser implementados por temas.
Lembre-se de que, no caso de temas, nem todos os temas ativados são verificados para implementações de gancho, ao contrário do que acontece com os módulos. Somente o tema atualmente usado e os temas base são verificados, conforme feito no módulo Views.
theme()
). Se não tiver sido inicializado, nenhum gancho alternativo em nenhum tema será executado.
theme()
não altera o tema usado para a página, mas invoca uma função para renderizar dados. Isso não muda o tema, por exemplo, de Garland para Minelli.
drupal_alter()
verá que ele apenas chama alter-hooks no tema se drupal_theme_initialize()
foi chamado antes. Caso contrário, não há um tema ativo (ainda) e, portanto, nenhum gancho é chamado. Pelo menos em D7, não há garantia quando drupal_theme_initialize()
é chamado pela primeira vez em uma solicitação.