Продолжаю серию статей, о том как написать модуль для друпала, в этой статье речь пойдет о хуках. Погуглив «что такое hook», находил статьи, где хуки объяснялись как магические порталы и как порог вхождения в друпал, на практике оказалось, что есть 251 хук ядра друпала и функция module_hook, которая сканирует модули на наличие префиксов функций, по которым можно добавлять код своей функции в ядро друпала или в другие модули.
Происходит это следующем образом:
- Функция в которую можно добавить свой код должна иметь префикс hook_ , чтобы запретить использовать функцию другими модулями надо в начале функции вставить _ (знак нижнего подчеркивания).
- Чтобы вставить свой код в другую функцию, надо вместо hook написать название своего модуля, например для hook_help() надо mymodule_help(), где mymodule название модуля.
- Затем функция module_hook() определяет был ли реализован хук в модуле, если возвращается значение TRUE, то задействуется API загрузки и взаимодействия модулей
Пример 1, как программно создать блок, используя хуки.
Есть в друпале модуль block, в api которого есть 8 хуков, нам для простого блока понадобятся 2 хука, hook_block_info и hook_block_view
В листинге хуков видем следующий пример кода:
-
hook_block_info
function hook_block_info() { // This example comes from node.module. $blocks['syndicate'] = array( 'info' => t('Syndicate'), 'cache' => DRUPAL_NO_CACHE, ); $blocks['recent'] = array( 'info' => t('Recent content'), // DRUPAL_CACHE_PER_ROLE will be assumed. ); return $blocks; }
-
hook_block_view
function hook_block_view($delta = '') { // This example is adapted from node.module. $block = array(); switch ($delta) { case 'syndicate': $block['subject'] = t('Syndicate'); $block['content'] = array( '#theme' => 'feed_icon', '#url' => 'rss.xml', '#title' => t('Syndicate'), ); break; case 'recent': if (user_access('access content')) { $block['subject'] = t('Recent content'); if ($nodes = node_get_recent(variable_get('node_recent_block_count', 10))) { $block['content'] = array( '#theme' => 'node_recent_block', '#nodes' => $nodes, ); } else { $block['content'] = t('No content available.'); } } break; } return $block; }
Немного переписав код, получаем такое содержимое файла mymodule.module:
t('mymodule-Syndicate'), 'cache' => DRUPAL_NO_CACHE, ); $blocks['mymodule-recent'] = array( 'info' => t('mymodule-Recent content'), // DRUPAL_CACHE_PER_ROLE will be assumed. ); return $blocks; } function mymodule_block_view($delta = '') { // This example is adapted from node.module. $block = array(); switch ($delta) { case 'mymodule-syndicate': $block['subject'] = t('mymodule-Syndicate'); $block['content'] = array( '#theme' => 'feed_icon', '#url' => 'rss.xml', '#title' => t('mymodule-Syndicate'), ); break; case 'mymodule-recent': if (user_access('access content')) { $block['subject'] = t('mymodule-Recent content'); if ($nodes = node_get_recent(variable_get('node_recent_block_count', 10))) { $block['content'] = array( '#theme' => 'node_recent_block', '#nodes' => $nodes, ); } else { $block['content'] = t('No content available.'); } } break; } return $block; }
На странице настройки блоков (admin/structure/block) видим наши 2 созданных блока.
Указав для них Sidebar first и нажав сохранить, видим наши 2 созданных блока в первом сайдбаре.
Пример 2, как программно создать страницу, используя хуки.
Для создания страницы надо использовать hook_menu(), на странице с описанием модуля видим листинг:
function hook_menu() { $items['example'] = array( 'title' => 'Example Page', 'page callback' => 'example_page', 'access arguments' => array('access content'), 'type' => MENU_SUGGESTED_ITEM, ); $items['example/feed'] = array( 'title' => 'Example RSS feed', 'page callback' => 'example_feed', 'access arguments' => array('access content'), 'type' => MENU_CALLBACK, ); return $items; }
Немного переписав код из примера получаем:
function mymodule_menu() { $items['hello'] = array( 'title' => 'hello world', 'page callback' => 'mymodule_hello', 'access callback' => TRUE, 'menu_name' => 'main-menu', 'options' => array('attributes' => array('class' => array('test-class'))), ); return $items; } function mymodule_hello() { return 'hello world'; }
Теперьпо адресу /hello, будет доступна страница созданная с помощью hook_menu()