Як я можу реалізувати kuk_menu ()?


103

Які основи реалізації hook_menu()?

Я хотів би бачити основи, висвітлені в одному запитанні, щоб уникнути необхідності відповідати на ті ж подібні, але різні запитання знову і знову.

Відповіді:


148

Ця інформація справедлива для 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;
}

Відвідування привіт / світ, $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()документація надає набагато більше інформації про найскладніші випадки використання гачка.


3
Дивовижно! Тільки для повноти titleпотрібне майно для всіх предметів, повернених зhook_menu()
Clive

1
Я знаю, що так говорять документи, але коли я тестував D7, це було не так. Я міг би додати його в першому прикладі я припускаю, але я хотів би зберегти речі абсолютного мінімуму , щоб зробити його якомога простіше.
Летаріон

1
Я б сказав, що додавання заголовка до сторінки є однією з абсолютних мінімальних речей, які ви можете зробити з прив'язкою_меню (), але це ваш пост: P Можливо, варто виправити помилки синтаксису (приклади коду 2, 4, 5 і 6), щоб люди могли скопіювати та вставити
Clive

1
Argh, я спочатку старанно працював над кодом, але, як пройшов час, я почав плакати і почав копіювати вставки. Виправлені синтаксичні помилки, принаймні ті, що я бачив;) Ну, ти маєш рацію, що має бути заголовок звичайно, тому я додавав його до початкового прикладу.
Летаріон

1
Як я можу зареєструвати файл PHP до контуру за допомогою гака_меню? Це призначений для користувача файл php, який включає завантажувальний файл друпала, використовує змінні сеансу друпалу та приймає аргумент, який є ідентифікатором користувача.
Елін Й.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.