Série : Symfony 7
Fichiers : https://github.com/NouvelleTechno/OpenBlog
Dans cet article, nous allons vous guider à travers le processus de création de formulaires sous Symfony, en utilisant le projet OpenBlog comme exemple. Nous allons aborder l'ajout de mots-clés, de catégories, ainsi que la création d'articles de blog, le tout en exploitant les fonctionnalités offertes par Symfony pour gérer les relations entre les entités, la validation des formulaires, et l'intégration des formulaires dans les vues Twig.
Prérequis
Avant de commencer, assurez-vous d'avoir un environnement Symfony fonctionnel, avec le projet OpenBlog configuré. Vous pouvez accéder au code source complet ici.
Création d'un Formulaire pour les Mots-Clés
Commençons par créer un formulaire permettant d'ajouter des mots-clés dans notre base de données. Nous allons générer un contrôleur et un formulaire à l'aide de la console Symfony.
Génération du Contrôleur et du Formulaire
Utilisez la commande suivante pour créer un contrôleur dans un sous-dossier Admin
:
symfony console make:controller Admin/KeywordController
Ensuite, générez un formulaire pour les mots-clés :
symfony console make:form AddKeywordFormType
Ce formulaire est lié à l'entité Keyword
qui contient les champs name
et slug
. Le slug sera généré automatiquement à partir du nom du mot-clé.
Implémentation du Contrôleur
Voici un extrait de code pour le contrôleur KeywordController
:
<?php
namespace App\Controller\Admin;
use App\Entity\Keywords;
use App\Form\AddKeywordFormType;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\String\Slugger\SluggerInterface;
#[Route('/admin/keywords', name: 'app_admin_keywords_')]
class KeywordsController extends AbstractController
{
#[Route('/', name: 'index')]
public function index(): Response
{
return $this->render('admin/keywords/index.html.twig', [
'controller_name' => 'KeywordsController',
]);
}
#[Route('/ajouter', name: 'add')]
public function addKeyword(
Request $request,
SluggerInterface $slugger,
EntityManagerInterface $em
): Response
{
// On initialise un mot clé
$keyword = new Keywords();
// On initialise le formulaire
$keywordForm = $this->createForm(AddKeywordFormType::class, $keyword);
// On traite le formulaire
$keywordForm->handleRequest($request);
// On vérifie si le formulaire est envoyé et valide
if($keywordForm->isSubmitted() && $keywordForm->isValid()){
// On crée le slug
$slug = strtolower($slugger->slug($keyword->getName()));
// On attribue le slug à notre mot clé
$keyword->setSlug($slug);
// On enregistre le mot clé en base de données
$em->persist($keyword);
$em->flush();
$this->addFlash('success', 'Le mot-clé a été créé');
return $this->redirectToRoute('app_admin_keywords_index');
}
// On affiche la vue
return $this->render('admin/keywords/add.html.twig', [
'keywordForm' => $keywordForm->createView(),
]);
}
}
Ce code initialise un mot-clé vide, puis crée et gère le formulaire. Si le formulaire est soumis et valide, le slug est généré, et le mot-clé est enregistré dans la base de données.
Gestion des Catégories avec Relations Parentales
La gestion des catégories implique une relation potentielle entre une catégorie et une autre (parent/enfant). Nous allons aborder la création d'un formulaire permettant cette gestion.
Création du Formulaire pour les Catégories
Utilisez les commandes suivantes pour générer un contrôleur et un formulaire pour les catégories :
symfony console make:controller Admin/CategoryController
symfony console make:form AddCategoryFormType
Dans le formulaire, nous devons permettre la sélection d'une catégorie parente. Voici comment nous pouvons configurer le CategoryFormType
:
<?php
namespace App\Form;
use App\Entity\Categories;
use App\Repository\CategoriesRepository;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class AddCategoriesFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('name', TextType::class, [
'label' => 'Nom de la catégorie'
])
->add('parent', EntityType::class, [
'class' => Categories::class,
'choice_label' => 'name',
'placeholder' => '-- Pas de parent --',
'required' => false,
'query_builder' => function(CategoriesRepository $cr){
return $cr->createQueryBuilder('c')
->orderBy('c.name', 'ASC');
}
])
;
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'data_class' => Categories::class,
]);
}
}
Implémentation du Contrôleur pour les Catégories
Le contrôleur CategoryController
suit une logique similaire à celle du KeywordController
, en prenant en compte la relation parent/enfant.
<?php
namespace App\Controller\Admin;
use App\Entity\Categories;
use App\Form\AddCategoriesFormType;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\String\Slugger\SluggerInterface;
#[Route('/admin/categories', name: 'app_admin_categories_')]
class CategoriesController extends AbstractController
{
#[Route('/', name: 'index')]
public function index(): Response
{
return $this->render('admin/categories/index.html.twig', [
'controller_name' => 'CategoriesController',
]);
}
#[Route('/ajouter', name: 'add')]
public function addCategory(
Request $request,
SluggerInterface $slugger,
EntityManagerInterface $em
): Response
{
// On initialise une catégorie
$category = new Categories();
// On initialise le formulaire
$categoryForm = $this->createForm(AddCategoriesFormType::class, $category);
// On traite le formulaire
$categoryForm->handleRequest($request);
// On vérifie si le formulaire est envoyé et valide
if($categoryForm->isSubmitted() && $categoryForm->isValid()){
// On génère le slug
$slug = strtolower($slugger->slug($category->getName()));
// On ajoute le slug à la catégorie
$category->setSlug($slug);
// On enregistre la catégorie en base de données
$em->persist($category);
$em->flush();
$this->addFlash('success', 'La catégorie a été créée');
return $this->redirectToRoute('app_admin_categories_index');
}
// On affiche la vue
return $this->render('admin/categories/add.html.twig', [
'categoryForm' => $categoryForm->createView(),
]);
}
}
3. Création d'Articles de Blog
Enfin, nous allons créer un formulaire pour ajouter des articles de blog, incluant la gestion des catégories et des mots-clés associés.
Génération du Formulaire pour les Articles
Générez le formulaire et le contrôleur pour les articles avec les commandes suivantes :
symfony console make:controller Profile/PostController
symfony console make:form AddPostFormType
Le formulaire pour les articles inclut des champs pour le titre, le contenu, l'image vedette, les catégories et les mots-clés. Voici un exemple de configuration de ce formulaire :
<?php
namespace App\Form;
use App\Entity\Categories;
use App\Entity\Keywords;
use App\Entity\Posts;
use App\Entity\Users;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class AddPostFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('title', TextType::class, [
'label' => 'Titre de l\'article'
])
->add('content', TextareaType::class, [
'label' => 'Contenu de l\'article'
])
->add('featuredImage', FileType::class, [
'label' => 'Image de l\'article',
'mapped' => false
])
->add('categories', EntityType::class, [
'class' => Categories::class,
'choice_label' => 'name',
'multiple' => true,
'expanded' => true
])
->add('keywords', EntityType::class, [
'class' => Keywords::class,
'choice_label' => 'name',
'multiple' => true,
'expanded' => true
])
;
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'data_class' => Posts::class,
]);
}
}
Gestion des Images et Relations dans le Contrôleur
Dans le contrôleur, nous devons gérer le téléchargement de l'image, ce sera fait dans une prochaine partie
<?php
namespace App\Controller\Profile;
use App\Entity\Posts;
use App\Form\AddPostFormType;
use App\Repository\UsersRepository;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\String\Slugger\SluggerInterface;
#[Route('/profil/articles', name: 'app_profile_posts_')]
class PostsController extends AbstractController
{
#[Route('/', name: 'index')]
public function index(): Response
{
return $this->render('profile/posts/index.html.twig', [
'controller_name' => 'PostsController',
]);
}
#[Route('/ajouter', name: 'add')]
public function addArticle(
Request $request,
SluggerInterface $slugger,
EntityManagerInterface $em,
UsersRepository $usersRepository
): Response
{
$post = new Posts();
$form = $this->createForm(AddPostFormType::class, $post);
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid()){
$post->setSlug(strtolower($slugger->slug($post->getTitle())));
$post->setUsers($usersRepository->find(1));
$post->setFeaturedImage('default.webp');
$em->persist($post);
$em->flush();
$this->addFlash('success', 'L\'article a été créé');
return $this->redirectToRoute('app_profile_posts_index');
}
return $this->render('profile/posts/add.html.twig', [
'form' => $form->createView(),
]);
}
}
Conclusion
Avec ces formulaires, vous avez maintenant une base solide pour gérer l'ajout de contenus dynamiques dans votre blog Symfony. Que ce soit pour des mots-clés, des catégories ou des articles, ces concepts peuvent être étendus pour inclure des fonctionnalités plus avancées, telles que la gestion des utilisateurs, des permissions, et bien plus encore.
N'hésitez pas à explorer et à adapter ces exemples pour répondre à vos besoins spécifiques, et si vous avez des questions, la communauté est là pour vous aider.
Obtenir de l'aide
Pour obtenir de l'aide, vous pouvez accéder au serveur Discord pour une entraide par chat.
Catégories : Symfony formulaire Symfony 7
Mots-clés : Symfony Formulaires entity Symfony 7