rougin / gable
A simple HTML table generator in PHP.
Requires
- php: >=5.3.0
- psr/http-message: ~1.0
Requires (Dev)
- phpunit/phpunit: ~4.2|~5.7|~6.0|~7.0|~8.0|~9.0
- sanmai/phpunit-legacy-adapter: ~6.1|~8.0
This package is auto-updated.
Last update: 2025-08-24 08:35:26 UTC
README
A simple HTML table generator in PHP.
Installation
Install the package using Composer:
$ composer require rougin/gable
Basic usage
The Table
class is the cornerstone of this package, providing a simple and intuitive API for generating HTML tables:
// index.php use Rougin\Gable\Table; $table = new Table; // Define the table columns --- $table->newColumn(); $table->setCell('Name'); $table->setCell('Age'); // ---------------------------- // Populate the table with data --- $table->newRow(); $table->setCell('John Doe'); $table->setCell('30'); $table->newRow(); $table->setCell('Jane Doe'); $table->setCell('28'); // -------------------------------- // Use the "__toString" method --- echo $table; // -------------------------------
The code above will generate the following HTML output:
<table> <thead> <tr> <th>Name</th> <th>Age</th> </tr> </thead> <tbody> <tr> <td>John Doe</td> <td>30</td> </tr> <tr> <td>Jane Doe</td> <td>28</td> </tr> </tbody> </table>
Method chaining
For a more fluent and expressive way of building tables, method chaining is also supported:
// index.php use Rougin\Gable\Table; $table = new Table; echo $table->newColumn() ->setCell('Name') ->setCell('Age') ->newRow() ->setCell('John Doe') ->setCell('30') ->newRow() ->setCell('Jane Doe') ->setCell('28');
Customization
The appearance of the table can be customized by adding CSS classes, inline styles, and other attributes to columns, rows, and cells:
// index.php use Rougin\Gable\Table; $table = new Table; // Adds CSS classes to the <table> element --- $table->setClass('table table-striped'); // ------------------------------------------ // Adds a CSS class to the <thead> row --- $table->newColumn('fw-bold'); // -------------------------------------- // Aligns to center then adds a CSS class to the cell --- $table->setCell('Name', 'center', 'text-uppercase'); // ------------------------------------------------------ // Aligns cell to the right ---- $table->setCell('Age', 'right'); // ----------------------------- // Adds a CSS class to the <tr> element --- $table->newRow('table-primary'); // ---------------------------------------- $table->setCell('John Doe'); $table->setCell('30'); $table->newRow(); // Adds a CSS class to the current cell -------- $table->setCell('Jane Doe', null, 'fst-italic'); // --------------------------------------------- $table->setCell('28'); echo $table;
<table class="table table-striped"> <thead> <tr class="fw-bold"> <th align="center" class="text-uppercase">Name</th> <th align="right">Age</th> </tr> </thead> <tbody> <tr class="table-primary"> <td>John Doe</td> <td>30</td> </tr> <tr> <td class="fst-italic">Jane Doe</td> <td>28</td> </tr> </tbody> </table>
Actions
Actions can be added to each row, allowing for operations like updating or deleting records. The withUpdateAction
and withDeleteAction
methods provide a convenient way to add the specified common actions:
// index.php use Rougin\Gable\Table; $table = new Table; $table->newColumn(); $table->setCell('Name'); $table->setCell('Age'); // Adds an "Action" column --- $table->withActions(); // --------------------------- // Assumes "alpinejs" is integrated -------- $table->withUpdateAction('update(item.id)'); $table->withDeleteAction('delete(item.id)'); // ----------------------------------------- $table->newRow(); $table->setCell('John Doe'); $table->setCell('30'); $table->newRow(); $table->setCell('Jane Doe'); $table->setCell('28'); echo $table;
<table> <thead> <tr> <th>Name</th> <th>Age</th> <th>Action</th> </tr> </thead> <tbody> <tr> <td>John Doe</td> <td>30</td> <td> <div class="dropdown"> <button class="btn btn-primary btn-sm dropdown-toggle" type="button" data-bs-toggle="dropdown">Action</button> <div class="dropdown-menu dropdown-menu-end"> <div><a class="dropdown-item" href="javascript:void(0)" @click="update(item.id)">Update</a></div> <div><hr class="dropdown-divider"></div> <div><a class="dropdown-item text-danger" href="javascript:void(0)" @click="delete(item.id)">Delete</a></div> </div> </div> </td> </tr> <tr> <td>Jane Doe</td> <td>28</td> <td> <div class="dropdown"> <button class="btn btn-primary btn-sm dropdown-toggle" type="button" data-bs-toggle="dropdown">Action</button> <div class="dropdown-menu dropdown-menu-end"> <div><a class="dropdown-item" href="javascript:void(0)" @click="update(item.id)">Update</a></div> <div><hr class="dropdown-divider"></div> <div><a class="dropdown-item text-danger" href="javascript:void(0)" @click="delete(item.id)">Delete</a></div> </div> </div> </td> </tr> </tbody> </table>
Note
This is only works when integrated in alpinejs
.
Badges
Badges can be used to highlight certain information in a cell, such as a record's status.
// index.php use Rougin\Gable\Table; $table = new Table; $table->newColumn(); $table->setCell('Status') ->addBadge('Active', "item.status === 'active'", 'bg-success') ->addBadge('Inactive', "item.status === 'inactive'", 'bg-danger'); $table->setCell('Name'); $table->newRow(); // Placeholder for the badge --- $table->setCell(''); // ----------------------------- $table->setCell('John Doe'); echo $table;
<table> <thead> <tr> <th>Name</th> <th>Status</th> </tr> </thead> <tbody> <tr> <td>John Doe</td> <td> <template x-if="item.status === 'active'"> <span class="badge rounded-pill text-uppercase bg-success">Active</span> </template> <template x-if="item.status === 'inactive'"> <span class="badge rounded-pill text-uppercase bg-danger">Inactive</span> </template> </td> </tr> </tbody> </table>
Note
This is only works when integrated in alpinejs
.
Pagination
The Pagee
class provides a simple way to generate pagination links for a table:
// index.php use Rougin\Gable\Pagee; $pagee = new Pagee; $pagee->setTotal(100); // Total number of items $pagee->setLimit(10); // Items per page $pagee->setPage(2); // Current page $pagee->setLink('/users'); // Base URL for the links echo $pagee;
<div class="d-inline-block"> <ul class="pagination"> <li class="page-item"> <a class="page-link" href="/users?p=1&l=10"> <span>First</span> </a> </li> <li class="page-item"> <a class="page-link" href="/users?p=1&l=10"> <span>Previous</span> </a> </li> <li class="page-item"> <a class="page-link" href="/users?p=1&l=10"> <span>1</span> </a> </li> <li class="page-item active"> <a class="page-link" href="javascript:void(0)"> <span>2</span> </a> </li> <li class="page-item"> <a class="page-link" href="/users?p=3&l=10"> <span>3</span> </a> </li> <li class="page-item"> <a class="page-link" href="/users?p=4&l=10"> <span>4</span> </a> </li> <li class="page-item"> <a class="page-link" href="/users?p=5&l=10"> <span>5</span> </a> </li> <li class="page-item"> <a class="page-link" href="/users?p=6&l=10"> <span>6</span> </a> </li> <li class="page-item"> <a class="page-link" href="/users?p=7&l=10"> <span>7</span> </a> </li> <li class="page-item"> <a class="page-link" href="/users?p=8&l=10"> <span>8</span> </a> </li> <li class="page-item"> <a class="page-link" href="/users?p=9&l=10"> <span>9</span> </a> </li> <li class="page-item"> <a class="page-link" href="/users?p=10&l=10"> <span>10</span> </a> </li> <li class="page-item"> <a class="page-link" href="/users?p=3&l=10"> <span>Next</span> </a> </li> <li class="page-item"> <a class="page-link" href="/users?p=10&l=10"> <span>Last</span> </a> </li> </ul> </div>
Integration to alpinejs
For creating dynamic and interactive tables, Gable
provides a seamless integration with alpinejs. This allows for features like real-time data updates, loading indicators, and more:
// index.php use Rougin\Gable\Table; $table = new Table; // Sets the table with "users" for "alpinejs" --- $table->withAlpine('users'); // ---------------------------------------------- // Shows a loading indicator while data is being fetched --- $table->withLoading(); // --------------------------------------------------------- $table->newColumn(); $table->setCell('Name')->withName('name'); $table->setCell('Email')->withName('email'); echo $table;
This will generate a table that is bound to an alpinejs
component, ready to display dynamic data:
<table> <thead> <tr> <th>Name</th> <th>Email</th> </tr> </thead> <tbody> <template x-if="items.length === 0 && loading"> <template x-data="{ length: items && items.length ? items.length : 5 }" x-for="i in length"> <tr> <td class="align-middle placeholder-glow"><span class="placeholder col-12"></span></td> <td class="align-middle placeholder-glow"><span class="placeholder col-12"></span></td> </tr> </template> </template> <template x-if="items.length === 0 && empty"> <tr> <td colspan="2" class="align-middle text-center"><span>No items found.</span></td> </tr> </template> <template x-if="! loading && loadError"> <tr> <td colspan="2" class="align-middle text-center"><span>An error occured in getting the items.</span></td> </tr> </template> <template x-if="items && items.length > 0"> <template x-for="item in users"> <tr> <td x-text="item.name"></td> <td x-text="item.email"></td> </tr> </template> </template> </tbody> </table>
Available methods
The following methods are available in the Table
class for advanced customization:
newColumn($class = null, $style = null, $width = null)
- Adds a new
<tr>
element to the<thead>
.
newRow($class = null, $style = null, $width = null)
- Adds a new
<tr>
element to the<tbody>
.
setCell($value, $align = null, $class = null, $cspan = null, $rspan = null, $style = null, $width = null)
- Adds a new
<td>
element.
withActions($value = 'Action', ...)
- Adds a column for actions.
withAlpine($name = 'items', ...)
- Integrates the table with Alpine.js.
withDeleteAction($clicked, $name = 'Delete')
- Adds a
Delete
action.
withLoading($count = 5, $name = 'loading')
- Adds a loading indicator.
withUpdateAction($clicked, $name = 'Update')
- Adds an
Update
action.
withNoItemsText($text, $key = 'empty')
- Sets the text to display when there are no items in the table.
withLoadErrorText($text, $key = 'loadError')
- Sets the text to display when an error occurs while loading items.
Change log
See CHANGELOG for more recent changes.
Development
Includes tools for code quality, coding style, and unit tests.
Code quality
Analyze code quality using phpstan:
$ phpstan
Coding style
Enforce coding style using php-cs-fixer:
$ php-cs-fixer fix --config=phpstyle.php
Unit tests
Execute unit tests using phpunit:
$ composer test