Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Постраничный вывод

Список из сотен статей не выводят целиком — его делят на страницы. В 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'].

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.