Installation:
composer require 2lenet/dashboard2-bundle
Add the bundle to config/bundles.php (if not auto-discovered) and register routes in config/routes.yaml:
dashboard_widgets:
resource: "@LleDashboardBundle/Resources/config/routes.yaml"
Run migrations to create the widgets table:
php bin/console make:migration
php bin/console doctrine:migrations:migrate
First Widget: Use the maker command to scaffold a basic widget:
php bin/console make:widget
Follow prompts to define a name (e.g., user_stats). The command generates:
AbstractWidget (e.g., src/Widget/UserStatsWidget.php).templates/widgets/user_stats.html.twig).Register the Widget:
Add your widget to the dashboard configuration in config/packages/lle_dashboard.yaml:
lle_dashboard:
widgets:
- Lle\DashboardBundle\Widget\UserStatsWidget
Access the Dashboard:
Visit /dashboard (or your configured route) to see the widget rendered.
Widget Development Cycle:
make:widget to generate boilerplate.render() to fetch data (e.g., via repository or API).getData()).Data Fetching:
getData() to return structured data for the template:
public function getData(): array
{
return [
'users' => $this->userRepository->findActiveUsers(),
];
}
@cache in Twig or AbstractWidget's built-in caching.Dynamic Widgets:
make:workflow-widget to integrate with Symfony’s workflow component.publish workflow transition.Configuration:
config/packages/lle_dashboard.yaml:
widgets:
- { class: App\Widget\UserStatsWidget, options: { limit: 10 } }
getOptions():
$limit = $this->getOptions()['limit'] ?? 5;
Templating:
user_stats.html.twig):
{% for user in data.users %}
<div>{{ user.username }} ({{ user.lastLogin|date('Y-m-d') }})</div>
{% endfor %}
@LleDashboard/widget.html.twig) for consistent styling.Role-Based Visibility:
supportsRole():
public function supportsRole(string $role): bool
{
return $role === 'ROLE_ADMIN';
}
config/packages/lle_dashboard.yaml:
widgets:
- { class: App\Widget\AdminWidget, roles: ['ROLE_ADMIN'] }
Migration Warnings:
WidgetNotFoundException.php bin/console doctrine:migrations:migrate post-install.Caching Quirks:
# config/packages/lle_dashboard.yaml
cache: false
invalidateCache() in widgets that need real-time data:
public function render(): string
{
$this->invalidateCache(); // Force refresh
// ...
}
Template Paths:
templates/widgets/{widget_name}.html.twig or configure custom paths in AbstractWidget.Dependency Injection:
getService():
public function __construct(private UserRepository $userRepository) {}
Route Conflicts:
config/routes.yaml:
dashboard:
path: /admin/dashboard
controller: LleDashboardBundle:Dashboard:index
Widget Reusability:
AbstractChartWidget).Performance:
render() instead of getData() if caching is enabled.AbstractWidget::isCacheValid() to skip expensive operations when cached.Testing:
public function testRender()
{
$widget = new UserStatsWidget($this->entityManager);
$html = $widget->render();
$this->assertStringContainsString('Active Users', $html);
}
Debugging:
config/packages/dev/lle_dashboard.yaml:
debug: true
php bin/console debug:widgets (if supported).Extending the Bundle:
vendor/lle/dashboard-bundle/templates/ to your project’s templates/ directory.AbstractWidget to add custom methods (e.g., getWidgetType() for categorization).Static Dashboards:
StaticDashboard component:
# config/packages/lle_dashboard.yaml
static_dashboard:
enabled: true
widgets:
- { template: 'widgets/static_home.html.twig' }
How can I help you explore Laravel packages today?