Czasami, gdy próbuję zastosować hak, po prostu zdaję sobie sprawę, że powinien on znajdować się w pliku modułu.
Czy istnieje sposób, aby dowiedzieć się, jakie haki można zaimplementować w pliku template.php kompozycji lub w module?
Czasami, gdy próbuję zastosować hak, po prostu zdaję sobie sprawę, że powinien on znajdować się w pliku modułu.
Czy istnieje sposób, aby dowiedzieć się, jakie haki można zaimplementować w pliku template.php kompozycji lub w module?
Odpowiedzi:
Ogólnie rzecz biorąc, tylko haki alter mogą być implementowane przez motywy, co oznacza haki podobne hook_form_alter()
i hook_menu_alter()
, lub w skrócie, wszystkie haki, które są wywoływane drupal_alter()
w Drupal 7 i niższych ( ModuleHandler()::alter()
lub ThemeManager::alter()
w Drupal 8).
Inne haki, które są wywoływane przez module_invoke_all()
( ModuleHandler::invokeAll()
w Drupal 8), nie są wywoływane dla motywów po prostu dlatego, że kod nie sprawdza, czy aktualnie włączony motyw definiuje jakiś haczyk.
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;
}
}
}
W Drupal 8, gdzie ModuleHandler
klasa wywołuje haki zaimplementowane z modułów, a ThemeManager
klasa wywołuje haki zaimplementowane przez kompozycje, tylko narzędzia pierwszej klasy invoke()
i invokeAll()
. Oznacza to, że w temacie Drupal 8 nie są wywoływane haki przez rdzeń Drupala.
Dotyczy to haków rdzeniowych Drupal, a przede wszystkim wszystkich haków używanych przez moduły innych firm. Następnie do modułu należy sprawdzenie, czy haczyk jest zaimplementowany przez motyw i wywołanie go. To właśnie robi moduł Widoki.
// 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);
}
W przypadku haków używanych przez moduły innych firm należy sprawdzić kod użyty do ich wywołania. Istnieje prawdopodobieństwo, że przy motywach wywoływane są tylko zaczepy alter, ale w niektórych przypadkach motywy mogą również implementować inne zaczepy.
Należy pamiętać, że w przypadku motywów nie wszystkie włączone motywy są sprawdzane pod kątem implementacji przechwytywania, w przeciwieństwie do modułów. Sprawdzane są tylko aktualnie używane motywy i motywy podstawowe, jak to zrobiono z modułu Widoki.
theme()
). Jeśli nie został zainicjowany, żadne haczyki alter w żadnym motywie nie zostaną wykonane.
theme()
nie zmienia kompozycji użytej dla strony, ale wywołuje funkcję renderowania danych. Nie zmienia motywu, na przykład z Garland na Minelli.
drupal_alter()
, zobaczysz, że wywołuje on zmiany w motywie tylko wtedy, gdy drupal_theme_initialize()
był wcześniej wywoływany. Jeśli tak nie było, to nie ma jeszcze aktywnego motywu (a zatem), dlatego nie ma żadnych wywoływanych haków. Przynajmniej w D7 nie ma gwarancji, kiedy drupal_theme_initialize()
zostanie wywołany po raz pierwszy w żądaniu.