hook_menu ()를 어떻게 구현해야합니까?


103

구현의 기본은 무엇입니까 hook_menu()?

나는 똑같지 만 다른 질문에 반복해서 답하지 않아도되도록 기본 질문을 단일 질문으로 다루고 싶습니다.

답변:


148

이 정보는 Drupal 6 및 7에 유효합니다. Drupal 8에서는 새로운 라우팅 시스템hook_menu() 으로 대체되었습니다 . 아래는 간단한 3 단계로 구현 합니다.hook_menu()

1 단계

빈 모듈 을 만드는 방법 의 지침에 따라 빈 모듈을 만듭니다 . 여기에 표시된 코드에서는 모듈의 이름이 helloworld 라고 가정합니다 .

2 단계

다음 코드를 모듈 파일에 추가하십시오.

/**
 * 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!';
}

3 단계

모듈을 활성화하고 http://example.com/hello를 방문하십시오 . (example.com을 서버의 도메인 이름으로 바꾸십시오.)
"Hello world!"메시지가 나타납니다. 그게 다야! 완전히 작동하는 hook_menu()구현이 있습니다. 다음은 다양한 고급 주제 hook_menu()입니다. 특히, 위의 페이지를 누구나 볼 수 있으므로 권한에 대해 읽으려고 할 수 있습니다.

인수

더 많은 데이터를 페이지 콜백에 전달하려면 페이지 인수를 사용하여이를 달성 할 수 있습니다. 페이지 인수는 페이지 콜백에 전달할 인수 배열이어야합니다. 정수가 인수로 사용되면 0부터 시작하여 슬래시 (/)마다 한 번씩 증가하는 URL의 일부를 나타냅니다. 다음 예에서 이는 0이 'hello'로 바뀐다는 의미입니다.

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

  return $items;
}

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

문자열은 그대로 전송되므로 다시 나가는 array(0, 'world')데 사용할 수 있습니다 hello world.

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

"와일드 카드"를 사용하여 URL에서 임의의 데이터를 승인 할 수 있습니다.

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

  return $items;
}

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

hello / world를 방문 $argument1하면과 같습니다 world.

인수 자동 로딩

종종 URL 인수는 예를 들어 엔티티를 식별하는 숫자입니다. 이 ID를 해당 객체로 변환하는 코드 복제를 피하기 위해 Drupal은 "이름이 지정된"와일드 카드에 대한 자동로드를 지원합니다. 이름이 지정된 와일드 카드를 사용하면 Drupal은 와일드 카드와 이름이 같은 기능을 접미사로 확인 _load합니다. 이러한 함수가 발견되면 URL의 값으로 호출되고 로더 함수가 리턴 한 값은 원래 값 대신 페이지 콜백으로 전달됩니다. Drupal에는 이미 노드로드 기능이 있으므로 node_load()노드를 자동로드하여 페이지 콜백에 전달할 수 있습니다.

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));
}

고급 자동 로딩

때로는 둘 이상의 인수를 기반으로 더 많은 것을 자동으로로드해야 할 수도 있습니다. 기본적으로 명명 된 인수 만 로더에 전달되므로 Drupal에게 로더에 전달할 추가로드 인수를 명시 적으로 알려야합니다. 예를 들어, 노드의 특정 개정을로드하려면 node_load()노드 ID 및 개정 ID 에 전달해야 합니다. 다음 코드로 달성 할 수 있습니다.

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));
}

권한

'access callback' => TRUE,위의 간단한 예를 전혀 볼 수 없게 만드는 것이 필요하지만, 그 어느 것도 제어 할 수 없기 때문에 거의 이상적이지 않습니다. / hello를 방문하려는 사람에게는 액세스 권한이 부여됩니다. 제어 수단을 제공하는 가장 쉬운 방법은 위의 페이지 콜백과 마찬가지로 액세스 콜백을 제공하는 것입니다. 다음 코드는 여전히 모든 사람에게 액세스를 허용하지만 액세스 시간에 호출 된 함수로 로직을 이동하여 더 복잡한 로직을 허용하는 방법을 보여줍니다.

/**
 * 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;
}

사용자 정의 함수를 사용하면 코드가 불필요하게 복제되기 때문에 이것이 반드시 최선의 방법은 아닙니다. 더 나은 방법은 대부분의 경우 사용하는 것 user_access()입니다. 액세스 콜백과 함께 액세스 인수를 설정할 수 있습니다. 다음 코드를 사용하여 사용자 프로파일 액세스 권한이있는 사용자 가 페이지를 볼 수 있도록 요구할 수 있습니다 .

/**
 * 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;
}

액세스 콜백은 기본적으로 user_access이므로 위 코드와 같이 생략 할 수 있습니다.

더 고급 주제

공식 hook_menu()문서는 후크의 가장 복잡한 사용 사례에 대한 더 많은 정보를 제공합니다.


3
대박! 완전성을 위해이 title부동산은 다음 항목에서 반환 된 모든 품목에 필요합니다.hook_menu()
Clive

1
문서가 그렇게 말하는 것을 알고 있지만 D7에서 테스트했을 때는 그렇지 않았습니다. 나는 그것을 추측하는 첫 번째 예에 추가 할 수 있지만 가능한 한 쉽게 하기 위해 물건을 절대적으로 최소화하고 싶었습니다 .
Letharion

1
페이지에 제목을 추가하는 것이 hook_menu ()로 할 수있는 최소한의 일 중 하나라고 말하고 싶지만 게시물입니다 : P 구문 오류를 수정하는 것이 좋습니다 (코드 예 2, 4, 5 및 6) 사람들이 복사하여 붙여 넣기
Clive

1
Argh, 나는 실제로 코드를 실제로 실행하는 데 부지런했지만 시간이 지남에 따라 더 가파르게 복사 복사를 시작했습니다. 구문 오류, 적어도 내가 본 것들을 수정했습니다.) 글쎄, 물론 제목 이 있어야한다는 것이 맞습니다 . 그래서 초기 예제에 하나를 추가했습니다.
Letharion

1
hook_menu를 사용하여 PHP 파일을 경로에 어떻게 등록 할 수 있습니까? drupal 부트 스트랩을 포함하고 drupal 세션 변수를 사용하며 사용자 ID 인 인수를 허용하는 사용자 정의 작성된 PHP 파일입니다.
Елин Й.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.