AJAX ссылки в Drupal 7 на примере листалки последних комментариев

В 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
Теги:
работа с блоками, создание модуля
Добавлено: 29 Июля 2018 20:19:33 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...