- Home
- Blog
- Information
- Technology
- Filament Admin Panels for Content-Heavy Sites
Filament Admin Panels for Content-Heavy Sites
Why Filament replaced a hand-rolled admin in a week: resources, relation managers, media uploads and a tree-aware category select — with the trade-offs I hit along the way.
The old admin was a pile of controllers and Blade forms that nobody wanted to touch. Filament describes a form and a table once per resource and the panel does the rest: validation, search, filters, bulk actions and a decent dark mode for free.
From custom CRUD to resources
Every content type on this site is a Filament resource. Posts get a two-column layout with the editor on the left and status, schedule, category, tags and cover on the right; categories get a tree-indented parent select; skills live in a relation manager under their category.
Key points
- One resource per model; relation managers for children.
- Enums with labels, colours and icons drive both the panel and the front-end.
- Business rules belong in observers and actions, not in form callbacks.
- Signed preview URLs for drafts, published() scope for everything else.
The parts that needed thought
Hierarchical categories need a select that shows the full path and hides the node being edited plus its descendants. Media uploads need conversions to run synchronously in development and on a queue in production, and drafts need a signed preview link that never leaks through the public routes.
Example in code
Select::make('category_id')
->label('Category')
->options(fn (?Category $record): array => app(CategoryTreeService::class)
->flatOptions($record?->getKey()))
->searchable()
->required();
What I would do again
Keep the enums shared between the panel and the public site, and put every business rule in observers or actions so the panel stays a thin skin over the domain rather than a second copy of it.
Filament turned a week of admin CRUD into an afternoon of configuration.
Takeaways
A generated admin is only as good as the domain underneath it. Invest in the models, enums and observers first; the panel then becomes a small amount of declarative glue.