Installation
composer require ekyna/table-bundle:0.1.*@dev
Add the bundle to app/AppKernel.php:
new Ekyna\Bundle\TableBundle\EkynaTableBundle(),
First Table Type
Create a table type class (e.g., src/Acme/DemoBundle/Table/Type/BrandType.php):
use Ekyna\Component\Table\AbstractTableType;
use Ekyna\Component\Table\TableBuilderInterface;
class BrandType extends AbstractTableType {
public function buildTable(TableBuilderInterface $tableBuilder) {
$tableBuilder
->addColumn('id', 'number')
->addColumn('name', 'text');
}
}
Render the Table in a Controller
use Ekyna\Bundle\TableBundle\Table\TableManager;
class DemoController extends Controller {
public function indexAction() {
$table = $this->get('ekyna_table.manager')->createTable('brand', 'AcmeDemoBundle');
return $this->render('AcmeDemo:Brand:index.html.twig', ['table' => $table]);
}
}
Twig Template
{{ table.render() }}
Table Definition
Extend AbstractTableType and implement buildTable() to define columns, filters, and sorting:
$tableBuilder
->addColumn('field', 'type', ['options'])
->addFilter('field', 'filter_type')
->setDefaultSort('field', 'asc');
Dynamic Data Binding
Use setData() in the controller to bind data to the table:
$table->setData($entityManager->getRepository('AcmeDemoBundle:Brand')->findAll());
Customizing Rows
Override configureRow() in your table type for per-row logic:
public function configureRow($view, $rowData, $rowIndex) {
$view->vars['custom_var'] = $rowData['name'] . '_custom';
}
Pagination & Limits Configure via Twig or controller:
{{ table.render({'limit': 10, 'page': request.query.page}) }}
Integration with Forms
Use addActionColumn() to embed buttons/links:
$tableBuilder->addActionColumn('actions', array(
'route' => 'brand_edit',
'routeParameters' => array('id' => 'id'),
'label' => 'Edit',
));
Reusable Table Types
Create base table types for shared logic (e.g., AbstractUserTableType) and extend them.
Event Listeners Attach listeners to modify table behavior:
$table->addListener(new CustomTableListener());
Custom Column Types
Extend AbstractColumnType for specialized columns (e.g., DateColumnType).
AJAX Integration
Use table.renderAsJson() for API responses:
return new JsonResponse($table->renderAsJson());
Theming
Override Twig templates in your bundle’s Resources/views/Table/ directory.
Bundle Registration
AppKernel.php.EkynaTableBundle is included in the $bundles array.Namespace Conflicts
use Ekyna\Component\Table\TableBuilder instead of TableBuilderInterface.TableBuilderInterface) for dependency injection.Data Binding
setData() expects an array of objects with properties matching column names.getters or normalize data:
$table->setData(array_map(function($brand) {
return (array) $brand;
}, $brands));
Sorting/Filtering
addColumn('field', 'type', ['data_key' => 'actual_property']) for custom mappings.Deprecated Methods
TableBuilder may lack addFilter).Enable Debug Mode
Set ekyna_table.debug: true in config to log table building:
ekyna_table:
debug: true
Inspect Table Structure Dump the table object in the controller:
dump($table->getDefinition());
Check Twig Variables
Use {{ dump(table) }} in templates to verify passed data.
Override Templates
Copy EkynaTableBundle:Table: templates to your bundle’s Resources/views/ to customize rendering.
Custom Column Types
Extend Ekyna\Component\Table\Column\AbstractColumnType to add new column behaviors (e.g., BooleanColumnType).
Table Events
Implement Ekyna\Component\Table\Event\TableEvents for pre/post-render hooks:
$table->addListener(new class implements TableEvents {
public function onPreRender(TableEvent $event) { ... }
});
Filter Providers
Create custom filter types by extending Ekyna\Component\Table\Filter\AbstractFilterType.
Configuration Overrides
Use setDefaultOptions() to enforce bundle-wide settings:
public function setDefaultOptions(OptionsResolverInterface $resolver) {
$resolver->setDefaults([
'default_limit' => 20,
'paginate' => true,
]);
}
Legacy Support
For Symfony 2.x compatibility, ensure your composer.json targets the correct PHP version:
"require": {
"php": "5.3.3-7.1",
"symfony/symfony": "2.3|2.7|2.8"
}
How can I help you explore Laravel packages today?