kalamu/dashboard-bundle
Kalamu Dashboard Bundle is a Laravel package for adding a ready-made admin dashboard to your app, with configurable pages, widgets, and management screens that help you scaffold back-office UI faster while keeping the implementation in PHP.
Before anything else: this is a Symfony bundle, not a Laravel package. There is no service provider, no config/dashboard.php, and no Blade. If you're a Laravel developer, the mental mapping is:
| Laravel | This bundle |
|---|---|
| Service Provider | Kalamu\DashboardBundle\KalamuDashboardBundle |
config/*.php |
config/packages/kalamu_dashboard.yaml |
| Blade | Twig |
| Eloquent | Doctrine ORM (via Kalamu core) |
php artisan vendor:publish |
Twig @KalamuDashboard/... overrides |
artisan |
bin/console |
It is also a satellite of the Kalamu CMS, not a standalone dashboard library. kalamu/dashboard-bundle assumes kalamu/core-bundle (users, security, admin layout, menu system) is installed and configured. Pulling it into a plain Symfony app will give you a renderer with nothing to render.
Version reality check as of v2.0.0: the release is explicitly Symfony 4 + Bootstrap 4. It drops Symfony 2.x support. That is the entire stated delta — a major-version bump for a compatibility adjustment, which usually means the config tree and/or Twig templates moved too. Read the tag diff, not just the notes.
Minimal path:
composer require kalamu/dashboard-bundle:^2.0 — and pin exactly (see Gotchas).config/bundles.php:
Kalamu\DashboardBundle\KalamuDashboardBundle::class => ['all' => true],
DependencyInjection/Configuration.php — the authoritative list of every YAML key. Read it before the README; it never lies, the docs might. Do this again on v2.0.0 even if you ran 1.x — this is where a compatibility bump most often hides BC breaks.Resources/config/ — service definitions and the routing file. This tells you the actual route name and path of the dashboard.Resources/views/ — the markup you'll be overriding. v2.0.0 is confirmed Bootstrap 4; if your app is Bootstrap 5 or Tailwind, that is a known restyle cost, not a surprise to discover mid-sprint.Controller/ — usually one thin controller that assembles the view model.bin/console debug:router | grep -i dashboard to find the mounted path, then hit it as an authenticated user.First real use case: a read-only operations page — a handful of "number + trend" tiles and one or two list panels (recent signups, failed jobs, pending moderation). Resist building anything interactive until you've confirmed the asset and JS story works in your environment.
Config-driven composition. The bundle's reason for existing is that the dashboard is declared, not coded. Expect a config tree roughly along these lines (verify key names against Configuration.php — do not trust a blog post, and re-verify after the 1.x → 2.x jump):
# config/packages/kalamu_dashboard.yaml
kalamu_dashboard:
title: "Ops"
columns: 3
panels:
- type: text
title: "Signups today"
# ...
Treat the YAML as the primary API surface. It diffs well, it's environment-overridable via config/packages/prod/, and it means a content editor can rearrange the dashboard without a deploy — which is usually the actual business requirement behind "configurable dashboard."
Custom panels as services. The scalable pattern for anything non-trivial: implement the bundle's panel/widget interface (check Model/ or Panel/ for the contract), register it as a service, and tag it so the compiler pass collects it. Keep the panel class to two responsibilities — fetch data, return a template + context — and push the query into a repository. Panels are the natural unit of code review here; a 300-line panel class is the failure mode.
Override Twig, don't fork. Symfony's bundle override convention is the extension point you want:
templates/bundles/KalamuDashboardBundle/index.html.twig
Copy from vendor/kalamu/dashboard-bundle/Resources/views/, edit in place. This survives composer update and is far cheaper than a fork. Same trick for the layout block if you need to inherit your app's admin chrome. On v2.0.0, re-copy your overrides rather than assuming last year's copies are still valid — a major bump that touches Bootstrap versions almost always rewrites this markup, and stale overrides silently mask the new structure.
Bridge to your own data. If part of the app is Eloquent or API-backed rather than Doctrine, don't contort the panel abstraction — write a small adapter service that returns plain arrays/DTOs, and let the panel only know the adapter. That keeps the panel testable and keeps the vendor interface at arm's length, which matters a lot for a package with zero dependents.
Menu integration. Kalamu core likely owns the admin menu. Register the dashboard as a menu entry through core's menu service/config rather than hardcoding a link in a template — otherwise the entry disappears the moment someone reorganizes navigation.
Resources/public/ before debugging "why does it look broken" — the answer is usually a missing <link> in your base.html.twig.bin/console config:dump-reference kalamu_dashboard and trust that output over the docs. This is the single most likely 1.x → 2.x breakage: a renamed or removed key fails loudly at warmup, which is at least the good failure mode.config:dump-reference and debug:container --tag=<panel tag> output on both sides and compare. The release notes won't enumerate the renames for you.bin/console cache:clear after YAML edits in dev if debug is off, or you'll debug a phantom. In dev, Twig template caching also bites when overriding bundle views — rm -rf var/cache/dev/twig is the fast fix, and it's near-mandatory right after taking a new major.debug:config kalamu_dashboard → debug:container --tag=<panel tag> → debug:router → Twig profiler. If the panel doesn't appear, it's almost always an untagged service or a YAML key that silently didn't match a panel type."kalamu/dashboard-bundle": "2.0.0" in composer.json and commit composer.lock. A ^1.0 would have let you drift across a major; a ^2.0 in a repo with this little activity buys you nothing but surprise. If you're on Symfony 2/3, note that v2.0.0 drops you — you are staying on 1.x permanently, and that's fine as long as the lock file says so.How can I help you explore Laravel packages today?