В Drupal 7 появился новый AJAX Framework, который позволяет абстрагироваться от написания Javascript кода.
Ниже приведён пример модуля, создающий блок с последними комментариями и ссылкой "more", клик на которой подгружает следующую пачку комментариев. Пример функционала модуля можно посмотреть на этом сайте в блоке Последние комментарии (синяя стрелочка после заголовка).
1. Создаём функцию, которая возвращает содержимое блока (т.е. последние комментарии и ajax ссылку "more"):
/**
* Возвращает html код содержимого блока
*/
function _last_comments_block_content($from_cid = NULL) {
// Выбираем комментарии из базы
$query = db_select('comment', 'c')
->fields('c', array('cid', 'nid', 'subject'))
->condition('status', COMMENT_PUBLISHED)
->orderBy('cid', 'DESC')
->range(0, 10);
if (!is_null($from_cid)) {
$query->condition('cid', $from_cid, '<');
}
$items = array();
foreach ($query->execute() as $comment) {
$items[] = l($comment->subject, 'node/' . $comment->nid, array('fragment' => 'comment-' . $comment->cid));
$last_cid = $comment->cid;
}
$content = theme('item_list', array('items' => $items));
$content .= '<div class="more-link">' . l('more', 'last-comments/' . $last_cid . '/nojs', array(
'attributes' => array(
'class' => array('use-ajax'),
'title' => 'More comments',
)
)) . '</div>';
return $content;
}
Чтобы наделить ссылку ajax функциями, ей нужно присвоить класс use-ajax и добавить к адресу аргумент nojs, чтобы в callback функции можно было опознать пользователей с отключённым javascript.
2. Создаём блок:
/**
* Реализация hook_block_info()
*/
function last_comments_block_info() {
$blocks['last-comments'] = array('info' => 'Last comments');
return $blocks;
}
/**
* Реализация hook_block_view();
*/
function last_comments_block_view($delta = '') {
$block = array();
if ($delta == 'last-comments') {
$block['subject'] = 'Last comments';
$block['content'] = '<div id="last-comments">' . _last_comments_block_content() . '</div>';
// подключаем необходимые ajax библиотеки
drupal_add_library('system', 'drupal.ajax');
drupal_add_library('system', 'jquery.form');
}
return $block;
}
Для работы AJAX-фреймворка, нужно не забыть подключить библиотеки drupal.ajax (файл misc/ajax.js) и jquery.form (файл misc/form.js).
3. Регистрируем адрес, по которому будут возвращаться данные:
/**
* Реализация hook_menu()
*/
function last_comments_menu() {
$items['last-comments/%'] = array(
'title' => 'Last comments',
'page callback' => 'last_comments_ajax_callback',
'page arguments' => array(1),
'delivery callback' => 'ajax_deliver', // данные, возвращённые ф-ей last_comments_ajax_callback(), будут отданы в json формате
'access arguments' => array('access content'),
);
return $items;
}
В первом аргументе будет содержаться id последнего показанного комментария.
4. Реализуем callback указанный в hook_menu:
/**
* Callback меню
*/
function last_comments_ajax_callback($from_cid, $mode = NULL) {
// Если у посетителя отключён javascript, то показываем ему сообщение
if ($mode != 'ajax') {
drupal_set_message('Turn Javascript');
drupal_goto(isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '<front>');
}
// обновляем содержимое блока
$commands[] = ajax_command_html('#last-comments', _last_comments_block_content($from_cid));
return array('#type' => 'ajax', '#commands' => $commands);
}
В калбаке возвращается не html код блока, а набор команд для AJAX-фреймворка. Например с помощью команды:
ajax_command_html('some-selector', 'some-text')
мы как бы говорим браузеру — заменить текст в селекторе some-selector на some-text, а браузер на это выполняет js код:
$('some-selector').html('some-text');
Встроенных команд не так много, но выручает универсальная ajax_command_invoke, с помощью которой можно дёргать любые методы jQuery. Например, чтобы сменить адрес у ссылки (атрибут href) нужно добавить:
$commands[] = ajax_command_invoke('some-selector', 'attr', array('href', '/my/new/path'));
Что равносильно js коду:
$('some-selector').attr('href', '/my/new/path');
Ну вот и всё. Мы написали модуль без единой строчки яваскрипта.
Написанное актуально для
Drupal 7.x