Installation
composer require beastphp/easy-admin-bundle
Register the bundle in config/bundles.php:
return [
// ...
Beast\EasyAdminBundle\EasyAdminBundle::class => ['all' => true],
];
Basic Configuration
Create a minimal config/packages/easy_admin.yaml:
easy_admin:
design:
menu:
- { label: 'Dashboard', icon: 'dashboard', route: 'easyadmin.dashboard' }
- { label: 'Users', icon: 'users', route: 'easyadmin.user.crud' }
First CRUD Controller
Generate a CRUD controller for an entity (e.g., User):
php bin/console make:easyadmin:crud User
This creates a controller at src/Controller/Admin/UserCrudController.php.
Access the Admin Panel
Visit /admin (or your configured route) and log in with a user having the ROLE_ADMIN role.
config/packages/easy_admin.yaml: Central configuration for routes, design, and ACL.src/Controller/Admin/: Auto-generated CRUD controllers for entities.templates/admin/: Override default templates (e.g., layout.html.twig).config/routes/easy_admin.yaml: Custom route definitions.namespace App\Controller\Admin;
use Beast\EasyAdminBundle\Controller\AbstractCrudController;
use App\Entity\User;
class UserCrudController extends AbstractCrudController
{
public static function getEntityFqcn(): string
{
return User::class;
}
public function configureFields(string $pageName): iterable
{
return [
'id',
'email',
'roles',
'createdAt',
];
}
}
/admin/user to list users.roles or email.AbstractCrudController for each entity.class ProductCrudController extends AbstractCrudController
{
public static function getEntityFqcn(): string { return Product::class; }
public function configureFields(string $pageName): iterable
{
return [
'name',
'price',
'stock',
'createdAt' => ['label' => 'Published On'],
];
}
}
make:easyadmin:crud to scaffold the controller.configureListFields() to control displayed columns.public function configureListFields(string $pageName): iterable
{
return [
'name',
'price' => ['format' => 'currency'],
'stock' => [
'label' => 'In Stock',
'format' => function ($stock) {
return $stock > 0 ? '<span class="text-success">Yes</span>' : '<span class="text-danger">No</span>';
},
],
];
}
configureFormFields() to add/remove fields or apply validation.public function configureFormFields(string $pageName): iterable
{
return [
'name',
'price' => [
'type' => 'money',
'currency' => 'EUR',
],
'description' => [
'type' => 'textarea',
'attr' => ['rows' => 4],
],
];
}
public function configureActions(): iterable
{
return [
'delete',
'export' => [
'label' => 'Export to CSV',
'icon' => 'file-export',
'action' => 'export',
],
];
}
configureMenuItems() or isAccessible().# config/packages/easy_admin.yaml
easy_admin:
design:
menu:
- { label: 'Users', icon: 'users', route: 'easyadmin.user.crud', role: 'ROLE_SUPER_ADMIN' }
public function isAccessible(): bool
{
return $this->get('security.authorization_checker')->isGranted('ROLE_ADMIN');
}
ChoiceType, EntityType) in configureFormFields():
'category' => [
'type' => 'entity',
'class' => Category::class,
'choice_label' => 'name',
],
#[ORM\Table(name: 'products')]
#[SoftDelete]
class Product {}
SoftDeleteable traits.configureFields():
'name' => ['label' => 'admin.product.name'],
config/packages/easy_admin.yaml:
easy_admin:
design:
translations: ['en', 'fr']
prePersist, postRemove):
// src/EventListener/ProductListener.php
public function onPrePersist(Product $product)
{
$product->setSlug(Str::slug($product->getName()));
}
services.yaml:
services:
App\EventListener\ProductListener:
tags:
- { name: kernel.event_listener, event: easyadmin.crud.pre_persist, method: onPrePersist }
templates/admin/ (e.g., crud/index.html.twig).vendor/beast/easy-admin-bundle/Resources/views/.Outdated Symfony Version
symfony/flex or manually patch dependencies.Missing ACL Configuration
configureMenuItems() or use Symfony’s security voter.Entity Changes Not Reflected
make:easyadmin:crud or manually update configureFields().Template Overrides Not Loading
templates/admin/ are ignored.crud/show.html.twig for the show action).Doctrine Events Conflicts
easyadmin.crud.* events instead of generic prePersist/postRemove.Enable Debug Mode
# config/packages/dev/easy_admin.yaml
easy_admin:
debug: true
var/log/dev.log.Check Route Generation
php bin/console debug:router | grep easyadmin
Inspect Controller Logic
configureFields() and add dump() calls for debugging:
public function configureFields(string $pageName): iterable
{
dump($pageName); // Debug current page (index/edit/show)
return [...];
}
Clear Cache
php bin/console cache:clear
How can I help you explore Laravel packages today?