A minimal, framework-agnostic grid helper for sortable table headers, pagination links, and result summary text.
Install the package with Composer:
composer require piko/griduse Piko\Grid;
$rows = [
['id' => 1, 'firstname' => 'John', 'lastname' => 'Lennon'],
['id' => 2, 'firstname' => 'Elvis', 'lastname' => 'Presley'],
['id' => 3, 'firstname' => 'Mick', 'lastname' => 'Jagger'],
];
$grid = new Grid([
'baseRoute' => '/admin/users',
'query' => $_GET,
'countItems' => count($rows),
'totalItems' => 100,
'itemsPerPage' => 10,
'currentPage' => (int)($_GET['page'] ?? 1),
// optional: 'language' => 'fr',
]);
?>
<table class="table">
<thead>
<tr>
<th><?= $grid->sortColumn('id', 'ID') ?></th>
<th><?= $grid->sortColumn('firstname', 'First name') ?></th>
<th><?= $grid->sortColumn('lastname', 'Last name') ?></th>
</tr>
</thead>
<tbody>
<?php foreach ($rows as $row): ?>
<tr>
<td><?= $row['id'] ?></td>
<td><?= $row['firstname'] ?></td>
<td><?= $row['lastname'] ?></td>
</tr>
<?php endforeach ?>
</tbody>
</table>
<div class="row">
<div class="col"><?= $grid->info() ?></div>
<div class="col"><?= $grid->paginator() ?></div>
</div>| Parameter | Type | Default | Description |
|---|---|---|---|
baseRoute |
string |
'' |
Base URI used to generate sort and pagination links (for example: /admin/users or /admin/users?status=active). |
query |
array<string,mixed> |
[] |
Current query parameters to preserve across generated links (sort, filters, etc.). |
countItems |
int |
0 |
Number of items in the current page/result set. |
totalItems |
int |
0 |
Total number of matching items across all pages. |
itemsPerPage |
int |
0 |
Items per page. |
currentPage |
int |
0 |
Current page number (1-based). |
language |
string |
'en' |
Optional language used only when no global Piko\I18n instance is already available. |
Returns an HTML link for a sortable header.
- If the column is already sorted, direction toggles between
ASCandDESC. - If not sorted yet, it initializes with
ASC. - Existing query parameters are preserved.
Returns a configured paginator instance for the current grid state.
Returns localized summary text:
No resultswhen no rows are available.Results {from} to {to} of {total}otherwise.
Typical generated URLs use:
pagefor paginationsort[column]=ASC|DESCfor sorting
Examples:
?page=2?sort[lastname]=ASC?sort[id]=DESC&page=3
Piko Grid uses piko/i18n for messages.
Built-in translations include:
- English (default source strings)
- French (
src/messages/fr.php)
You can force a language when creating the grid:
$grid = new Grid([
// ...
'language' => 'fr',
]);- PHP
>= 8.0 piko/i18njasongrimes/paginator
- You want a lightweight, framework-agnostic grid helper.
- You prefer explicit query handling (
sort,page, filters) over widget conventions. - You already control rendering in PHP templates and only need sorting links, pagination wiring, and result info.
- You want minimal dependencies and predictable behavior.
- You need built-in column filters, formatters, action columns, or rich cell rendering.
- You want tight integration with ORM/model layers and data providers.
- You need advanced admin features out of the box (AJAX/PJAX updates, bulk actions, complex column configuration).
- Your team prefers convention-heavy components that reduce custom template code.
In short: piko/grid optimizes for simplicity, portability, and control, while higher-level grids (for example, Yii GridView-style components) optimize for batteries-included features.
Run static checks and coding standards:
composer testOr run them separately:
composer phpcs
composer phpstanContributions are welcome.
- Fork the repository
- Create a feature/fix branch
- Run quality checks
- Open a pull request
LGPL-3.0-or-later. See LICENSE.txt (or package metadata) for details.