The EasyAdmin dashboard
Almost every site needs an admin panel: a list of posts, users and orders with search and edit forms. Writing it by hand is long and dull. The EasyAdmin package builds such a panel from Doctrine entities.
Installation
composer require easycorp/easyadmin-bundle
php bin/console make:admin:dashboardThe second command creates the panel's main controller — by default it opens at /admin.
A section for an entity
php bin/console make:admin:crudThe command asks which entity to create a section for and generates a controller:
namespace App\Controller\Admin;
use App\Entity\Post;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
class PostCrudController extends AbstractCrudController
{
public static function getEntityFqcn(): string
{
return Post::class;
}
}That is already enough: a list, search, create and edit forms and deletion appear.
The menu
Sections are added to the menu in the dashboard controller:
use EasyCorp\Bundle\EasyAdminBundle\Config\MenuItem;
public function configureMenuItems(): iterable
{
yield MenuItem::linkToDashboard('Home', 'fa fa-home');
yield MenuItem::section('Content');
yield MenuItem::linkToCrud('Posts', 'fa fa-file-text', Post::class);
yield MenuItem::linkToCrud('Comments', 'fa fa-comment', Comment::class);
yield MenuItem::section('People');
yield MenuItem::linkToCrud('Users', 'fa fa-user', User::class);
}Fields
By default EasyAdmin shows every property. The configureFields() method sets which fields to show and how:
use EasyCorp\Bundle\EasyAdminBundle\Field\AssociationField;
use EasyCorp\Bundle\EasyAdminBundle\Field\BooleanField;
use EasyCorp\Bundle\EasyAdminBundle\Field\DateTimeField;
use EasyCorp\Bundle\EasyAdminBundle\Field\IdField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextEditorField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;
public function configureFields(string $pageName): iterable
{
yield IdField::new('id')->hideOnForm();
yield TextField::new('title', 'Title');
yield TextEditorField::new('body', 'Text')->hideOnIndex();
yield AssociationField::new('author', 'Author');
yield BooleanField::new('published', 'Published');
yield DateTimeField::new('createdAt', 'Created')->hideOnForm();
}hideOnForm() removes a field from the form, hideOnIndex() from the list.
Search, ordering, filters
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
use EasyCorp\Bundle\EasyAdminBundle\Config\Filters;
public function configureCrud(Crud $crud): Crud
{
return $crud
->setEntityLabelInSingular('Post')
->setEntityLabelInPlural('Posts')
->setSearchFields(['title', 'body'])
->setDefaultSort(['createdAt' => 'DESC'])
->setPaginatorPageSize(30);
}
public function configureFilters(Filters $filters): Filters
{
return $filters->add('published')->add('author')->add('createdAt');
}Custom actions
Besides the standard buttons you can add your own — "Publish", for example. An action is described in configureActions() and tied to a controller method.
Protection
The panel must be closed to outsiders:
# config/packages/security.yaml
security:
access_control:
- { path: ^/admin, roles: ROLE_ADMIN }Individual sections can be restricted further: MenuItem::linkToCrud(...)->setPermission('ROLE_SUPER_ADMIN').
Common mistake
The access_control rule is easy to forget or delete by accident — and the panel opens to anyone who guesses the /admin address. Right after installation visit the site as a guest and make sure the panel is unavailable, or better, write a test that checks it.