Пейджинг
CodeIgniter предоставляет очень простую, но гибкую библиотеку пейджирования, которую легко стилизовать, она работает с моделью и способна поддерживать несколько пейджеров на одной странице.
Загрузка библиотеки
Как и все сервисы в CodeIgniter, ее можно загрузить через Config\Services, хотя обычно вам не нужно загружать ее вручную:
$pager = \Config\Services::pager();
Пейджирование результатов базы данных
В большинстве случаев вы будете использовать библиотеку Pager для пейджирования результатов, полученных из базы данных. При использовании класса Model вы можете использовать его встроенный paginate() метод для автоматического получения текущей группы результатов, а также для настройки библиотеки Pager, чтобы она была готова к использованию в ваших контроллерах. Она даже считывает текущую страницу, которую она должна отобразить, из текущего URL-адреса через page=X параметр запроса.
Для предоставления постраничного списка пользователей в вашем приложении метод вашего контроллера будет выглядеть примерно так:
<?php
namespace App\Controllers;
use CodeIgniter\Controller;
class UserController extends Controller
{
public function index()
{
$model = new \App\Models\UserModel();
$data = [
'users' => $model->paginate(10),
'pager' => $model->pager,
];
echo view('users/index', $data);
}
}
В этом примере мы сначала создаем новый экземпляр нашего UserModel. Затем мы заполняем данные для отправки в представление. Первый элемент — это результаты из базы данных, users, которые извлекаются для правильной страницы, возвращая 10 пользователей на страницу. Второй элемент, который необходимо отправить в представление, — это сам экземпляр Pager. Для удобства модель сохранит используемый экземпляр и сохранит его в общедоступной переменной класса, $pager. Поэтому мы получаем его и присваиваем переменной $pager в представлении.
В представлении нам затем нужно указать, где отобразить результирующие ссылки:
<?= $pager->links() ?>
И этого достаточно. Класс Pager отобразит ссылки «Первая» и «Последняя», а также «Следующая» и «Предыдущая» для любых страниц, отстоящих более чем на две страницы от текущей.
Важно помнить, что схема библиотеки для «Следующая» и «Предыдущая» отличается от используемой в традиционном способе пейджирования результатов.
«Следующая» и «Предыдущая» здесь связаны с группой ссылок, которые должны быть отображены в структуре пейджирования, а не со следующей или предыдущей страницей записей.
Если вы предпочитаете более простой вывод, вы можете использовать метод simpleLinks(), который использует только ссылки «Старее» и «Новее», вместо подробных ссылок пейджирования:
<?= $pager->simpleLinks() ?>
За кулисами библиотека загружает файл представления, определяющий, как форматируются ссылки, что упрощает их модификацию по мере необходимости. Ниже приведено подробное описание того, как полностью настроить вывод.
Пейджирование нескольких результатов
Если вам необходимо предоставить ссылки из двух разных наборов результатов, вы можете передавать имена групп большинству методов пейджирования, чтобы сохранить данные разделенными:
// In the Controller
public function index()
{
$userModel = new \App\Models\UserModel();
$pageModel = new \App\Models\PageModel();
$data = [
'users' => $userModel->paginate(10, 'group1'),
'pages' => $pageModel->paginate(15, 'group2'),
'pager' => $userModel->pager,
];
echo view('users/index', $data);
}
// In the views:
<?= $pager->links('group1') ?>
<?= $pager->simpleLinks('group2') ?>
Установка страницы вручную
Если вам нужно указать, какую страницу результатов вернуть, вы можете указать страницу в качестве третьего аргумента. Это может быть полезно, когда у вас есть другой способ, отличный от стандартного $_GET параметра, для управления отображением страницы.
$userModel = new \App\Models\UserModel(); $page = 3; $users = $userModel->paginate(10, 'group1', $page);
Указание сегмента URI для страницы
Также можно использовать сегмент URI для номера страницы вместо параметра запроса страницы. Просто укажите номер сегмента, используемого в качестве четвертого аргумента. URI, сгенерированные пейджером, будут выглядеть как https://domain.tld/model/[номерСтраницы] вместо https://domain.tld/model?page=[номерСтраницы].
$users = $userModel->paginate(10, 'group1', null, 3);
Обратите внимание: значение $segment не может быть больше, чем количество сегментов URI плюс 1.
Ручное пейджирование
Вы можете столкнуться со случаями, когда вам просто нужно создать пейджирование на основе известных данных. Вы можете создать ссылки вручную с помощью метода makeLinks(), который принимает текущую страницу, количество результатов на страницу и общее количество элементов в качестве первого, второго и третьего параметров соответственно:
<?= $pager->makeLinks($page, $perPage, $total) ?>
По умолчанию это отобразит ссылки в обычном формате, как серию ссылок, но вы можете изменить используемую шаблон отображения, передав имя шаблона в качестве четвертого параметра. Более подробную информацию можно найти в следующих разделах.
<?= $pager->makeLinks($page, $perPage, $total, 'template_name') ?>
Также можно использовать сегмент URI для номера страницы вместо параметра запроса страницы, как описано в предыдущем разделе. Укажите номер сегмента, используемого в качестве пятого параметра к makeLinks().
<?= $pager->makeLinks($page, $perPage, $total, 'template_name', $segment) ?>
Обратите внимание: значение $segment не может быть больше, чем количество сегментов URI плюс 1.
Если вам нужно отобразить много пейджеров на одной странице, то дополнительный параметр, определяющий группу, может быть полезен:
$pager = service('pager');
$pager->setPath('path/for/my-group', 'my-group'); // Additionally you could define path for every group.
$pager->makeLinks($page, $perPage, $total, 'template_name', $segment, 'my-group');
Библиотека пейджирования по умолчанию использует параметр запроса page для HTTP-запросов (если не указано имя группы или группа default) или page_[имяГруппы] для имен пользовательских групп.
Пейджирование только с ожидаемыми запросами
По умолчанию все запросы GET отображаются в ссылках пейджирования.
Например, при обращении к URL-адресу http://domain.tld?search=foo&order=asc&hello=i+am+here&page=2, ссылка на страницу 3 может быть сгенерирована вместе с другими ссылками следующим образом:
echo $pager->links(); // Page 3 link: http://domain.tld?search=foo&order=asc&hello=i+am+here&page=3
Метод only() позволяет ограничить это только уже ожидаемыми запросами:
echo $pager->only(['search', 'order'])->links(); // Page 3 link: http://domain.tld?search=foo&order=asc&page=3
Параметр запроса page включен по умолчанию. И only() действует во всех ссылках пейджирования.
Настройка ссылок
Настройка представления
При отображении ссылок на странице используется файл представления для описания HTML. Вы можете легко изменить используемое представление, отредактировав app/Config/Pager.php:
public $templates = [
'default_full' => 'CodeIgniter\Pager\Views\default_full',
'default_simple' => 'CodeIgniter\Pager\Views\default_simple',
];
Это значение хранит псевдоним и пути к представлениям с именованным пространством имен для представления, которое должно использоваться. Представления default_full и default_simple используются для методов links() и simpleLinks() соответственно. Чтобы изменить способ их отображения во всем приложении, вы можете назначить здесь новое представление.
Например, предположим, что вы создали новый файл представления, который работает с фреймворком Foundation CSS, и поместили этот файл в app/Views/Pagers/foundation_full.php. Поскольку каталог application имеет именованное пространство имен App, а все каталоги под ним непосредственно отображаются в сегментах именованного пространства имен, вы можете найти файл представления по его именованному пространству имен:
'default_full' => 'App\Views\Pagers\foundation_full',
Однако, поскольку он находится в стандартном каталоге app/Views, вам не нужно его именовать, поскольку метод view() может найти его по имени файла. В этом случае вы можете просто указать подкаталог и имя файла:
'default_full' => 'Pagers/foundation_full',
После создания представления и настройки в конфигурации оно будет автоматически использоваться. Вам не нужно заменять существующие шаблоны. Вы можете создавать дополнительные шаблоны в файле конфигурации по мере необходимости. Общей ситуацией является необходимость различных стилей для переднего и заднего плана вашего приложения.
public $templates = [
'default_full' => 'CodeIgniter\Pager\Views\default_full',
'default_simple' => 'CodeIgniter\Pager\Views\default_simple',
'front_full' => 'App\Views\Pagers\foundation_full',
];
После настройки вы можете указать его в качестве последнего параметра в методах links(), simpleLinks(), и makeLinks():
<?= $pager->links('group1', 'front_full') ?>
<?= $pager->simpleLinks('group2', 'front_full') ?>
<?= $pager->makeLinks($page, $perPage, $total, 'front_full') ?>
Создание представления
При создании нового представления вам нужно только создать код, необходимый для создания самих ссылок пейджирования. Не следует создавать лишних оберток div, так как они могут быть использованы в нескольких местах, и вы лишь ограничиваете их полезность. Наиболее просто продемонстрировать создание нового представления, показав существующий шаблон default_full:
<?php $pager->setSurroundCount(2) ?>
<nav aria-label="Page navigation">
<ul class="pagination">
<?php if ($pager->hasPrevious()) : ?>
<li>
<a href="<?= $pager->getFirst() ?>" aria-label="<?= lang('Pager.first') ?>">
<span aria-hidden="true"><?= lang('Pager.first') ?></span>
</a>
</li>
<li>
<a href="<?= $pager->getPrevious() ?>" aria-label="<?= lang('Pager.previous') ?>">
<span aria-hidden="true"><?= lang('Pager.previous') ?></span>
</a>
</li>
<?php endif ?>
<?php foreach ($pager->links() as $link) : ?>
<li <?= $link['active'] ? 'class="active"' : '' ?>>
<a href="<?= $link['uri'] ?>">
<?= $link['title'] ?>
</a>
</li>
<?php endforeach ?>
<?php if ($pager->hasNext()) : ?>
<li>
<a href="<?= $pager->getNext() ?>" aria-label="<?= lang('Pager.next') ?>">
<span aria-hidden="true"><?= lang('Pager.next') ?></span>
</a>
</li>
<li>
<a href="<?= $pager->getLast() ?>" aria-label="<?= lang('Pager.last') ?>">
<span aria-hidden="true"><?= lang('Pager.last') ?></span>
</a>
</li>
<?php endif ?>
</ul>
</nav>
setSurroundCount()
В первой строке метод setSurroundCount() указывает, что мы хотим отобразить две ссылки по обе стороны от ссылки текущей страницы. Единственным параметром, который он принимает, является количество отображаемых ссылок.
hasPrevious() & hasNext()
Эти методы возвращают логическое значение true, если существуют дополнительные ссылки, которые могут быть отображены по обе стороны от текущей страницы, основываясь на значении, переданном в setSurroundCount. Например, предположим, что у нас есть 20 страниц данных. Текущая страница — страница 3. Если счетчик окружающих ссылок равен 2, то следующие ссылки будут отображаться в списке: 1, 2, 3, 4 и 5. Поскольку первой отображаемой ссылкой является страница одна, hasPrevious() вернет false, так как страницы с нулевым номером нет. Однако hasNext() вернет true, так как после пятой страницы есть еще 15 страниц результатов.
getPrevious() & getNext()
Эти методы возвращают URL для предыдущей или следующей страниц результатов по обе стороны от пронумерованных ссылок. См. предыдущий абзац для полного объяснения.
getFirst() & getLast()
Подобно getPrevious() и getNext(), эти методы возвращают ссылки на первую и последнюю страницы в наборе результатов.
links()
Возвращает массив данных обо всех пронумерованных ссылках. Каждый массив ссылок содержит uri ссылки, заголовок, который просто является номером, и булево значение, указывающее, является ли ссылка текущей/активной ссылкой или нет:
$link = [
'active' => false,
'uri' => 'http://example.com/foo?page=2',
'title' => 1,
];
В представленном коде стандартной структуры пейджирования используются методы getPrevious() и getNext() для получения ссылок на предыдущую и следующую группы пейджирования соответственно.
Если вы хотите использовать структуру пейджирования, где prev и next будут ссылками на предыдущую и следующую страницы, основываясь на текущей странице, просто замените методы getPrevious() и getNext() на getPreviousPage() и getNextPage(), а методы hasPrevious() и hasNext() на hasPreviousPage() и hasNextPage() соответственно.
Ниже приведен пример с этими изменениями:
<nav aria-label="<?= lang('Pager.pageNavigation') ?>">
<ul class="pagination">
<?php if ($pager->hasPreviousPage()) : ?>
<li>
<a href="<?= $pager->getFirst() ?>" aria-label="<?= lang('Pager.first') ?>">
<span aria-hidden="true"><?= lang('Pager.first') ?></span>
</a>
</li>
<li>
<a href="<?= $pager->getPreviousPage() ?>" aria-label="<?= lang('Pager.previous') ?>">
<span aria-hidden="true"><?= lang('Pager.previous') ?></span>
</a>
</li>
<?php endif ?>
<?php foreach ($pager->links() as $link) : ?>
<li <?= $link['active'] ? 'class="active"' : '' ?>>
<a href="<?= $link['uri'] ?>">
<?= $link['title'] ?>
</a>
</li>
<?php endforeach ?>
<?php if ($pager->hasNextPage()) : ?>
<li>
<a href="<?= $pager->getNextPage() ?>" aria-label="<?= lang('Pager.next') ?>">
<span aria-hidden="true"><?= lang('Pager.next') ?></span>
</a>
</li>
<li>
<a href="<?= $pager->getLast() ?>" aria-label="<?= lang('Pager.last') ?>">
<span aria-hidden="true"><?= lang('Pager.last') ?></span>
</a>
</li>
<?php endif ?>
</ul>
</nav>
hasPreviousPage() & hasNextPage()
Этот метод возвращает значение true, если есть ссылки на страницы до и после текущей отображаемой страницы, соответственно.
Их отличие от hasPrevious() и hasNext() заключается в том, что они основаны на текущей странице, тогда как hasPrevious() и hasNext() основаны на наборе ссылок, которые должны отображаться до и после текущей страницы на основе значения, переданного в setSurroundCount.
getPreviousPage() & getNextPage()
Эти методы возвращают URL предыдущей и следующей страниц по отношению к текущей отображаемой странице, в отличие от getPrevious() и getNext(), которые возвращают URL предыдущей или следующей страниц результатов по обе стороны от пронумерованных ссылок. Полное объяснение см. в предыдущем абзаце.
Если вам нужны номера страниц вместо URL, вы можете использовать следующие методы:
getPreviousPageNumber() & getNextPageNumber()
Эти методы возвращают номер страницы для предыдущей или следующей страницы по отношению к текущей отображаемой странице.
getFirstPageNumber() & getLastPageNumber()
Эти методы возвращают номера страниц первой и последней страниц в наборе результатов.
getCurrentPageNumber()
Этот метод возвращает номер страницы текущей страницы.
getPageCount()
Этот метод возвращает общее количество страниц.
© 2014–2020 British Columbia Institute of Technology
Licensed under the MIT License.
https://codeigniter.com/user_guide/libraries/pagination.html