📖 Класс Paginator
Paginator — это сервис для разбиения результатов запроса (pbQuery) на страницы. Он автоматически считает количество записей, текущую и последнюю страницу, а также формирует список элементов. Класс поддерживает:
- 🔢 получение данных постранично (
items(),total(),currentPage()и т.д.); - 🖼 вывод через шаблон (
renderItem,view); - 🔗 генерацию навигации (
links()); - ⚡ работу через AJAX (если включена системная настройка
pageblocks_load_scripts).
📰 Выводим новости
🚦 Маршруты
Для примера с новостями нам нужно зарегистрировать два маршрута:
// web.php (routes)
route('/news', 'NewsController@index')->name('news.index');
route('/news/pagination', 'NewsController@pagination')->name('news.pagination');news.index— вывод новостей со встроенной пагинацией;news.pagination— возвращает данные для AJAX-запроса.
🎛 Контроллер
Пример контроллера NewsController с двумя методами:
class NewsController
{
// 1. Метод для вывода новостей
public function index()
{
$paginator = query(\modResource::class)
->where(['template' => 5, 'published' => 1])
->orderBy('publishedon', 'desc')
->paginate(5)
->route('news.pagination'); // маршрут для ajax-запросов
return view('file:templates/news', [
'paginator' => $paginator,
]);
}
// 2. Метод для получения данных (AJAX)
public function pagination()
{
$paginator = query(modResource::class)
->where(['template' => 5, 'published' => 1])
->orderBy('publishedon', 'desc')
->paginate(5);
return array_merge($paginator->toArray(), [
'links' => $paginator->links(), // html-код постраничной навигации
'data' => $paginator->renderItem('file:chunks/news/item.tpl'), // готовая верстка элементов
]);
}
}🖼 Шаблон новостей
Файл: templates/news.tpl
<ul>
{foreach $paginator->items() as $item}
<li>
<a href="{$item.uri}">{$item.pagetitle}</a>
<span class="date">{$item.publishedon|date_format:"%d.%m.%Y"}</span>
</li>
{/foreach}
</ul>
<div class="pagination" pb-pagination>
{$paginator->links()}
</div>🧩 Шаблон одного элемента
Файл: chunks/news/item.tpl
<li>
<a href="{$uri}">{$pagetitle}</a>
<span class="date">{$publishedon|date_format:"%d.%m.%Y"}</span>
</li>🔄 Работа через AJAX
Если в системных настройках включено pageblocks_load_scripts, то блок с пагинацией:
<div class="pb-pagination" pb-pagination>
{$paginator->links()}
</div>автоматически подхватится JavaScript-классом pbPagination. При клике на ссылку будет отправлен AJAX-запрос к маршруту news.pagination, и список новостей обновится без перезагрузки страницы.
📦 Формат ответа (метод pagination)
Метод pagination() возвращает JSON с такими данными:
{
"success": true,
"total": 42, // общее количество новостей
"count": 5, // количество элементов на текущей странице
"per_page": 5, // сколько элементов на страницу
"current_page": 2, // текущая страница
"last_page": 9, // всего страниц
"from": 6, // порядковый номер первой новости на странице
"to": 10, // порядковый номер последней новости на странице
"data": [ ... ], // массив новостей (результат выборки)
"links": "<ul>...</ul>", // html-код постраничной навигации
"data": "<li>...</li><li>...</li>" // готовая верстка элементов (chunk)
}👉 Обрати внимание: ключ data здесь перекрывается —
- первый
dataидёт от$paginator->toArray()(массив элементов), - второй
data— это HTML-разметка списка (renderItem).
Таким образом, фронтенд может либо работать с JSON-данными, либо сразу вставлять готовую разметку.
↕️ Сортировка
Теперь мы хотим дать пользователю возможность выбирать, как сортировать новости: по дате или по заголовку, и в каком направлении (ASC/DESC).
Для этого метод pagination примет объект Request:
use Boshnik\PageBlocks\Http\Request;
class NewsController
{
public function pagination(Request $request)
{
// определяем параметры сортировки
$sortby = $request->get('sortby', 'publishedon'); // поле сортировки
$sortdir = $request->get('sortdir', 'desc'); // направление сортировки
$paginator = query(modResource::class)
->where(['template' => 5, 'published' => 1])
->orderBy($sortby, $sortdir)
->paginate(5);
return array_merge($paginator->toArray(), [
'links' => $paginator->links(),
'data' => $paginator->renderItem('file:chunks/news/item.tpl'),
]);
}
}🖼 Верстка с селектом сортировки
В шаблоне новостей (templates/news.tpl) добавим селект с вариантами сортировки:
<div pb-sort>
<label for="sort">Сортировка:</label>
<select name="sort">
<option value="publishedon-desc">Дате (убывание)</option>
<option value="publishedon-asc">Дате (возрастание)</option>
<option value="pagetitle-desc">Заголовку (убывание)</option>
<option value="pagetitle-asc">Заголовку (возрастание)</option>
</select>
</div>
<ul id="news-list">
{foreach $paginator->items() as $item}
<li>
<a href="{$item.uri}">{$item.pagetitle}</a>
<span class="date">{$item.publishedon|date_format:"%d.%m.%Y"}</span>
</li>
{/foreach}
</ul>
<div class="pagination" pb-pagination>
{$paginator->links()}
</div>🔄 Как это работает
- Пользователь выбирает вариант сортировки в селекте.
- JavaScript отправляет AJAX-запрос на маршрут
news.pagination, добавляяsortbyиsortdirв параметры. - Контроллер использует их при построении запроса.
- Ответ возвращается в JSON, обновляется список и пагинация.