Installation
composer require bunta/datatablesbundle
Add to config/bundles.php:
Bunta\DatatablesBundle\SgDatatablesBundle::class => ['all' => true],
Enable in Routing
Add to config/routes.yaml:
sg_datatables:
resource: "@SgDatatablesBundle/Resources/config/routing.yml"
prefix: /datatables
First Use Case
Annotate an entity (e.g., src/Entity/User.php):
use Bunta\DatatablesBundle\Annotation\DataTable;
use Bunta\DatatablesBundle\Annotation\Column;
/**
* @DataTable
*/
class User
{
/**
* @Column(name="name", type="string")
*/
private $name;
}
Access via /datatables/user with GET params:
$.ajax({
url: '/datatables/user',
data: { search: { value: 'John' } }
});
CRUD Integration
DataTable annotation on entities to auto-generate API endpoints.POST /datatables/user/_action):
// src/Controller/UserDataTableController.php
use Bunta\DatatablesBundle\Controller\DataTableController;
class UserDataTableController extends DataTableController
{
public function actionEdit($id)
{
$user = $this->getDoctrine()->getRepository(User::class)->find($id);
// Custom logic...
}
}
Column Customization
config/packages/sg_datatables.yaml):
sg_datatables:
columns:
User:
email: { type: "email", searchable: true }
Column annotation for per-property overrides.Server-Side Processing
DataTableBuilder for complex queries:
$builder = $this->get('sg_datatables.builder');
$query = $builder->createQueryBuilder(User::class)
->add('where', 'u.active = :active', ['active' => true])
->getQuery();
Frontend Integration
$('#user-table').DataTable({
ajax: '/datatables/user',
columns: [
{ data: 'name' },
{ data: 'email' }
]
});
preFlush/postLoad for dynamic data (e.g., computed columns).// src/Security/Voter/DataTableVoter.php
public function supportsAttribute($attribute)
{
return $attribute === 'DATATABLE_ACCESS';
}
sg_datatables.cache_provider (default: null).Annotation Parsing
autoload is misconfigured.composer dump-autoload runs post-install.Doctrine Mismatches
Column annotations on non-Doctrine properties (e.g., getFullName()) cause errors.type="method" and specify the method name:
/**
* @Column(name="full_name", type="method")
*/
public function getFullName() { ... }
Routing Conflicts
/datatables/{entity} clashes with custom routes.config/routes.yaml:
sg_datatables:
path: /api/datatables
Pagination Limits
length (10) may be too low for large datasets.sg_datatables:
default_length: 100
Enable Verbose Logging
Add to config/packages/dev/sg_datatables.yaml:
sg_datatables:
debug: true
Logs SQL queries and processing steps to var/log/dev.log.
Check QueryBuilder
Dump the generated QueryBuilder in a controller:
$builder = $this->get('sg_datatables.builder');
$qb = $builder->createQueryBuilder(User::class);
dump($qb->getDQL());
Custom Column Types
Extend Bunta\DatatablesBundle\Column\ColumnTypeInterface:
class CustomType implements ColumnTypeInterface
{
public function getType() { return 'custom'; }
public function getSearchCondition($value, $alias) {
return "$alias LIKE :val";
}
}
Register in services:
services:
sg_datatables.type.custom:
class: App\Column\CustomType
tags: [sg_datatables.type]
Post-Process Responses
Subscribe to sg_datatables.post_process event:
// src/EventListener/DataTableListener.php
public function onPostProcess(PostProcessEvent $event)
{
$data = $event->getData();
$data['custom_field'] = 'value';
$event->setData($data);
}
Bind in services.yaml:
services:
App\EventListener\DataTableListener:
tags: [kernel.event_listener, sg_datatables.post_process]
Override Default Templates
Copy vendor/bunta/datatablesbundle/Resources/views/ to templates/bundles/sgdatatables/ and modify.
How can I help you explore Laravel packages today?