Installation
composer require aygon/data-list-bundle
Add to AppKernel.php (Symfony 2.x):
new Aygon\DataListBundle\AygonDataListBundle(),
First Use Case: Basic Data List Define a list in a controller:
use Aygon\DataListBundle\DataList;
public function listAction()
{
$list = new DataList();
$list->setModel('AppBundle:Post'); // Doctrine entity
$list->setFields(['title', 'content']); // Fields to display
$list->setOrder('createdAt', 'DESC');
return $this->render('AppBundle:Post:list.html.twig', [
'list' => $list->getData(),
]);
}
Twig Template
{% for item in list %}
<tr>
<td>{{ item.title }}</td>
<td>{{ item.content }}</td>
</tr>
{% endfor %}
Pagination
$list->setItemsPerPage(10); // Default: 20
Filtering with Forms
$list->setFilterForm([
'title' => ['type' => 'text', 'label' => 'Search Title'],
'published' => ['type' => 'checkbox', 'label' => 'Published Only'],
]);
Render the form in Twig:
{{ form_start(list.filterForm) }}
{{ form_widget(list.filterForm) }}
<button type="submit">Filter</button>
{{ form_end(list.filterForm) }}
Dynamic Field Selection
$list->setFields(['title', 'createdAt']);
$list->addField('author'); // Add dynamically
Custom Query Logic Override the query builder:
$list->setQueryBuilder(function ($qb) {
$qb->leftJoin('p.user', 'u');
return $qb;
});
Bulk Actions
$list->setBulkActions([
'delete' => ['label' => 'Delete Selected'],
'publish' => ['label' => 'Publish'],
]);
Handle actions in the controller:
if ($list->isBulkAction('delete')) {
$list->deleteSelected();
}
Symfony Forms Integration
Use Symfony’s FormBuilder for complex filters:
$builder = $this->createFormBuilder();
$builder->add('title', TextType::class);
$list->setFilterForm($builder->getForm());
Event Listeners Attach listeners for pre/post actions:
$list->addPreAction(function ($list) {
$list->addFilter('status', 'published');
});
API Responses Serialize data for APIs:
$data = $list->getData();
$serializer = $this->get('serializer');
return new JsonResponse($serializer->serialize($data, 'json'));
Caching Cache filtered results:
$cache = $this->get('cache');
$key = 'list_' . md5(serialize($list->getFilters()));
if (!$cache->has($key)) {
$data = $list->getData();
$cache->set($key, $data, 3600);
} else {
$data = $cache->get($key);
}
Deprecated Symfony 2.x
No Built-in Security
deleteSelected) lack CSRF protection by default.@Security annotations or validate requests manually.Query Builder Overrides
setQueryBuilder may conflict with pagination/filtering logic.addPreAction to modify the query.Field Naming Collisions
id or createdAt may clash with Doctrine metadata.$list->setFields(['p.title as post_title']);
Filter Form Submission
$list->handleRequest($request) in the controller.Enable Query Logging
$list->setDebug(true); // Logs SQL queries
Dump Filters
dump($list->getFilters()); // Debug applied filters
Check Form Errors
{% if list.filterForm.errors %}
<div class="alert">{{ list.filterForm.errors|join(', ') }}</div>
{% endif %}
Custom Field Types Override rendering for fields:
{% block aygon_data_list_field_default %}
{{ item[field] }}
{% endblock %}
Add Actions Extend bulk actions:
$list->addBulkAction('archive', function ($ids) {
// Custom logic
});
Modify Data Before Rendering
$list->addPostAction(function ($data) {
foreach ($data as &$item) {
$item->formattedDate = $item->createdAt->format('Y-m-d');
}
return $data;
});
Override Twig Templates
Copy templates from vendor/aygon/data-list-bundle/Resources/views/ to your bundle’s Resources/views/AygonDataListBundle/ to customize.
Pro Tip: For complex projects, wrap DataList in a service to centralize configuration and reuse logic across controllers.
How can I help you explore Laravel packages today?