Прикрутить пагинатор в Drupal'e более чем простая задача. Пара строчек кода, не более, в буквальном смысле. Даже странно (и немного обидно), что я потратил как-то уж слишком много времени, чтобы разобраться в этом.
Для теста создадим модуль test_pager, который просто выводит на страницу какую-то информацию. Нам понадобится два файлика, файл конфигурации test_pager.info и, собственно, test_pager.module.
В .info файл напишем что-нибудь наподобие этого:
name = Test Pager
description = Testing pager
core = 7.x
Ну а в test_pager.module создадим нашу страничку с выводом на ней It works!
'Test pager',
'page callback' => '_test_pager',
'access callback' => TRUE,
);
return $items;
}
function _test_pager() {
return 'It works!';
}
Кстати, имя коллбека начинается с '_' неспроста, это одно из соглашений Друпала по именованию функций. Если функция "строго приватная", т. е. нигде больше не вызывается, то называть ее следует начиная с нижнего подчеркивания.
Все, модуль создан, пора его тестировать. Включаем его и переходим на страницу /test-pager.
It works! - а значит самое время прикручивать пагинатор.
То, как мы будем прикручивать пагинатор, зависит от способа получения данных на вывод - либо мы их формируем через запрос к БД с помощью API Друпала (db_select), либо создаем вручную.
С первым все достаточно просто. Для примера сделаем выборку из таблицы... Хм, модуль тестирую на новом инсталле Друпала, контента никакого нет. Пожалуй, выведу имена переменных, хранящихся в таблице variable, их там штук 20-ть должно быть.
Переписываем содержимое нашего коллбека _test_pager:
function _test_pager() {
$output = '';
$result = db_select('variable', 'v')
->fields('v', array('name'))
->execute();
foreach ($result as $record) {
$output .= '
'. $record->name . '
';
}
return $output;
}
Чистим кэш, обновляем страничку /test-pager, видим следующую картину:
Как и предполагалось, выводятся имена переменных из таблицы variable (колонка name). Вот сразу скриншот из phpMyAdmin, чтобы понятней было что это и откуда:
Ну а теперь заместо того, чтобы выводить все на одной странице, добавляем пагинатор. Для этого нам потребуется в цепочке методов db_select() вызвать метод extend('PagerDefault'). Вызывать его надо до выполнения запроса, т. е. до вызова метода execute(). По умолчанию будет создан пагинатор с 10-тью записями на каждую страницу, но можно назначить и свое значение с помощью метода limit(), например extend('PagerDefault')->limit(3) (т. е. если мы хотим выводить по 10 записей на страницу, то limit(10) можно не вызывать, т. к. это дефолтное значение).
И надо не забыть вывести сам пагинатор, который блок со ссылками « first ‹ previous 1 2 3 4 5 6 7 next › last ». За вывод этого блока отвечает функция theme('pager'), вызов которой и возвращает эти ссылки. Т. е. все что нам надо сделать, это добавить в самом конце к выводу $output .= theme('pager');
Итого, измененный код коллбека должен выглядеть как-то так:
function _test_pager() {
$output = '';
$result = db_select('variable', 'v')
->fields('v', array('name'))
->extend('PagerDefault')
->limit(3)
->execute();
foreach ($result as $record) {
$output .= '
'. $record->name . '
';
}
$output .= theme('pager');
return $output;
}
Чистим кэш, рефрешим страничку и видим... Да, наш уже работающий пагинатор:
Красота!
А теперь делаем то же самое, но только предположим, что данные получаем не через db_select(), а собираем вручную (да хотя бы через тот же db_query). Для простоты, будем выводить содержимое вот такого массивчика:
$test_array = array('111',
'222',
'333',
'444',
'555',
'666',
'777',
'888',
'999',
'000',
);
Принцип тот же самый, за тем лишь исключением, что теперь нам надо инициализировать пагинатор вручную. Для этого существует функция pager_default_initialize($total, $limit, $element = 0). Два первых аргумента - обязательные, $total это суммарное количество элементов на вывод, $limit это сколько элементов выводить на одну страницу. Третий аргумент опциональный, и нужен лишь в том случае, если у нас на странице много пагинаторов, чтобы они не путались.
Ну а возвращает эта функция номер страницы, на которой мы находимся, другими словами $_GET['page'] с нулем по умолчанию (т. е. если мы на первой, главной, странице - функция вернет ноль, перейдем по пагинатору на вторую страницу, функция вернет единицу, и так далее).
Вот. Ну а дальше уже дело техники, и главное не забыть вставить сами ссылки пагинатора, theme('pager').
function _test_pager() {
$output = '';
$test_array = array('111',
'222',
'333',
'444',
'555',
'666',
'777',
'888',
'999',
'000',
);
//сколько всего элементов
$total = count($test_array);
//будем выводить по четыре элемента на страницу
$limit = 4;
//инициализируем пагинатор
$page = pager_default_initialize($total, $limit);
//вычисляем смещение
$offset = $page * $limit;
//формируем массив на вывод для текущей страницы
$new_array = array_slice($test_array, $offset, $limit);
foreach ($new_array as $value) {
$output .= '
' . $value . '
';
}
//не забываем добавить пагинатор
$output .= theme('pager');
return $output;
}
Все! Осталось только обновить страницу и радоваться постраничному выводу:
И парочка ссылок на документацию:
function theme_pager
function pager_default_initialize
Добавление пагинатора рассмотрено на примере Drupal 7, в Drupal 6 чуток по-другому (как - не разбирался, давно обновил все сайты до семерки, но то что в шестом Друпале нет pager_default_initialize - факт, зато есть pager_query). Для Drupal 8 все останется также, как и для Drupal 7, надо полагать.
Комментарии
Спасибо огромное!
Рад, что помогло ^_^