A volte quando provo ad applicare un hook, solo per rendermi conto che dovrebbe essere in un file del modulo.
C'è un modo per sapere quali hook possono essere implementati nel file template.php di un tema o uno in un modulo?
A volte quando provo ad applicare un hook, solo per rendermi conto che dovrebbe essere in un file del modulo.
C'è un modo per sapere quali hook possono essere implementati nel file template.php di un tema o uno in un modulo?
Risposte:
In generale, solo i hook di modifica possono essere implementati per temi, il che significa hook come hook_form_alter()
e hook_menu_alter()
, o in breve, tutti gli hook che vengono invocati drupal_alter()
in Drupal 7 e inferiori ( ModuleHandler()::alter()
o ThemeManager::alter()
in Drupal 8).
Altri hook, che sono invocati da module_invoke_all()
( ModuleHandler::invokeAll()
in Drupal 8), non vengono richiamati per i temi semplicemente perché il codice non controlla se il tema attualmente abilitato definisce alcun 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;
}
}
}
In Drupal 8, dove la ModuleHandler
classe invoca hook implementati dai moduli e la ThemeManager
classe richiama hook implementati dai temi, solo la prima classe implementa invoke()
e invokeAll()
. Ciò significa che in Drupal 8 gli hook dei temi non sono richiamati, dal core di Drupal.
Questo è valido per i core hook di Drupal, e soprattutto per tutti i hook utilizzati dai moduli di terze parti. Spetta quindi a un modulo verificare che un hook sia implementato anche da un tema e invocarlo. Questo è ciò che fa il modulo 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);
}
Per gli hook utilizzati da moduli di terze parti, è necessario controllare il codice utilizzato per richiamarli. È probabile che vengano invocati solo temi hook per i temi, ma in alcuni casi anche altri hook possono essere implementati dai temi.
Tieni presente che nel caso dei temi, non tutti i temi abilitati vengono controllati per implementazioni hook, contrariamente a quanto accade con i moduli. Vengono controllati solo il tema attualmente utilizzato e i temi di base, come fatto dal modulo Viste.
theme()
). Se non è stato inizializzato, nessun hook di modifica in nessun tema verrà eseguito.
theme()
non cambia il tema utilizzato per la pagina, ma invoca una funzione per il rendering dei dati. Non cambia il tema, ad esempio, da Garland a Minelli.
drupal_alter()
, vedi che invoca alter-hook nel tema solo se è drupal_theme_initialize()
stato chiamato prima. In caso contrario, non esiste un tema attivo (ancora) e quindi non vengono chiamati hook. Almeno in D7 non c'è garanzia quando drupal_theme_initialize()
viene chiamato la prima volta in una richiesta.