Hook_menu Drupal 7 создание страниц через модуль
В прошлом уроке мы рассмотрели как выводить информацию из БД с помощью API Drupal, а именно с помощью хуков hook_block_info(), hook_block_view(). В этом уроке мы будем выводить страницы, а точнее с помощью хука hook_menu, подключать страницу к другим частям друпала: меню, модулю перевода, шаблонам и т.д.
Начнем с простого, подключим страницу с выводом названий последних 10 новостей и их описанием. Получится у нас небольшая лента новостей. Использовать будем мы хук hook_menu(). Ниже его описание, а после описания начнем его использовать.
hook_menu()
Определяет пункт меню и возвращает страницу.
Этот хук вызванный в модуле регистрирует путь в том порядке каком он будет обработан Друпалом. Пути могут быть зарегистрированы только для обработки или они могут быть размещены в меню, например в меню навигации. Пути и связанная с ними информация называется menu router item. Этот хук редко вызывается (например когда включается модуль) и его результат кешируется в базе данных. Поэтому постоянно приходится чистить кеш, при изменение хука в модуле.
hook_menu() реализует возвращение ассоциативного массива, ключи которого определяют пути и значения которого ассоциативный массив свойств каждого их путей. (В результате получается лист свойств описываемых ниже)
Определение для каждого пути включает возвращаемую страницу, которая подключается когда регистрируемая страница запрошена. Если нет других запрашиваемых путей, которые должны отвечать на URL, то хук возвращает страницу. Например ваш модуль может зарегистрировать путь 'абв/где'.
<?php function mymodule_menu() { $items['abc/def'] = array( 'page callback' => 'mymodule_abc_view', ); return $items; } function mymodule_abc_view($ghi = 0, $jkl = '') { // ... } ?>
Когда путь 'абв/где' будет запрошен и дальше не будет ничего написано в URL, то и дополнительных аргументов передаваться не будет. Когда будет запрошен путь 'абв/где/1/Омск', то на страницу будет переданы аргументы "1" и "Омск". Это нам очень пригодится, когда мы будем создавать шаблоны страниц.
Дополнительные аргументы в пути можно определить как ассоциативный массив. Этот список аргументво может содержать комплексные значения аргументов и простые числовые. Когда числа используются и вызвана callback функция (функция возвращающая страницу), то соответствующий путь модуля будет замещен числом. Например первый аргумент можно вызвать с помощью функции arg(0), второй аргумент - arg(1), и т.д.
<?php function mymodule_menu() { $items['abc/def'] = array( 'page callback' => 'mymodule_abc_view', 'page arguments' => array(1, 'foo'), ); return $items; } ?>
Когда вызван путь 'abc/def', возвращаемая страница будет запрашивать 'def' как первый аргумент и всегда 'foo' как второй аргумент. Полное описание хука можно найти на этой странице: http://api.drupal.org/api/drupal/modules--system--system.api.php/functio...
Итак создадим простую страницу:
function sitemade_menu(){ $items = array(); // инициализируем массив наших пунктов меню $items['page_example'] = array( //добавляем страницу по пути 'page_example' 'title' => 'Пример страницы', //заголовок страницы 'description' => 'Обычная страница', //описание страницы 'page callback' => '_page_example', //функция возвращающая контент страницы 'access callback' => TRUE, // разрешаем всем просматривать эту страницу 'expanded' => TRUE, ); return $items; //возвращаем список страниц } function _page_example($content = NULL) { $content = ''; //инициализируем переменную пустого контента $query = db_select('node_revision', 'n'); //выбираем таблицу node_revision в которой лежит текущая ревизия документа $query->innerJoin('field_revision_body', 'b', 'b.revision_id = n.vid'); //присоединяем таблицу field_revision_body в которой лежит body $query->innerJoin('node', 'd', 'n.nid=d.nid'); //присоединяем таблицу node в которой лежит title ноды $query->fields('n', array('title'), array('nid'), array('vid')); //выбираем поля $query->fields('b', array('body_value')); $query->condition('d.type', 'news'); //делаем ограничение по контент типу $query->orderBy('n.timestamp', 'DESC'); //сортируем сначала свежие новости $query->range(0, 10); //выбираем только 10 последних $result = $query->execute(); //выполняем запрос к БД while($nodes = $result->fetch()){ //обрабатываем запрос $content .= '<h3>' . $nodes->title . '</h3>'; //выводим title $content .= $nodes->body_value; //выводим body } return $content; //возвращаем контент }
Также можно использовать свойство хука type, для того чтобы разместить страницу в различных меню, например в админке или в главное меню (main menu).
Давайте сделаем это:
function sitemade_menu(){ $items = array(); // инициализируем массив наших пунктов меню $items['page_example'] = array( //добавляем страницу по пути 'page_example' 'title' => 'Пример страницы', //заголовок страницы 'description' => 'Обычная страница', //описание страницы 'page callback' => '_page_example', //функция возвращающая контент страницы 'access callback' => TRUE, // разрешаем всем просматривать эту страницу 'expanded' => TRUE, 'type' => MENU_NORMAL_ITEM, 'menu_name' => 'main-menu', ); return $items; //возвращаем список страниц }
Обновим кеш и теперь появится ссылка в меню на эту страницу.
Помимо обычных пунктов меню, можно добавить отображение страницы в админке Друпала:
function sitemade_menu(){ $items = array(); // инициализируем массив наших пунктов меню $items['admin/config/content/page_example'] = array( //добавляем страницу по пути 'admin/config/content/page_example' 'title' => 'Пример страницы', //заголовок страницы 'description' => 'Обычная страница', //описание страницы 'page callback' => '_page_example', //функция возвращающая контент страницы 'access arguments' => array('administer site configuration'), //поставим права доступа для админа ); return $items; //возвращаем список страниц }
Теперь наша страница выводится только для админа и ссылка на страницу можно найти в админке:
Ссылка в админке появляется потому что друпал автоматически по пути admin/config/content/* вставляет ссылку, если мы поставим путь для хука admin/config/people/*, то ссылка появится в блоке Пользователи (вместо звездочки можно писать свое название, у нас это page_example).
Теперь мы умеем делать блоки и страницы, я думаю это основные хуки для вывода контента, они будут часто встречаться в Ваших модулях.
В следующем уроке мы разберем hook_perm(), для создания новых разрешений для пользователей.