EasyAdmin 4 for admin panel based on PHP 8 and Symfony 6: Install and create a sample

nabbisen - Mar 7 '22 - - Dev Community

Summary

EasyAdmin enables you to create easily admin panel bound to storage such as RDBMS.

It is one of the bundles of Symfony, a powerful and flexible PHP framework, also requiring Doctrine ORM entities.

Environment

Tutorial

sudo can be used instead of doas below.

PHP

PHP8 and PHP-FPM

$ doas apk add php8-fpm
Enter fullscreen mode Exit fullscreen mode

PHP extensions

$ doas apk add php8-gd php8-curl php8-dom php8-iconv php8-json php8-mbstring php8-openssl php8-pdo php8-session php8-tokenizer php8-session php8-xml php8-simplexml php8-xmlwriter php8-zip php8-ctype php8-intl php8-opcache php8-pcntl
Enter fullscreen mode Exit fullscreen mode
Case SQLite3
$ doas apk add sqlite
$ doas apk add php8-pdo_sqlite
Enter fullscreen mode Exit fullscreen mode
Case MariaDB
$ doas apk add mariadb-client
$ doas apk add php8-pdo_mysql php8-mysqlnd
Enter fullscreen mode Exit fullscreen mode

PHP-FPM daemon

$ # enable
$ doas rc-update add php_fpm
$ # start
$ doas rc-service php_fpm start
Enter fullscreen mode Exit fullscreen mode

Caddy

$ doas apk add caddy
Enter fullscreen mode Exit fullscreen mode
$ # enable
$ doas rc-update add caddy
$ # start
$ doas rc-service caddy start
Enter fullscreen mode Exit fullscreen mode
your.host

log {
    output file "/var/log/caddy/caddy.log"
}

root * "/var/local/appbc/public"

@blocked {
    path /.git*
}
respond @blocked 403

@assets {
    path_regexp ^.*(\.html|\.css|\.js|\.jpg|\.jpeg|\.png|\.webp|\.gif|\.svg|\.woff2)$
}
file_server @assets

@approutes {
    path_regexp ^.*/[^\./]*/?$
}
#rewrite @approutes /index.php?{query}&c={path}
rewrite @approutes /index.php?{query}

@indexphp {
    path /index.php*
}
#php_fastcgi @indexphp "unix//run/php-fpm7/php-fpm.pid"
php_fastcgi @indexphp "127.0.0.1:9000"
Enter fullscreen mode Exit fullscreen mode

Symfony

$ composer create-project symfony/website-skeleton "<project-dir>"

$ cd "<project-dir>"
Enter fullscreen mode Exit fullscreen mode

symfony welcome

EasyAdmin

Install

$ composer require easycorp/easyadmin-bundle
Enter fullscreen mode Exit fullscreen mode

The output was:

Using version ^4.0 for easycorp/easyadmin-bundle
./composer.json has been updated
Running composer update easycorp/easyadmin-bundle
Loading composer repositories with package information
Restricting packages listed in "symfony/symfony" to "6.0.*"
Updating dependencies
Lock file operations: 3 installs, 0 updates, 0 removals
  - Locking easycorp/easyadmin-bundle (v4.0.6)
  - Locking symfony/polyfill-uuid (v1.24.0)
  - Locking symfony/uid (v6.0.3)
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 3 installs, 0 updates, 0 removals
  - Downloading symfony/polyfill-uuid (v1.24.0)
  - Downloading symfony/uid (v6.0.3)
  - Downloading easycorp/easyadmin-bundle (v4.0.6)
  - Installing symfony/polyfill-uuid (v1.24.0): Extracting archive
  - Installing symfony/uid (v6.0.3): Extracting archive
  - Installing easycorp/easyadmin-bundle (v4.0.6): Extracting archive
Generating optimized autoload files
110 packages you are using are looking for funding.
Use the `composer fund` command to find out more!

Symfony operations: 1 recipe (...)
  - Configuring easycorp/easyadmin-bundle (>=3.0): From github.com/symfony/recipes:master
Executing script cache:clear [OK]
Executing script assets:install public [OK]

 What's next? 


Some files have been created and/or updated to configure your new packages.
Please review, edit and commit them: these files are yours.
Enter fullscreen mode Exit fullscreen mode

Create a Dashboard

Install
$ php bin/console make:admin:dashboard
Enter fullscreen mode Exit fullscreen mode

