gstreamer0.10-ffmpeg
gstreamer0.10-plugins-good
packages.
The true reason to use EasyAdmin is for its CRUD controllers. Each CRUD controller will give us a rich set of pages to create, read, update, and delete a single entity. This is where EasyAdmin shines, and the next few minutes are going to be critically important to understand how EasyAdmin works. So, buckle up!
We have four entities. Let's generate a CRUD controller for Question
first. Find your terminal and run:
symfony console make:admin:crud
As you can see, it recognizes our four entities. I'll hit 1 for App\Entity\Question
, let this generate into the default directory... and with default namespace.
Sweet! This did exactly one thing: it created a new QuestionCrudController.php
file. Let's... go open it up!
... lines 1 - 2 | |
namespace App\Controller\Admin; | |
use App\Entity\Question; | |
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController; | |
class QuestionCrudController extends AbstractCrudController | |
{ | |
public static function getEntityFqcn(): string | |
{ | |
return Question::class; | |
} | |
/* | |
public function configureFields(string $pageName): iterable | |
{ | |
return [ | |
IdField::new('id'), | |
TextField::new('title'), | |
TextEditorField::new('description'), | |
]; | |
} | |
*/ | |
} |
Cool. But before we look too deeply into this, head over to the admin page and refresh to see... absolutely no difference! We do have a new QuestionCrudController
, but these CRUD controllers are totally useless until we link to them from a dashboard. So, back over in DashboardController
, down at the bottom... yield MenuItem
... but instead of linkToDashboard()
, there are a number of other things that we can link to. We want linkToCrud()
. Pass this the label - so "Questions" - and some FontAwesome icon classes: fa fa-question-circle
. Then, most importantly, pass the entity's class name: Question::class
:
... lines 1 - 5 | |
use App\Entity\Question; | |
... lines 7 - 15 | |
class DashboardController extends AbstractDashboardController | |
{ | |
... lines 18 - 30 | |
public function configureMenuItems(): iterable | |
{ | |
... line 33 | |
yield MenuItem::linkToCrud('Questions', 'fa fa-question-circle', Question::class); | |
} | |
} |
Behind the scenes, when we click this new link, EasyAdmin will recognize that there is only one CRUD controller for the entity - QuestionCrudController
- and will know to use it. And yes, in theory, we can have multiple CRUD controllers for a single entity... and that's something we'll talk about later.
Okay, go refresh to reveal our new link, click and... whoa! This is amazingly cool! We have a slider for the isApproved
field, which saves automatically. We also have a search bar on top... and sortable columns to help us find whatever we're looking for.
We can delete, edit... and the form even has a nice calendar widget. This is loaded with rich features out-of-the-box.
So let's repeat this for our other three controllers. Head back to your terminal and, once again, run:
symfony console make:admin:crud
This time generate a CRUD for Answer
... with the default stuff... one for Topic
with the defaults... I'll clear my screen... and finally generate one for User
.
Beautiful! The only thing this did was add three more CRUD controller classes. But to make those useful, we need to link to them. I'll paste 3 more links... then customize the label, font icons and class on each of them:
... lines 1 - 4 | |
use App\Entity\Answer; | |
... line 6 | |
use App\Entity\Topic; | |
use App\Entity\User; | |
... lines 9 - 15 | |
class DashboardController extends AbstractDashboardController | |
{ | |
... lines 18 - 30 | |
public function configureMenuItems(): iterable | |
{ | |
... lines 33 - 34 | |
yield MenuItem::linkToCrud('Answers', 'fas fa-comments', Answer::class); | |
yield MenuItem::linkToCrud('Topics', 'fas fa-folder', Topic::class); | |
yield MenuItem::linkToCrud('Users', 'fas fa-users', User::class); | |
} | |
} |
Super fast!
Let's go check it out! Refresh and... look! Simply by running that command four times, we now have four different fully-featured admin sections!
I want to look a little deeper into how this is working behind the scenes. Go to QuestionCrudController
and look at its base class:
... lines 1 - 5 | |
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController; | |
class QuestionCrudController extends AbstractCrudController | |
{ | |
... lines 10 - 24 | |
} |
Hold Cmd
or Ctrl
to jump into AbstractCrudController
. We saw earlier that our dashboard extends AbstractDashboardController
. CRUD controllers extend AbstractCrudController
.
Pretty much everything about how our CRUD controller works is going to be controlled by overriding the configure methods that you see inside of here. We'll learn about all of these as we go along. But on a high level, configureCrud()
helps you configure things about the CRUD section as a whole, configureAssets()
allows you to add custom CSS and JavaScript to the section, and configureActions()
allows you to control the actions you want, where an action is a button or link. So, you can control whether or not you have delete, edit or index links on different pages. More on that later.
The last super important method is configureFields()
, which controls the fields we see on both the index page and on the form. But don't worry about those too much yet. We'll master each method along the way.
Below this, super cool... we can see the actual code that executes for each page! The index()
method is the real action for the index, or "list" page. detail()
is an action that shows the details of a single item, and edit()
is the edit form. I love that we can see the full code that runs all of this. It'll be super useful when we're figuring out how to extend things.
But... wait a second. If you scroll back up to the configure methods, a few of these look familiar. Some of these also exist in the dashboard base controller class. And it turns out, understanding why some methods live in both classes is the key to being able to make changes to your entire admin section or changes to just one CRUD section. Let's dive into that next.
Do I see it correctly that the CRUD system requires the SensioFrameworkExtraBundle. Is there an update planned to use Symfony internally?
Hey @Rufnex
Good catch, I believe something in this tutorial is still using annotations instead of PHP attributes, but if you're not using them in your project you can remove SensioFrameworkExtraBundle
. Also, EasyAdminBundle
version 4 does not force you to use it, but perhaps a lower version will
Cheers!
Hm, i get no navbar on the left .. i use the latest sf and easyadmin. i see only the welcome page. any ideas why?
if i use a custom template like that
{% extends '@EasyAdmin/page/content.html.twig' %}
{% block content %}
<h1>Willkommen im Admin-Dashboard</h1>
<!-- Hier kannst du deine benutzerdefinierten Widgets oder Inhalte hinzufügen -->
{% endblock %}
And call it in index() with return $this->render('admin/my-dashboard.html.twig');
It works. Is this a normal behavior?
Hey Rufnex,
Hm, do you have DashboardController
? Do you have any menu items in the configureMenuItems()
method of it?
Could you share a screenshot maybe? You can upload to an image hosting like e.g. Imgur and send the link to it. Is there a chance that the menu was accidentally collapsed for you?
Cheers!
<?php
namespace App\Controller\Admin;
use App\Entity\Pages;
use EasyCorp\Bundle\EasyAdminBundle\Config\Dashboard;
use EasyCorp\Bundle\EasyAdminBundle\Config\MenuItem;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractDashboardController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class DashboardController extends AbstractDashboardController
{
#[Route('/admin', name: 'admin')]
public function index(): Response
{
#return parent::index();
// Option 1. You can make your dashboard redirect to some common page of your backend
//
// $adminUrlGenerator = $this->container->get(AdminUrlGenerator::class);
// return $this->redirect($adminUrlGenerator->setController(OneOfYourCrudController::class)->generateUrl());
// Option 2. You can make your dashboard redirect to different pages depending on the user
//
// if ('jane' === $this->getUser()->getUsername()) {
// return $this->redirect('...');
// }
// Option 3. You can render some custom template to display a proper dashboard with widgets, etc.
// (tip: it's easier if your template extends from @EasyAdmin/page/content.html.twig)
//
// return $this->render('some/path/my-dashboard.html.twig');
return $this->render('admin/dashboard.html.twig');
}
public function configureDashboard(): Dashboard
{
return Dashboard::new()
->setTitle('Test Beta');
}
public function configureMenuItems(): iterable
{
yield MenuItem::linkToDashboard('Dashboard', 'fa fa-home');
yield MenuItem::linkToCrud('The Label', 'fas fa-list', Pages::class);
}
}
With return parent::index();
it doesnt work (only the splash welcome displays).
Hey Rufnex,
Ah, yes... you've probably missed the previous video where we mention that in a newer version of EasyAdmin, see https://symfonycasts.com/screencast/easyadminbundle/dashboard#:~:text=the admin dashboard!-,Tip,-Since version 4.0.3 . So that's ok, just follow the instructions in that note to follow this tutorial :)
Cheers!
How Can I change the default welcome page. No matter the changes i've done, it always look the same and different from this one page.
Hey Marco,
Do you want to change the dashboard default page? If so, we are talking about it later in the course, see: https://symfonycasts.com/screencast/easyadminbundle/dashboard-page
I hope this helps!
Cheers!
Hi Symfonycasts Team.
Currently, the URLs look very cryptic for users.
If I would like to use EasyAdmin to provide this interface to customers or normal users, is there a possibility to display these URLs in a more user-friendly way? Possibly even in SEO form?
Hey Michael,
I'm afraid there's no easy way for this out of the box. I'm not saying that it's impossible, you probably may override some things in the source code, or even fork the EA, but it definitely won't be easy, because as you will see further, EasyAdmin put a lot of stuff in that URL, including sorting by column, search query, applied filters, etc. So, by design, it's not supposed to work with SEO urls by default, and it's an internal "admin" feature that's hidden from your users and search engine robots that will parse your website, so it's not that important. Though on the other side, I see what you mean, sometimes clients may want to see nicer URLs and it may be a problem with EasyAdmin.
Well, you can disable signed URLs for EA, and it will not include that long hash for "signature" query parameter in the URLs - it will help a bit, but will make URLs a bit more guessable and compact, but still other query parameters will still exist like Controller and action names at least.
Here's an issue that might be interested for you: https://github.com/EasyCorp... - you can see Javier's answer on it and the exact reasons why it's working this way.
Cheers!
Hello Victor.
Thanks for the quick reply.
The issue is indeed interesting (even if the attitude of javiereguiluz is rather averse :-D ). I was basically about - what you have already guessed correctly - that you could use the admin panel possibly also as a user area for customers or externals. And for this at least the mentioned adjustment of the URL in the issue would be better than the current state.
Let's hope that we get javiereguiluz convinced :-)
Hey Michael,
Yeah, I see what you mean. But that's not because Javier "hates" SEO URLs.. it's just about simplicity, this decision was made by design, and it's easier to maintain. So, I'm sure it won't be changes in the nearest future unfortunately. So, you either should take care of it yourself, but it might be pretty complex IMO, or just take a look at other solutions like SonataAdminBundle or ApiPlatform admin. I hope this helps.
Cheers!
// composer.json
{
"require": {
"php": ">=8.1.0",
"ext-ctype": "*",
"ext-iconv": "*",
"composer/package-versions-deprecated": "^1.11", // 1.11.99.4
"doctrine/doctrine-bundle": "^2.1", // 2.5.5
"doctrine/doctrine-migrations-bundle": "^3.0", // 3.2.1
"doctrine/orm": "^2.7", // 2.10.4
"easycorp/easyadmin-bundle": "^4.0", // v4.0.2
"handcraftedinthealps/goodby-csv": "^1.4", // 1.4.0
"knplabs/knp-markdown-bundle": "dev-symfony6", // dev-symfony6
"knplabs/knp-time-bundle": "^1.11", // 1.17.0
"sensio/framework-extra-bundle": "^6.0", // v6.2.5
"stof/doctrine-extensions-bundle": "^1.4", // v1.7.0
"symfony/asset": "6.0.*", // v6.0.1
"symfony/console": "6.0.*", // v6.0.2
"symfony/dotenv": "6.0.*", // v6.0.2
"symfony/flex": "^2.0.0", // v2.0.1
"symfony/framework-bundle": "6.0.*", // v6.0.2
"symfony/mime": "6.0.*", // v6.0.2
"symfony/monolog-bundle": "^3.0", // v3.7.1
"symfony/runtime": "6.0.*", // v6.0.0
"symfony/security-bundle": "6.0.*", // v6.0.2
"symfony/stopwatch": "6.0.*", // v6.0.0
"symfony/twig-bundle": "6.0.*", // v6.0.1
"symfony/ux-chartjs": "^2.0", // v2.0.1
"symfony/webpack-encore-bundle": "^1.7", // v1.13.2
"symfony/yaml": "6.0.*", // v6.0.2
"twig/extra-bundle": "^2.12|^3.0", // v3.3.7
"twig/twig": "^2.12|^3.0" // v3.3.7
},
"require-dev": {
"doctrine/doctrine-fixtures-bundle": "^3.3", // 3.4.1
"symfony/debug-bundle": "6.0.*", // v6.0.2
"symfony/maker-bundle": "^1.15", // v1.36.4
"symfony/var-dumper": "6.0.*", // v6.0.2
"symfony/web-profiler-bundle": "6.0.*", // v6.0.2
"zenstruck/foundry": "^1.1" // v1.16.0
}
}
Hey Nicolas,
We're sorry for this! Yeah, EA changed some styles lately, and you need to do some extra steps to see that side menu. Please, follow the instructions in the previous chapters, you can find them in the note: https://symfonycasts.com/sc... - look for "Since version 4.0.3 of EasyAdmin" text there.
I hope this helps! If not - let us know!
Cheers!