it-swarm-vi.com

Tôi nên triển khai hook_menu () như thế nào?

Các nguyên tắc cơ bản của việc thực hiện hook_menu() là gì?

Tôi muốn thấy những điều cơ bản được đề cập trong một câu hỏi duy nhất, để tránh phải trả lời những câu hỏi tương tự nhưng khác nhau lặp đi lặp lại.

102
Letharion

Thông tin này có giá trị cho Drupal 6 và 7. Trong Drupal 8, hook_menu() đã được thay thế bởi hệ thống định tuyến mới . Dưới đây chúng tôi triển khai hook_menu() trong ba bước đơn giản.

Bước một

Tạo mô-đun trống theo hướng dẫn trong Cách tạo mô-đun trống . Trong mã được hiển thị ở đây, giả sử mô-đun được đặt tên helloworld .

Bước hai

Thêm mã sau vào tệp mô-đun.

/**
 * Implements hook_menu().
 */
function helloworld_menu() {
  $items['hello'] = array(
    'title' => 'Hello world!',
    'page callback' => 'helloworld_page',
    'access callback' => TRUE,
  );

  return $items;
}

/**
 * Page callback for /hello.
 */
function helloworld_page() {
  return 'Hello world!';
}

Bước thứ ba

Kích hoạt mô-đun và truy cập http://example.com/hello . (Thay thế example.com bằng tên miền cho máy chủ của bạn.)
[.__.] Bạn sẽ thấy thông báo "Xin chào thế giới!". Đó là nó! Bạn có một triển khai hook_menu() hoạt động đầy đủ. Điều gì tiếp theo là các chủ đề nâng cao khác nhau liên quan đến hook_menu(). Cụ thể, bạn có thể muốn đọc về quyền, vì trang trên sẽ có thể xem được bởi bất kỳ ai.

Tranh luận

Nếu bạn muốn truyền thêm dữ liệu cho cuộc gọi lại trang, bạn có thể sử dụng đối số trang để đạt được điều này. Đối số trang phải là một mảng các đối số để chuyển sang gọi lại trang. Nếu một số nguyên được sử dụng làm đối số, nó sẽ đại diện cho một phần của URL, bắt đầu từ 0, tăng một lần cho mỗi dấu gạch chéo (/). Trong ví dụ sau, điều này có nghĩa là 0 sẽ được chuyển thành 'xin chào'.

function helloworld_menu() {
  $items['hello'] = array(
    'page callback' => 'helloworld_page',
    'page arguments' => array(0),
  );

  return $items;
}

function helloworld_page($argument1) {
  return $argument1;
}

Các chuỗi sẽ được gửi trên nguyên văn, vì vậy array(0, 'world') có thể được sử dụng để lấy lại hello world.

function helloworld_page($argument1, $argument2) {
  return $argument1 . ' ' . $argument2;
}

"Ký tự đại diện" có thể được sử dụng để chấp nhận dữ liệu tùy ý từ URL.

function helloworld_menu() {
  $items['hello/%'] = array(
    'page callback' => 'helloworld_page',
    'page arguments' => array(1),
  );

  return $items;
}

function helloworld_page($argument1) {
  return $argument1;
}

Truy cập hello/world, $argument1 Sẽ bằng world.

Đối số tự động tải

Thông thường, một đối số URL sẽ là số xác định, ví dụ: một thực thể. Để tránh sao chép mã chuyển đổi ID này thành đối tượng tương ứng, Drupal hỗ trợ tự động tải cho các ký tự đại diện "có tên". Khi sử dụng ký tự đại diện có tên, Drupal sẽ kiểm tra đối với một hàm có cùng tên với ký tự đại diện, được thêm vào bởi _load. Nếu tìm thấy một hàm như vậy, nó sẽ được gọi với giá trị của giá trị trong URL và bất cứ điều gì được hàm nạp lại trả về được chuyển đến hàm gọi lại trang thay cho giá trị ban đầu. Vì Drupal đã có chức năng như vậy để tải các nút, node_load() , chúng ta có thể nhận các nút tự động tải và chuyển đến trang gọi lại.

function helloworld_menu() {
  $items['hello/%node'] = array(
    'page callback' => 'helloworld_page',
    'page arguments' => array(1),
  );

  return $items;
}

function helloworld_page($node) {
  return t('Hello node (ID = !nid)', array('!nid' => $node->nid));
}

Tự động tải nâng cao

Đôi khi, sẽ cần phải tự động tải nhiều hơn dựa trên nhiều hơn một đối số. Do chỉ có đối số được đặt tên được truyền cho trình tải theo mặc định, nên người ta cần nói rõ ràng Drupal mà các đối số tải thêm sẽ được chuyển cho trình tải. Ví dụ: để tải một bản sửa đổi cụ thể của một nút, cần phải chuyển đến node_load() ID nút và ID sửa đổi. Điều đó có thể được thực hiện bằng mã sau đây.

function helloworld_menu() {
  $items['hello/%node/revision/%'] = array(
    'page callback' => 'helloworld_page',
    'page arguments' => array(1),
    'load arguments' => array(3),
  );

  return $items;
}

function helloworld_page($node) {
  return t('Hello node (ID = !nid, revision ID = !rid)', array('!nid' => $node->nid, '!rid' => $node->vid));
}

Quyền

'access callback' => TRUE, Là cần thiết để làm cho ví dụ đơn giản ở trên có thể xem được, nhưng nó hầu như không lý tưởng, vì nó không cho phép kiểm soát những gì đã từng có. Bất cứ ai cố gắng truy cập/xin chào sẽ được cấp quyền truy cập. Cách dễ nhất để cung cấp một số biện pháp kiểm soát, là cung cấp một cuộc gọi lại truy cập, giống như cuộc gọi lại trang từ phía trên. Đoạn mã sau vẫn cho phép truy cập vào bất kỳ ai, nhưng chỉ ra cách di chuyển logic đến một hàm được gọi tại thời điểm truy cập, do đó cho phép logic phức tạp hơn.

/**
 * Implements hook_menu().
 */
function helloworld_menu() {
  $items['hello'] = array(
    'page callback' => 'helloworld_page',
    'access callback' => 'helloworld_access',
  );

  return $items;
}

/**
 * Access callback for /hello.
 */
function helloworld_access() {
  return TRUE;
}

Đây không hẳn là cách tốt nhất, vì sử dụng một chức năng tùy chỉnh thường sẽ không cần sao chép mã. Cách tốt hơn là, hầu hết thời gian, sẽ sử dụng user_access() . Cùng với cuộc gọi lại truy cập, có thể đặt đối số truy cập. Có thể yêu cầu trang có thể xem được từ người dùng với quyền truy cập hồ sơ người dùng với mã sau đây.

/**
 * Implements hook_menu().
 */
function helloworld_menu() {
  $items['hello'] = array(
    'page callback' => 'helloworld_page',
    'access callback' => 'user_access',
    'access arguments' => array('access user profiles'),
  );

  return $items;
}

Vì cuộc gọi lại truy cập theo mặc định là user_access, nên nó có thể bị bỏ qua, như trong đoạn mã trên.

Chủ đề nâng cao hơn

Tài liệu chính thức hook_menu() cung cấp nhiều thông tin hơn về các trường hợp sử dụng phức tạp nhất cho hook.

147
Letharion