D'accord !
L'affichage de tous les commentaires
On va plutôt continuer nos vues liées à notre panneau d'administration. On va donc faire pour commencer la vue qui permet d'afficher tous nos commentaires. C'est assez simple, ça ressemble grandement à celle qui permet d'afficher tous les utilisateurs.
Simple amélioration, je vais utiliser @if de Blade pour faire une condition et afficher si le commentaire est signalé ou non !
{"language":"application/x-httpd-php","content":"<x-app-layout>\n <x-slot name=\"header\">\n <h2 class=\"font-semibold text-xl text-gray-800 leading-tight\">\n Gestion des commentaires\n </h2>\n </x-slot>\n\n <div class=\"py-12\">\n <div class=\"max-w-7xl mx-auto sm:px-6 lg:px-8\">\n <div class=\"bg-white overflow-hidden shadow-sm sm:rounded-lg\">\n <h3 class=\"text-3xl mx-4 my-4\">Les commentaires du site</h3>\n <div class=\"flex flex-col\">\n <div class=\"-my-2 overflow-x-auto sm:-mx-6 lg:-mx-8\">\n <div class=\"py-2 align-middle inline-block min-w-full sm:px-6 lg:px-8\">\n <div class=\"shadow overflow-hidden border-b border-gray-200 sm:rounded-lg\">\n <table class=\"min-w-full divide-y divide-gray-200\">\n <thead class=\"bg-gray-50\">\n <tr>\n <th scope=\"col\" class=\"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider\">\n Titre\n </th>\n <th scope=\"col\" class=\"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider\">\n Auteur\n </th>\n <th scope=\"col\" class=\"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider\">\n Contenu\n </th>\n <th scope=\"col\" class=\"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider\">\n Statut\n </th>\n <th scope=\"col\" class=\"relative px-6 py-3\">\n <span class=\"sr-only\">Modifier/Supprimer</span>\n </th>\n </tr>\n </thead>\n <tbody class=\"bg-white divide-y divide-gray-200\">\n @foreach($comments as $comment)\n <tr>\n <td class=\"px-6 py-4 whitespace-nowrap\">\n <div class=\"text-sm font-medium text-gray-900\">\n {{ $comment->title }}\n </div>\n </td>\n <td class=\"px-6 py-4 whitespace-nowrap\">\n <div class=\"text-sm font-medium text-gray-900\">\n {{ $comment->author }}\n </div>\n </td>\n <td class=\"px-6 py-4 whitespace-nowrap\">\n <div class=\"text-sm font-medium text-gray-900\">\n {{ $comment->content }}\n </div>\n </td>\n <td class=\"px-6 py-4 whitespace-nowrap\">\n <div class=\"text-sm font-medium text-gray-900\">\n @if($comment->reported)\n <span class=\"text-red-600\">Signalé</span>\n @else\n Non reporté\n @endif\n </div>\n </td>\n <td class=\"px-6 py-4 whitespace-nowrap text-right text-sm font-medium\">\n <a href=\"{{ route('comments.edit', $comment) }}\" class=\"text-indigo-600 hover:text-indigo-900\">Modifier</a>\n <a href=\"{{ route('comments.destroy', $comment) }}\" class=\"text-red-600 hover:text-red-900\">Supprimer</a>\n </td>\n </tr>\n @endforeach\n </tbody>\n </table>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n</x-app-layout>","filename":"resources/views/comments/index.blade.php"}
Et comment on pourrait faire pour afficher le titre du post dans lequel a été écrit le commentaire ?
Bien vu Arthur. On va se baser sur les relationships. Dans notre entité Comment on a créé la méthode post qui nous permet de le récupérer ce fameux post. Vois comment on utilise ça :
{"language":"application/x-httpd-php","content":"<td class=\"px-6 py-4 whitespace-nowrap\">\n <div class=\"text-sm font-medium text-gray-900\">\n <a href=\"{{ route('posts.show', $comment->post) }}\">\n {{ $comment->post->title }}\n </a>\n </div>\n</td>","filename":"resources/views/comments/index.blade.php"}
Tout simplement !
Hé oui, comme souvent dans Laravel, c'est très simple...
La création d'un post
On va passer à la création d'un post maintenant. On va donc traiter les formulaires !
Intéressant !
Comme d'habitude on commence par créer notre vue. Ici, ce sera dans resources/views/posts/create.blade.php.
Voici ce que je te propose pour le formulaire. Y'a-t-il des choses qui te choquent ?
{"language":"text/html","content":"<x-app-layout>\n <x-slot name=\"header\">\n <h2 class=\"font-semibold text-xl text-gray-800 leading-tight\">\n Gestion des posts\n </h2>\n </x-slot>\n\n <div class=\"py-12\">\n <div class=\"max-w-7xl mx-auto sm:px-6 lg:px-8\">\n <div class=\"bg-white overflow-hidden shadow-sm sm:rounded-lg\">\n <h3 class=\"text-3xl mx-4 my-4\">Création d'un post</h3>\n <form action=\"{{ route('posts.store') }}\" method=\"POST\" class=\"mx-auto\">\n @csrf\n <div class=\"px-4 py-5 bg-white sm:p-6\">\n <div class=\"py-2\">\n <label for=\"title\" class=\"block text-sm font-medium text-gray-700\">Titre</label>\n <input type=\"text\" name=\"title\" id=\"title\" class=\"mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md\">\n </div>\n <div class=\"py-2\">\n <label for=\"content\" class=\"block text-sm font-medium text-gray-700\">Contenu</label>\n <textarea id=\"content\" name=\"content\" rows=\"3\" class=\"shadow-sm focus:ring-indigo-500 focus:border-indigo-500 mt-1 block w-full sm:text-sm border-gray-300 rounded-md\"></textarea>\n </div>\n <div class=\"py-2\">\n <input type=\"submit\" class=\"cursor-pointer inline-flex items-center w-1/4 py-4 border border-gray-400 shadow-sm text-base font-medium rounded-md text-gray-700 bg-white justify-center\" value=\"Créer\">\n </div>\n </div>\n </form>\n </div>\n </div>\n </div>\n</x-app-layout>","filename":"views/posts/create.blade.php"}
C'est quoi @csrf ?
Je t'en avais un petit peu parlé, c'est pour éviter que notre site soit sensible à faille CSRF. Cette fonction de blade va gérer un input hidden qui contient un token de sécurité. Si tu fais inspecter l'élément, tu verras à input de cette forme :
{"language":"text/html","content":"<input type=\"hidden\" name=\"_token\" value=\"VY9XpHxUGgfWk7mx9oOgozAPALBAnPWpL7GRLgQA\">","filename":""}
Si on ne le met pas, on aura une erreur lors de la soumission du formulaire. L'utilisation du token CSRF est obligatoire ;)
Donc c'est tout ce qu'il faut savoir au niveau des formulaires ?
Non. Tu te rappelles de $request->validate ? Je t'avais dit que si des erreurs étaient soulevées, on retournait au formulaire. Mais il faut maintenant afficher les erreurs ! Qui seront en Français grâce aux traductions qu'on a téléchargées au début du cours ;)
Pour ça, Blade met à notre disposition la fonction @error qu'on utilise comme suit :
{"language":"text/html","content":"<form action=\"{{ route('posts.store') }}\" method=\"POST\" class=\"mx-auto\">\n @csrf\n <div class=\"px-4 py-5 bg-white sm:p-6\">\n <div class=\"py-2\">\n <label for=\"title\" class=\"block text-sm font-medium text-gray-700\">Titre</label>\n <input type=\"text\" name=\"title\" id=\"title\" class=\"mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md\" value=\"{{ old('title') }}\">\n @error('title')\n <span class=\"text-red-600\">{{ $message }}</span>\n @enderror\n </div>\n <div class=\"py-2\">\n <label for=\"content\" class=\"block text-sm font-medium text-gray-700\">Contenu</label>\n <textarea id=\"content\" name=\"content\" rows=\"3\" class=\"shadow-sm focus:ring-indigo-500 focus:border-indigo-500 mt-1 block w-full sm:text-sm border-gray-300 rounded-md\">{{ old('content') }}</textarea>\n @error('content')\n <span class=\"text-red-600\">{{ $message }}</span>\n @enderror\n </div>\n <div class=\"py-2\">\n <input type=\"submit\" class=\"cursor-pointer inline-flex items-center w-1/4 py-4 border border-gray-400 shadow-sm text-base font-medium rounded-md text-gray-700 bg-white justify-center\" value=\"Créer\">\n </div>\n </div>\n</form>","filename":"views/posts/create.blade.php"}
Ce qui serait bien aussi, c'est de remettre les champs avec leur ancienne valeur s'il y a eu une erreur. Encore une fois, Blade a ce qu'il nous faut ! On va utiliser la fonction old().
{"language":"text/html","content":"<input type=\"text\" name=\"title\" id=\"title\" class=\"mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md\" value=\"{{ old('title') }}\">","filename":"views/posts/create.blade.php"}
Et enfin, on retournait un message de succès si tout avait fonctionné. Il serait temps de l'afficher ! Les messages flash sont stockés dans des sessions et comme d'habitude Blade a une fonction pour afficher le contenu d'une clé de session. Au final, notre code ressemble donc à :
{"language":"text/html","content":"<x-app-layout>\n <x-slot name=\"header\">\n <h2 class=\"font-semibold text-xl text-gray-800 leading-tight\">\n Gestion des posts\n </h2>\n </x-slot>\n\n <div class=\"py-12\">\n <div class=\"max-w-7xl mx-auto sm:px-6 lg:px-8\">\n <div class=\"bg-white overflow-hidden shadow-sm sm:rounded-lg\">\n <h3 class=\"text-3xl mx-4 my-4\">Création d'un post</h3>\n @if(session('success'))\n <div class=\"text-xl text-green-400\">\n {{ session('success') }}\n </div>\n @endif\n <form action=\"{{ route('posts.store') }}\" method=\"POST\" class=\"mx-auto\">\n @csrf\n <div class=\"px-4 py-5 bg-white sm:p-6\">\n <div class=\"py-2\">\n <label for=\"title\" class=\"block text-sm font-medium text-gray-700\">Titre</label>\n <input type=\"text\" name=\"title\" id=\"title\" class=\"mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md\" value=\"{{ old('title') }}\">\n @error('title')\n <span class=\"text-red-600\">{{ $message }}</span>\n @enderror\n </div>\n <div class=\"py-2\">\n <label for=\"content\" class=\"block text-sm font-medium text-gray-700\">Contenu</label>\n <textarea id=\"content\" name=\"content\" rows=\"3\" class=\"shadow-sm focus:ring-indigo-500 focus:border-indigo-500 mt-1 block w-full sm:text-sm border-gray-300 rounded-md\">{{ old('content') }}</textarea>\n @error('content')\n <span class=\"text-red-600\">{{ $message }}</span>\n @enderror\n </div>\n <div class=\"py-2\">\n <input type=\"submit\" class=\"cursor-pointer inline-flex items-center w-1/4 py-4 border border-gray-400 shadow-sm text-base font-medium rounded-md text-gray-700 bg-white justify-center\" value=\"Créer\">\n </div>\n </div>\n </form>\n </div>\n </div>\n </div>\n</x-app-layout>","filename":"views/posts/create.blade.php"}
On a vu beaucoup de choses ! Mais je suis si impatient de tester !
Hé bien, tu le peux, je te laisse remplir le formulaire et créer ton premier post !
Il nous resterait encore 2 vues à voir du côté du tableau de bord : l'édition des posts et des commentaires. Pour t'entrainer, je ne te fournis pas la solution. Quelques indications tout de même :
- Pour utiliser old() avec une valeur par défaut, on peut faire {{ old('valeur', $valeurParDefaut) }}, par exemple old('title', $post->title)
- Nos routes pour les requêtes d'update sont de type PUT ou PATCH. On ne peut pas préciser ce type de requête dans method="" d'un formulaire, il faut utiliser method="POST" et rajouter un champ hidden généré par Laravel comme @csrf. Dans le cas de PUT, on mettra @method('PUT').
Ok je vais essayer de faire ça ! Merci !
Bilan de cette partie :
J'ai terminé cette partie - La gestion des formulaires avec Blade
- L'utilisation des relationship au sein des vues