Ganci tematici vs ganci modulo


10

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?


4
Generalmente quando un hook non è disponibile per essere sovrascritto in un tema, è per una buona ragione. I temi dovrebbero essere solo per il codice relativo alla visualizzazione del contenuto e delle funzionalità fornite dai moduli. Il codice che aggiunge / rimuove / modifica funzionalità o contenuto di solito dovrebbe essere in un modulo. Pensa anche al fatto che se cambi temi perdi le personalizzazioni fatte in template.php, quindi se stai apportando delle modifiche che vorresti probabilmente conservare se cambiassi temi, vorrai sicuramente andare in un modulo.
Rooby,

Risposte:


11

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 ModuleHandlerclasse invoca hook implementati dai moduli e la ThemeManagerclasse 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.


hook_entity_view_alter () non funziona nei temi.
dxvargas,

Almeno in D7 gli alter-hook nei temi vengono invocati solo se il tema è già stato inizializzato nella stessa richiesta (ad es. Chiamando theme()). Se non è stato inizializzato, nessun hook di modifica in nessun tema verrà eseguito.
zwirbeltier,

@zwirbeltier Gli hook dei temi vengono richiamati per il tema utilizzato per il rendering della pagina. 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.
kiamlaluno

@kiamlaluno: se guardi il codice 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.
zwirbeltier,

@zwirbeltier Il set di temi di Drupal è già inizializzato quando viene visualizzata una pagina. Se un modulo imposta un tema per una pagina senza chiamare la funzione appropriata, è la sua responsabilità a inizializzarlo.
kiamlaluno
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.