Installation
Run composer require 2lenet/dashboard-bundle in your Laravel project (note: this bundle is Symfony-based, but can be adapted for Laravel via Symfony Bridge or Laravel Mix).
Configuration
Add the bundle to config/services.yaml (or Laravel’s equivalent service provider binding):
App\Widgets\:
resource: '../src/Widgets'
tags: ['tkuska_dashboard.widget']
Register routes in routes.yaml (or Laravel’s routes/web.php):
require __DIR__.'/../vendor/tkuska/dashboard-bundle/Resources/config/routes.yaml';
Database Setup
Create and run a migration for the widget table:
php artisan make:migration create_widgets_table
Update the migration file to match the bundle’s expected schema (e.g., id, user_id, type, config, order).
Run:
php artisan migrate
First Widget
Create a widget class in src/Widgets/ extending AbstractWidget:
namespace App\Widgets;
use Tkuska\DashboardBundle\Widgets\AbstractWidget;
class ExampleWidget extends AbstractWidget {
public function getName() { return 'Example Widget'; }
public function getJsonSchema() { return []; } // Empty schema for now
public function support() { return true; }
}
Test the Dashboard
Visit /dashboard (or the route defined in the bundle) to see your widget in action.
Extending AbstractWidget
Override core methods to customize behavior:
getName(): Human-readable widget name (e.g., "User Stats").getJsonSchema(): Define configurable fields using JSON Schema. Example:
public function getJsonSchema() {
return [
'type' => 'object',
'properties' => [
'title' => ['type' => 'string', 'default' => 'Default Title'],
'limit' => ['type' => 'integer', 'default' => 10],
],
];
}
transformResponse(): Modify the widget’s output (e.g., wrap in a partial view or API response).Configuration Management
getConfigForm() to customize the admin UI for widget settings (rarely needed; default form works for JSON Schema).widget.config column (serialized JSON).Dynamic Loading
supportsAjax() to true for lazy-loaded widgets (e.g., heavy or API-dependent widgets).public function supportsAjax() { return true; }
Integration with Laravel
Twig_Environment) to Laravel’s container via AppServiceProvider:
public function register() {
$this->app->singleton('twig', function () {
return \Twig\Environment::newLoader(new \Twig\Loader\FilesystemLoader(__DIR__.'/../resources/views'));
});
}
routes/web.php:
Route::prefix('dashboard')->group(function () {
require __DIR__.'/../vendor/tkuska/dashboard-bundle/Resources/config/routes.yaml';
});
Widget Rendering
render() (if needed) to customize output:
public function render() {
return $this->twig->render('widgets/example.html.twig', [
'config' => $this->config,
]);
}
resources/views/widgets/.User-Specific Dashboards
user_id in the widgets table.$widgets = Widget::where('user_id', auth()->id())->orderBy('order')->get();
Database Schema Mismatch
widgets table with columns like id, user_id, type, config (JSON), and order. Custom migrations may break functionality.doctrine:migrations:diff to generate a compatible migration.Twig Environment Issues
Twig_Environment binding errors in logs.JSON Schema Validation
getJsonSchema() may cause silent failures or malformed UI forms.Route Conflicts
/dashboard) may clash with Laravel’s default routes.routes/web.php or use route namespaces:
# In routes.yaml
dashboard_widgets:
path: /admin/dashboard
Widget Ordering
order column. Manual reordering requires updating this column (e.g., via a drag-and-drop UI or admin panel).Caching Headaches
Log Widget Configs
Dump configs in getJsonSchema() or render() to verify data:
\Log::debug('Widget config:', $this->config);
Check Bundle Events
The bundle may dispatch events (e.g., dashboard.widget.render). Listen for them in Laravel’s event system:
Event::listen('dashboard.widget.render', function ($widget) {
\Log::info('Rendering widget:', $widget->getName());
});
Disable Widgets Safely
Set support() { return false; } to hide widgets without deleting them.
Custom Widget Types
Extend AbstractWidget to create reusable widget templates (e.g., ChartWidget, TableWidget).
Admin Panel Integration
Add a /dashboard/admin route to manage widgets (user assignment, reordering, deletion). Example:
Route::get('/dashboard/admin', [DashboardController::class, 'admin'])->name('dashboard.admin');
Widget Permissions Add middleware to restrict widget access:
public function render() {
if (!auth()->user()->can('view-dashboard')) {
abort(403);
}
return parent::render();
}
Internationalization
Use Twig’s trans filter in widget templates for multi-language support:
{{ 'widget.title'|trans({ 'name': config.title }) }}
Testing Widgets
Mock AbstractWidget in PHPUnit tests:
$widget = $this->createMock(AbstractWidget::class);
$widget->method('getName')->willReturn('Test Widget');
$widget->method('render')->willReturn('Mocked HTML');
How can I help you explore Laravel packages today?