Как мне реализовать hook_menu ()?

Каковы основы реализации hook_menu()?

Я хотел бы, чтобы основы были рассмотрены в одном вопросе, чтобы избежать необходимости повторять одни и те же похожие, но разные вопросы снова и снова.

100 голосов | спросил 4 revs, 2 users 57%
Letharion
1 Jam1000000amThu, 01 Jan 1970 03:00:00 +030070 1970, 03:00:00

1 ответ


145

Эта информация действительна для Drupal 6 и 7. В Drupal 8, hook_menu() заменен на новая система маршрутизации . Ниже мы реализуем hook_menu() тремя простыми шагами.

Шаг первый

Создайте пустой модуль, следуя инструкциям в Как создать пустой модуль . В приведенном здесь коде предполагается, что модуль называется helloworld .

Шаг второй

Добавьте в файл модуля следующий код.

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

Шаг третий

Включите модуль и посетите http://example.com/hello . (Замените example.com доменным именем для вашего сервера.)
Вы должны увидеть сообщение «Привет мир!». Это оно! У вас есть полностью работающая реализация hook_menu(). Ниже приведены различные более сложные темы, касающиеся hook_menu(). В частности, вы можете захотеть прочитать о разрешениях, поскольку страница, приведенная выше, будет доступна любому пользователю.

Аргументы

Если вы хотите передать больше данных на обратный вызов страницы, вы можете использовать аргументы страницы для этого. Аргументы страницы должны быть массивом аргументов для перехода на обратный вызов страницы. Если в качестве аргумента используется целое число, оно будет представлять собой часть URL-адреса, начиная с 0, увеличивая один раз для каждой косой черты (/). В следующем примере это означает, что 0 будет обращено в «привет».

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 будет номер, идентифицирующий, например, объект. Чтобы избежать дублирования кода, который преобразует этот идентификатор в соответствующий объект, 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(). Это может быть выполнено с помощью следующего кода.

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, необходимо сделать простой пример выше видимым вообще, но он вряд ли идеален, поскольку он не позволяет контролировать, что так было. Каждому, кто пытается посетить /привет, будет предоставлен доступ. Самый простой способ обеспечить некоторую степень контроля - это обеспечить обратный вызов доступа, как и обратный вызов страницы сверху. Следующий код по-прежнему позволяет получить доступ ко всем, но показывает, как переместить логику в функцию, называемую во время доступа, тем самым обеспечивая более сложную логику.

/**
 * 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() предоставляет намного больше информации о наиболее сложных вариантах использования для hook.

ответил Brian 28 FebruaryEurope/MoscowbTue, 28 Feb 2017 22:55:41 +0300000000pmTue, 28 Feb 2017 22:55:41 +030017 2017, 22:55:41

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132