Parte 8: Cómo crear un panel de administración con Symfony 6
En este tutorial vamos a ver cómo crear fácilmente un potente panel de administración con Symfony 6 de forma sencilla paso a paso.
Hola 👋, después de un tiempo vuelvo a retomar el blog 😅. Hace unos meses murió mi portátil, así que vi que sería buena opción tomarme las cosas con más calma y desconectar un poco del mundillo de la programación fuera del horario laboral. Después de este tiempo me veo con más ganas de retomar el blog y ahora que tengo un nuevo PC espero que los tutoriales salgan como churros (o al menos escribir artículos con más asiduidad 😅).
Antes de empezar 🛑 y como siempre, si te has perdido alguno de los tutoriales de esta serie, aquí te dejo todos los tutoriales escritos hasta ahora:
- Parte 1: Cómo crear una webapp con Symfony 6
- Parte 2: Cómo crear entidades, migraciones y conectarnos a una base de datos con Symfony 6
- Parte 3: Cómo crear datos falsos en una base de datos con Symfony 6
- Parte 4: Controladores, templates y estilos con Tailwind CSS en Symfony 6
- Parte 5: Optimización de queries con Doctrine, ajustes y página de post en Symfony 6
- Parte 6: Autenticación y registro con Symfony 6
- Parte 7: Cómo crear formularios con Symfony 6
- Parte 8: Cómo crear un panel de administración con Symfony 6 👷📍
Instalar EasyAdmin Bundle 👷
Como primer paso en este tutorial, vamos a instalar el bundle de easyadmin, este nos permitirá crear un panel de administración fácilmente sin apenas tener que escribir unas cuantas líneas de código.
Para instalarlo debemos lanzar el siguiente comando en la raíz del proyecto:
symfony composer req "admin:^4"
Una vez instalado, ya podremos empezar a configurar el panel de administración y para ello el siguiente paso será crear el controlador del panel de administración.
Esto lo podemos hacer de manera sencilla con el siguiente comando:
symfony console make:admin:dashboard
Como en otras ocasiones, aparecerá el asistente y seleccionaremos los valores por defecto.
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/]:
>
Lo que hace, básicamente, es crear el controlador y lo guarda dentro de la carpeta Admin.
Ahora nos dirigimos al archivo src\Controller\Admin\DashboardController.php y te comento las partes más importantes.
Como puedes ver, tenemos un método index con la ruta a nuestro panel que por defecto será admin. Para probar en el entorno de local está muy bien, pero te recomiendo que si vas a subir un proyecto a producción modifiques la ruta para que sea difícil de localizar por posibles atacantes.
También tenemos un par de métodos para añadir configuraciones en nuestro panel que ahora os explicaré como editarlos para modificar la apariencia de nuestro panel.
Si accedemos a la ruta /admin, podrás ver una página de bienvenida de EasyAdmin. Más adelante veremos como cambiar eso y mostrar las distintas secciones de nuestro panel de administración.
Limitar el acceso al panel de Admin ⛔
Antes de continuar con la construcción del panel de administración debemos controlar que solo puedan acceder los usuarios con el rol de admin (ROLE_ADMIN). Para ello vamos al archivo config\packages\security.yaml y en la sección de access_control, debemos descomentar la línea "- { path: ^/admin, roles: ROLE_ADMIN }".
access_control:
- { path: ^/admin, roles: ROLE_ADMIN }
Esto le indicará a Symfony que solo los usuarios con el rol de admin pueden acceder a la ruta /admin y a las secciones que contenga.
Crear las distintas secciones de nuestro panel de administración 🏗️
El siguiente paso es crear las secciones para administrar las distintas entidades de nuestro blog, que son los posts, usuarios, comentarios y tags. Esto nos permitirá añadir nueva información, editarla, leerla y borrarla, vamos lo que comúnmente se conoce como CRUD.
Para ello lanzaremos el siguiente comando:
symfony console make:admin:crud
Aparecerá el asistente y nos preguntará sobre qué entidad queremos crear el CRUD. Como queremos crearla para las cuatro debemos ir seleccionándolas una a una y elegiremos los valores por defecto. El resultado será que creará los controladores para cada entidad.
Configurar el panel de administración ⚙️
Una vez hecho esto, vamos a configurar nuestro panel de administración. Para ello, quiero que vuelvas al archivo src\Controller\Admin\DashboardController.php y reemplaces el código existente por el siguiente:
<?php
namespace App\Controller\Admin;
use App\Entity\Comment;
use App\Entity\Post;
use App\Entity\Tag;
use App\Entity\User;
use EasyCorp\Bundle\EasyAdminBundle\Config\Dashboard;
use EasyCorp\Bundle\EasyAdminBundle\Config\MenuItem;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractDashboardController;
use EasyCorp\Bundle\EasyAdminBundle\Router\AdminUrlGenerator;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class DashboardController extends AbstractDashboardController
{
#[Route('/admin', name: 'admin')]
public function index(): Response
{
$adminUrlGenerator = $this->container->get(AdminUrlGenerator::class);
return $this->redirect($adminUrlGenerator->setController(PostCrudController::class)->generateUrl());
}
public function configureDashboard(): Dashboard
{
return Dashboard::new()
->setTitle('Blog Symfony');
}
public function configureMenuItems(): iterable
{
yield MenuItem::linkToDashboard('Dashboard', 'fa fa-tachometer-alt');
yield MenuItem::linktoRoute('Back to the website', 'fas fa-home', 'get_posts');
yield MenuItem::linkToCrud('Posts', 'fas fa-file-text', Post::class);
yield MenuItem::linkToCrud('Comments', 'fas fa-comments', Comment::class);
yield MenuItem::linkToCrud('Tags', 'fas fa-tags', Tag::class);
yield MenuItem::linkToCrud('Users', 'fas fa-user', User::class);
}
}
Como puedes ver, lo primero que he hecho es importar las entidades de nuestro proyecto. Estas son utilizadas en el método configureMenuItems() que muestra la barra de navegación del dashboard.
Si te fijas en este método, lo que hacemos es crear un link para la página principal del dashboard, otro para la página principal de nuestra web y los últimos cuatro redirigen a nuestras distintas entidades.
Los distintos parámetros que reciben cada MenuItem::linkTo... es primero un título que es el que veremos como nombre de sección. El siguiente es una clase de css. En este caso son iconos de font-awesome que ya utilizamos anteriormente en este tutorial y en el caso de linkToCrud las rutas hacia nuestras entidades.
También he modificado el método index para que ya no nos dirija a la página de bienvenida de EasyAdmin. En el propio método, antes de reemplazar el contenido nos explica las distintas posibilidades que tenemos. Yo he configurado que cuando acceda al index, nos muestre la página de posts.
Si accedes al panel de administración ya podrás ver que ahora aparece el listado de post y a la izquierda están las distintas secciones que habilitamos (una para cada entidad).
Customizar la sección de comentarios 💬
Ahora que ya tenemos configurado nuestro panel, es hora de customizarlo según nuestras necesidades. Actualmente, ya podríamos trabajar con él, pero faltan unas cuantas cosas interesantes que seguro te ayudarán.
Como ejemplo, vamos a ver los cambios que yo implementaría en la sección de comentarios. Estos son:
- Eliminar el botón de añadir un nuevo comentario y poder editarlos. Los comentarios los crearán los usuarios desde un post en concreto, así que aquí no tiene sentido. Tampoco tiene sentido editar los comentarios, si un usuario incumple nuestras normas. Simplemente lo borraremos.
- Añadir en el listado el usuario y el título del post. Esto nos vendrá bien para localizar fácilmente quién ha escrito cada comentario y en que post lo ha añadido.
- Buscador. De esta manera podremos buscar por usuario y por palabras dentro del contenido de los comentarios que nos será útil para ver si un usuario está incumpliendo nuestras normas.
Para realizar estos cambios debemos abrir el archivo src\Controller\Admin\CommentCrudController.php y en él realizaremos los siguientes cambios:
Para eliminar el botón de añadir y editar, añadiremos los siguientes cambios:
...
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
...
public function configureActions(Actions $actions): Actions
{
return $actions
->disable(Crud::PAGE_DETAIL, Action::NEW)
->disable(Crud::PAGE_DETAIL, Action::EDIT)
;
}
...
En él importamos las librerías que necesitamos y crearemos el método configureActions en el cual deshabilitaremos la acción de NEW y EDIT.
Para configurar la información que queremos buscar y además añadir el orden en el que se mostrarán los comentarios y como nombrar las etiquetas de nuestra entidad en singular y plural, añadiremos el siguiente método:
public function configureCrud(Crud $crud): Crud
{
return $crud
->setEntityLabelInSingular('Comment')
->setEntityLabelInPlural('Comments')
->setSearchFields(['user.username', 'user.email', 'content'])
->setDefaultSort(['created_at' => 'DESC'])
;
}
Como puedes observar, en la línea "->setSearchFields(['user.username', 'user.email', 'content'])" indicamos porque campos queremos poder buscar. Como el nombre y email del usuario son de otra entidad, debemos acceder a él desde user y el nombre del campo. También es necesario que exista la relación entre tablas, si no, no funcionará (nosotros ya lo hicimos cuando creamos las entidades, así que no te preocupes).
Por último, modificaremos que vamos a mostrar en el listado de comentarios. Para ello modificamos el método configureFields:
public function configureFields(string $pageName): iterable
{
return [
IdField::new('id'),
TextField::new('user.username', 'User'),
TextField::new('post.title', 'Post'),
DateTimeField::new('created_at', 'Created At'),
TextEditorField::new('content'),
];
}
En él, he añadido que aparezca el ID del comentario, el nombre de usuario, el título del post, fecha de creación y el contenido. Al igual que en la parte de la búsqueda, username y title al ser campos que no pertenecen a la entidad de comentarios, pero si están relacionados, tendremos que acceder a ellos desde user y post.
Como segundo parámetro, podemos renombrar el nombre de la cabecera del listado.
Según el tipo de campo deberás seleccionar la clase a usar, aunque es bastante intuitivo. Por ejemplo, para created_at que es un campo de fecha, usé DateTimeField.
Con esto ya tienes información para poder seguir por tu cuenta, así que te propongo como tarea que añadas las siguientes mejoras en el panel de administración:
- En el listado de posts aparezca el nombre del usuario que lo crea.
- Al crear un nuevo post que el usuario sea el creador del post y esto no se pueda editar
- Al editar el usuario no aparezca el campo de password.
También te dejo los links a la documentación por si tienes alguna duda:
https://symfony.com/doc/6.2/the-fast-track/en/9-backend.html
https://symfony.com/bundles/EasyAdminBundle/4.x/dashboards.html
Como siempre te dejo en el enlace al repo https://github.com/albertorc87/blog-symfony-tutorial/tree/crear-panel-administracion-symfony-6
Y con esto cerramos este tutorial. Para el próximo veremos como crear tests en nuestro proyecto y así tener una aplicación más robusta y menos propensa a fallos cada vez que subamos cambios.
Espero que este post te ayude y como siempre, te recomiendo seguirme en Twitter para estar al tanto de los nuevo contenido. Ahora también puedes seguirme en Instagram donde estoy subiendo tips, tutoriales en vídeo e información sobre herramientas para developers.
Por último os dejo mi guía para aprender a trabajar con APIs donde explico todo el funcionamiento de una API, el protocolo HTTP y veremos como construir una API con arquitectura REST.
Nos leemos 👋.