Đôi khi, khi tôi cố gắng áp dụng một hook, chỉ để nhận ra rằng nó phải nằm trong một tệp mô-đun.
Có cách nào để biết những hook nào có thể được thực hiện trong tệp template.php của chủ đề hoặc một hook trong mô-đun không?
Đôi khi, khi tôi cố gắng áp dụng một hook, chỉ để nhận ra rằng nó phải nằm trong một tệp mô-đun.
Có cách nào để biết những hook nào có thể được thực hiện trong tệp template.php của chủ đề hoặc một hook trong mô-đun không?
Câu trả lời:
Nói chung, chỉ các móc thay đổi có thể được triển khai theo các chủ đề, có nghĩa là các móc như hook_form_alter()
và hook_menu_alter()
hoặc nói ngắn gọn là tất cả các móc được gọi drupal_alter()
trong Drupal 7 trở xuống ( ModuleHandler()::alter()
hoặc ThemeManager::alter()
trong Drupal 8).
Các hook khác, được gọi bởi module_invoke_all()
( ModuleHandler::invokeAll()
trong Drupal 8), không được gọi cho các chủ đề đơn giản vì thực tế mã không kiểm tra xem chủ đề hiện được kích hoạt có xác định bất kỳ hook nào không.
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;
}
}
}
Trong Drupal 8, trong đó ModuleHandler
lớp gọi các hook được triển khai từ các mô-đun và ThemeManager
lớp gọi các hook được thực hiện theo các chủ đề, chỉ có lớp đầu tiên thực hiện invoke()
và invokeAll()
. Điều này có nghĩa là trong móc chủ đề Drupal 8 không được gọi, bởi lõi Drupal.
Điều này hợp lệ cho các móc lõi Drupal và hầu hết tất cả các móc được sử dụng bởi các mô-đun của bên thứ ba. Sau đó, một mô-đun để xác minh một hook cũng được thực hiện bởi một chủ đề và gọi nó. Đây là những gì mô-đun Views làm.
// 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);
}
Đối với các hook được sử dụng bởi các mô-đun của bên thứ ba, bạn cần kiểm tra mã được sử dụng để gọi chúng. Có thể chỉ các móc thay đổi được gọi cho các chủ đề, nhưng trong một số trường hợp, các móc khác cũng có thể được thực hiện theo các chủ đề.
Hãy nhớ rằng trong trường hợp chủ đề, không phải tất cả các chủ đề được kích hoạt đều được kiểm tra để triển khai hook, trái với những gì xảy ra với các mô-đun. Chỉ chủ đề hiện đang được sử dụng và chủ đề cơ sở được kiểm tra, như được thực hiện từ mô-đun Lượt xem.
theme()
). Nếu nó chưa được khởi tạo, không có móc thay đổi nào trong bất kỳ chủ đề nào sẽ được thực thi.
theme()
không thay đổi chủ đề được sử dụng cho trang, nhưng nó gọi một chức năng để hiển thị dữ liệu. Nó không thay đổi chủ đề, ví dụ, từ Garland sang Minelli.
drupal_alter()
bạn thấy rằng nó chỉ gọi các hook-hook trong chủ đề nếu drupal_theme_initialize()
được gọi trước đó. Nếu không, thì không có chủ đề hoạt động (chưa) và do đó không có hook được gọi. Ít nhất trong D7 không có gì đảm bảo khi drupal_theme_initialize()
được gọi lần đầu tiên trong một yêu cầu.