I was asked a couple of times and used the default:

 Which class name do you prefer for your Dashboard controller? [DashboardController]:
 > 

 In which directory of your project do you want to generate "DashboardController"? [src/Controller/Admin/]:
 > 



 [OK] Your dashboard class has been successfully generated.                                                             


 Next steps:
 * Configure your Dashboard at "src/Controller/Admin/DashboardController.php"
 * Run "make:admin:crud" to generate CRUD controllers and link them from the Dashboard.
Enter fullscreen mode Exit fullscreen mode

Here, you can see the default dashboard!!

easyadmin default dashboard

Well, there is no menu! Let's create your own dashboard and add menus to it.

Create the first dashboard of your own

Let's create a custom template:

$ mkdir templates/admin

$ nvim templates/admin/index.html.twig
Enter fullscreen mode Exit fullscreen mode

Write just this in it:

+ {% extends '@EasyAdmin/page/content.html.twig' %}
Enter fullscreen mode Exit fullscreen mode

Then, edit the controller (src/Controller/Admin/DashboardController.php):

  class DashboardController extends AbstractDashboardController
  {
      #[Route('/admin', name: 'admin')]
      public function index(): Response
      {
-         return parent::index();
+         return $this->render('admin/index.html.twig');
Enter fullscreen mode Exit fullscreen mode

Then prepare assets:

$ yarn encore dev
$ # alternatively, `npm run dev` is available
Enter fullscreen mode Exit fullscreen mode

Besides, you sometimes have to clear cache.

$ php(8) bin/console cache:clear
Enter fullscreen mode Exit fullscreen mode

Reload the dashboard page, and you will see it's replaced with your own.

your own dashboard

There are few menus. Next, let's implement to manage table records.

Prepare an entity

Let's make some entity. It's dealt with by Symfony and Doctrine.

Use make bundle. You will be asked on its schema:

$ php bin/console make:entity
Enter fullscreen mode Exit fullscreen mode

Then make it substantial:

$ php bin/console make:migration
$ # reply yes
$ php bin/console doctrine:migrations:migrate
$ # reply yes
Enter fullscreen mode Exit fullscreen mode

Create a CRUD controller

It's EasyAdmin's turn.

$ php bin/console make:admin:crud
Enter fullscreen mode Exit fullscreen mode

The output was:

 Which Doctrine entity are you going to manage with this CRUD controller?:
  [0] App\Entity\(...)
 > 0

 Which directory do you want to generate the CRUD controller in? [src/Controller/Admin/]:
 > 

 Namespace of the generated CRUD controller [App\Controller\Admin]:
 > 


 [OK] Your CRUD controller class has been successfully generated.                                                       


 Next steps:
 * Configure your controller at "src/Controller/Admin/(...)CrudController.php"
 * Read EasyAdmin docs: https://symfony.com/doc/master/bundles/EasyAdminBundle/index.html
Enter fullscreen mode Exit fullscreen mode

Add a menu on the entity:

  (...)
+ use App\Entity\SamplePack;

  class DashboardController extends AbstractDashboardController
  (...)
      public function configureMenuItems(): iterable
      {
          yield MenuItem::linkToDashboard('Dashboard', 'fa fa-home');
-         // yield MenuItem::linkToCrud('The Label', 'fas fa-list', EntityClass::class);
+         yield MenuItem::linkToCrud('The Label', 'fas fa-list', SamplePack::class);
    }
Enter fullscreen mode Exit fullscreen mode

Then, reload the page.

menu to entity

Yay, got it. Let's click "The Label" on the left side:

entity page

We can manage storage here!!

Conclusion

I tried a new feature released just at the beginning of the year, menu badges.

To show a count:

-         yield MenuItem::linkToCrud('The Label', 'fas fa-list', SamplePackClass::class);
+         yield MenuItem::linkToCrud('The Label', 'fas fa-list', SamplePackClass::class)
+         ->setBadge(468, 'success');
Enter fullscreen mode Exit fullscreen mode

badge of number

Nice.

To show a message:

-         yield MenuItem::linkToCrud('The Label', 'fas fa-list', SamplePackClass::class);
+         yield MenuItem::linkToCrud('The Label', 'fas fa-list', SamplePackClass::class)
+         ->setBadge('Ciao!', 'background: transparent; color: #44bb88; outline: 2px solid white');
Enter fullscreen mode Exit fullscreen mode

badge of string

Sweet 💃💃

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .