Móc chủ đề vs móc mô-đun


10

Đô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?


4
Nói chung khi một hook không có sẵn để được ghi đè trong một chủ đề thì đó là lý do chính đáng. Chủ đề chỉ nên dành cho mã liên quan đến việc hiển thị nội dung và chức năng mà các mô-đun cung cấp. Mã thường thêm / xóa / thay đổi chức năng hoặc nội dung thường phải có trong một mô-đun. Ngoài ra, hãy nghĩ về thực tế rằng nếu bạn thay đổi chủ đề, bạn sẽ mất bất kỳ tùy chỉnh nào được thực hiện trong template.php, vì vậy nếu bạn đang thực hiện các thay đổi mà bạn có thể muốn giữ nếu bạn đã thay đổi chủ đề thì điều đó chắc chắn sẽ muốn đi vào một mô-đun.
rooby

Câu trả lời:


11

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()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 đó ModuleHandlerlớp gọi các hook được triển khai từ các mô-đun và ThemeManagerlớ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()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.


hook_entity_view_alter () không hoạt động trong các chủ đề.
dxvargas

Ít nhất trong các thay đổi D7 trong các chủ đề chỉ được gọi nếu chủ đề đã được khởi tạo trong cùng một yêu cầu (ví dụ: bằng cách gọi 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.
zwirbeltier

@zwirbeltier Móc chủ đề được gọi cho chủ đề được sử dụng để hiển thị trang. 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.
kiamlaluno

@kiamlaluno: Nếu bạn nhìn vào mã trong 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.
zwirbeltier

@zwirbeltier Chủ đề được thiết lập từ Drupal đã được khởi tạo khi một trang được hiển thị. Nếu một mô-đun đặt một chủ đề cho một trang mà không gọi chức năng thích hợp, thì đó là khả năng đáp ứng của nó để khởi tạo nó.
kiamlaluno
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.