📖 Paginator Class
Paginator is a service for paginating the results of a pbQuery. It automatically calculates the total number of records, the current and last page, and generates a list of items. The class supports:
- 🔢 Getting paginated data (
items(),total(),currentPage(), etc.); - 🖼 Rendering via templates (
renderItem,view); - 🔗 Navigation link generation (
links()); - ⚡ AJAX functionality (if the
pageblocks_load_scriptssystem setting is enabled).
📰 Displaying News Articles
🚦 Routes
For the news example, we need to register two routes:
// web.php (routes)
route('/news', 'NewsController@index')->name('news.index');
route('/news/pagination', 'NewsController@pagination')->name('news.pagination');news.index- displays news with built-in pagination;news.pagination- returns data for AJAX requests.
🎛 Controller
Example NewsController with two methods:
class NewsController
{
// 1. Method to display news
public function index()
{
$paginator = query(\modResource::class)
->where(['template' => 5, 'published' => 1])
->orderBy('publishedon', 'desc')
->paginate(5)
->route('news.pagination'); // route for ajax requests
return view('file:templates/news', [
'paginator' => $paginator,
]);
}
// 2. Method to get data (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 pagination navigation
'data' => $paginator->renderItem('file:chunks/news/item.tpl'), // pre-rendered item markup
]);
}
}🖼 News Template
File: 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>🧩 Single Item Template
File: chunks/news/item.tpl
<li>
<a href="{$uri}">{$pagetitle}</a>
<span class="date">{$publishedon|date_format:"%d.%m.%Y"}</span>
</li>🔄 AJAX Functionality
If the pageblocks_load_scripts system setting is enabled, the pagination block:
<div class="pb-pagination" pb-pagination>
{$paginator->links()}
</div>will be automatically handled by the pbPagination JavaScript class. When a link is clicked, an AJAX request will be sent to the news.pagination route, and the news list will update without a page reload.
📦 Response Format (pagination method)
The pagination() method returns JSON with the following data:
{
"success": true,
"total": 42, // total number of news articles
"count": 5, // number of items on the current page
"per_page": 5, // items per page
"current_page": 2, // current page number
"last_page": 9, // total number of pages
"from": 6, // sequence number of the first news item on the page
"to": 10, // sequence number of the last news item on the page
"data": [ ... ], // array of news items (query results)
"links": "<ul>...</ul>", // html pagination navigation
"data": "<li>...</li><li>...</li>" // pre-rendered item markup (chunk)
}👉 Note: The data key is overwritten here -
- the first
datacomes from$paginator->toArray()(array of items), - the second
datais the HTML markup for the list (renderItem).
This way, the frontend can either work with JSON data or directly insert the pre-rendered markup.
↕️ Sorting
Now we want to give the user the ability to choose how to sort the news: by date or by title, and in which direction (ASC/DESC).
To do this, the pagination method will accept a Request object:
use Boshnik\PageBlocks\Http\Request;
class NewsController
{
public function pagination(Request $request)
{
// determine sorting parameters
$sortby = $request->get('sortby', 'publishedon'); // sort field
$sortdir = $request->get('sortdir', 'desc'); // sort direction
$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'),
]);
}
}🖼 Template with Sort Select
In the news template (templates/news.tpl), let's add a select dropdown with sorting options:
<div pb-sort>
<label for="sort">Sort by:</label>
<select name="sort">
<option value="publishedon-desc">Date (Descending)</option>
<option value="publishedon-asc">Date (Ascending)</option>
<option value="pagetitle-desc">Title (Descending)</option>
<option value="pagetitle-asc">Title (Ascending)</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>🔄 How It Works
- The user selects a sorting option from the dropdown.
- JavaScript sends an AJAX request to the
news.paginationroute, addingsortbyandsortdiras parameters. - The controller uses them when building the query.
- The response is returned as JSON, updating both the list and the pagination.