Installation:
composer require mmucklo/grid-bundle
Accept the recipe prompt (y) to auto-configure the bundle.
Enable the Bundle:
Add to config/bundles.php:
return [
// ...
Mmucklo\GridBundle\MmuckloGridBundle::class => ['all' => true],
];
First Use Case:
Create a controller action to render a grid for an entity (e.g., User):
use Mmucklo\GridBundle\Controller\GridController;
class UserController extends GridController
{
public function gridAction()
{
return $this->grid('App\Entity\User');
}
}
Route it in config/routes.yaml:
user_grid:
path: /users/grid
controller: App\Controller\UserController::gridAction
Template Setup:
Extend the base template (MmuckloGridBundle::grid.html.twig) in your project:
{% extends 'MmuckloGridBundle::grid.html.twig' %}
{% block grid_title %}Users{% endblock %}
Frontend Dependencies: Ensure jQuery and DataTables (recommended) are loaded in your layout:
<!-- resources/public/js/jquery.js -->
<!-- resources/public/js/jquery.datatables.js -->
Dynamic Grid Configuration:
Override grid settings via YAML (config/packages/mmucklo_grid.yaml):
mmucklo_grid:
grids:
App\Entity\User:
columns:
- { name: 'id', label: 'ID' }
- { name: 'email', label: 'Email' }
actions:
- { route: 'user_show', label: 'View' }
datatables:
order: [[0, 'desc']] # Default sort
Custom Column Rendering: Use Twig filters or custom renderers:
{# In your extended template #}
{% set column = column|default({}) %}
{% if column.name == 'status' %}
{{ status|renderStatus(column) }}
{% else %}
{{ value }}
{% endif %}
Action Buttons: Define actions in YAML or dynamically:
actions:
- { route: 'user_edit', label: 'Edit', icon: 'pencil' }
- { route: 'user_delete', label: 'Delete', icon: 'trash', confirm: true }
Filtering: Leverage DataTables server-side processing (recommended) or client-side filters:
// In your controller, extend GridController
public function configureGrid($gridName)
{
$this->grid->addFilter('active', 'boolean', 'Active');
}
Integration with Forms: Use the grid to populate forms or vice versa:
{# Link to edit action #}
<a href="{{ path('user_edit', { id: row.id }) }}">Edit</a>
Multi-Entity Grids: Combine multiple entities with custom joins:
grids:
App\Entity\Order:
columns:
- { name: 'customer.name', label: 'Customer' }
Lazy-Loading: Use AJAX for large datasets:
$(document).ready(function() {
$('#user-grid').DataTable({
ajax: {
url: '/users/grid',
type: 'POST',
data: function(d) {
d._token = '{{ csrf_token() }}';
}
}
});
});
Event Listeners: Hook into grid events (e.g., post-render):
// src/EventListener/GridListener.php
public function onGridRender(GridEvent $event)
{
$event->getGrid()->addJs('console.log("Grid rendered!");');
}
Register in services.yaml:
services:
App\EventListener\GridListener:
tags:
- { name: kernel.event_listener, event: mmucklo.grid.render, method: onGridRender }
Entity Not Found:
config/packages/doctrine.yaml under orm.entities.DataTables Not Loading:
{{ encore_entry_link_tags('app') }} {# If using Webpack #}
<link rel="stylesheet" href="https://cdn.datatables.net/1.10.21/css/jquery.dataTables.css">
<script src="https://cdn.datatables.net/1.10.21/js/jquery.dataTables.js"></script>
Server-Side Processing Errors:
_token in AJAX requests.public function gridAction(Request $request)
{
$this->grid->handleRequest($request);
return $this->grid->render();
}
Column Mismatches:
getter or setter in column definitions:
columns:
- { name: 'fullName', getter: 'getFullName' }
Pagination Issues:
$this->grid->setPagination(20);
$this->grid->setPaginator(new DoctrinePaginator($query, false));
Enable Debug Mode:
Set debug: true in config/packages/mmucklo_grid.yaml to log SQL queries and grid events.
Check Generated HTML: Inspect the rendered grid to verify column names, actions, and filters:
{% dump(grid) %}
Log Grid Events: Use Symfony’s profiler to trace grid events:
$eventDispatcher->addListener(GridEvents::PRE_RENDER, function(GridEvent $event) {
\Symfony\Component\Debug\Debug::dump($event->getGrid()->getConfiguration());
});
Default Grid Name: The grid name defaults to the fully qualified entity class name. Override in YAML:
grids:
App\Entity\User:
name: 'user_list'
Action Confirmation:
Use confirm in actions to show a SweetAlert or Bootstrap modal:
actions:
- { route: 'user_delete', label: 'Delete', confirm: 'Are you sure?' }
Custom Templates:
Override the base template (grid.html.twig) or partials (e.g., actions.html.twig) in:
templates/MmuckloGridBundle/grid/
MongoDB ODM:
Ensure your GridBuilder extends MongoGridBuilder and use ODM-specific column types:
columns:
- { name: 'createdAt', type: 'date', label: 'Created At' }
Custom Grid Builder:
Extend Mmucklo\GridBundle\Grid\GridBuilder to add logic:
class CustomGridBuilder extends GridBuilder
{
public function addCustomColumn($name, $options)
{
$this->columns[$name] = array_merge(['type' => 'custom'], $options);
}
}
Register as a service:
services:
App\Grid\CustomGridBuilder:
parent: mmucklo.grid.grid_builder
tags: ['mmucklo.grid.grid_builder']
Dynamic Column Generation: Use a compiler pass to inject columns at runtime:
public function process(ContainerBuilder $container)
{
$definition = $container->findDefinition('mmucklo.grid.grid_builder');
$definition->addMethodCall('addDynamicColumn', ['dynamic_col', ['label' => 'Dynamic']]);
}
Plugin System: Create a plugin interface to extend grid functionality:
interface GridPluginInterface
{
public function apply(GridBuilder $grid);
}
Register plugins in services.yaml:
services:
App\Grid\Plugin\ExportPlugin:
tags: ['mmucklo.grid.plugin']
How can I help you explore Laravel packages today?