Постраничный вывод
Список из сотен статей не выводят целиком — его делят на страницы. В CakePHP для этого есть метод контроллера paginate() и помощник шаблонов Paginator: первый берёт из базы нужную порцию записей, второй рисует ссылки на страницы.
В контроллере
// src/Controller/ArticlesController.php
public function index(): void
{
$articles = $this->paginate($this->Articles->find());
$this->set(compact('articles'));
}Вместо ->all() запрос передают в paginate(). По умолчанию он возвращает 20 записей и сам читает номер страницы из адреса: /articles?page=2.
Ссылки на страницы
Добавьте в конец templates/Articles/index.php:
<nav>
<?= $this->Paginator->prev('← Назад') ?>
<?= $this->Paginator->numbers() ?>
<?= $this->Paginator->next('Вперёд →') ?>
</nav>Под списком появятся номера страниц и ссылки «Назад» и «Вперёд». Цикл foreach по $articles остаётся прежним.
Настройки
// src/Controller/ArticlesController.php
protected array $paginate = [
'limit' => 10,
'order' => ['Articles.created' => 'DESC'],
];Свойство $paginate задаёт размер страницы и сортировку по умолчанию для всех действий контроллера. Теперь на странице десять статей, свежие сверху.
| Настройка | Что задаёт |
|---|---|
limit | Записей на странице |
maxLimit | Наибольшее значение limit, которое можно передать в адресе |
order | Сортировка по умолчанию |
sortableFields | Столбцы, по которым разрешена сортировка |
Счётчик
<p><?= $this->Paginator->counter('Страница {{page}} из {{pages}}, всего статей: {{count}}') ?></p>Слова в двойных фигурных скобках заменяются числами: «Страница 2 из 5, всего статей: 48».
Сортировка по столбцу
<table>
<tr>
<th><?= $this->Paginator->sort('title', 'Заголовок') ?></th>
<th><?= $this->Paginator->sort('created', 'Дата') ?></th>
</tr>
</table>Заголовок столбца превращается в ссылку вида /articles?sort=title&direction=asc. Первый щелчок сортирует по возрастанию, второй — по убыванию; paginate() читает эти параметры сам.
Вместе с условиями
public function index(): void
{
$query = $this->Articles->find()->where(['published' => true]);
$this->set('articles', $this->paginate($query));
}В paginate() можно передать любой запрос: с условиями, со связями через contain(), со своим методом поиска.
Частая ошибка
Если задан список sortableFields, сортировку по столбцам вне списка CakePHP молча игнорирует — это защита от произвольных значений в адресе. Когда заголовок-ссылка «не сортирует», добавьте столбец в список: 'sortableFields' => ['title', 'created'].