Maintenant que nous savons créer / peupler notre BDD et récupérer des données d’utilisateurs, nous allons voir comment les afficher et modifier.
Nous verrons dans cette troisième partie la configuration des assets et comment afficher nos utilisateurs à l’aide du moteur de template Twig. Enfin nous découvrirons les Forms qui permettront de modifier les informations utilisateurs.
Nous utiliserons le bundle webpack-encore-bundle, qui nous permettra de compiler nos assets en 1 seul fichier CSSFeuilles de style qui permettent de mettre en forme des pages web. et 1 seul fichier JS à travers un serveur Node. Cela fera gagner en performance pour charger tous nos assets (idéal pour les sites importants avec énormément de ressources à utiliser).
Tout d’abord, il faut ajouter le bundle webpack-encore-bundle :
composer require symfony/webpack-encore-bundle
Ensuite, comme nous utilisons un serveur Node pour compiler les assets, il est nécessaire d’installer Node pour pouvoir utiliser les commandes npm.
Une fois Node installé, nous pouvons installer les packages JS du fichier package.js (les développeurs AngularAngular est un framework de développement JavaScript populaire basé sur TypeScript. / ReactReact est un framework de développement JavaScript populaire. / Vue.jsFramework JavaScript populaire. ne seront pas dépaysés) avec la commande :
npm install
À présent, nous avons accès à la commande encore : elle permet de lancer un serveur Node qui va compiler en direct nos assets à chaque modification (très pratique pendant le développement) :
encore dev-server
Un fichier manifest.json dans le dossier public/build est mis à jour pour indiquer sur quels liens sont accessibles nos assets :
{
"build/app.css": "http://localhost:8080/build/app.css",
"build/app.js": "http://localhost:8080/build/app.js",
"build/runtime.js": "http://localhost:8080/build/runtime.js",
"build/vendors~app.js": "http://localhost:8080/build/vendors~app.js"
}
Les fichiers app.css et app.js sont disponibles dans le dossier assets. Ce sont ces fichiers qui vont contenir tout le CSS et JS de notre application. On peut directement écrire dedans mais surtout faire des imports de fichiers pour que ce soit plus lisible.
Finalement, nous devons importer les fichiers app.css et app.js dans notre template base.html.twig dans le dossier templates pour que tous les templates "enfants", que nous créerons plus tard pour les utilisateurs, puissent utiliser les assets :
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>{% block title %}{% endblock %}</title>
{% block stylesheets %}
<!-- Ajout du CSS -->
{{ encore_entry_link_tags(’app’) }}
{% endblock %}
</head>
<body>
{% block body %}{% endblock %}
{% block javascripts %}
<!-- Ajout du JS -->
{{ encore_entry_script_tags(’app’) }}
{% endblock %}
</body>
</html>
Le SASS est presque indispensable. Il va nous permettre d’avoir un code beaucoup plus lisible et surtout utiliser @import
pour importer le CSS d’autres packages (comme Bootstrap).
Le fichier webpack.config.js à la racine du projet doit être modifié pour activer le SASS :
...
// enables Sass/SCSS support
.enableSassLoader() // Décommenter cette ligne pour activer le SASS
...
Enfin, il suffit d’installer les packages JS suivants :
npm install sass-loader@^8.0.0 node-sass --save-dev
On peut maintenant renommer le fichier app.css en app.sccs et relance le serveur Node (commande encore dev-server
).
Nous allons maintenant ajouter Bootstrap à notre application et donc dans nos assets. Pour cela, il faut d’abord ajouter le package npm Bootstrap :
npm install bootstrap jquery popper.js --save
Ensuite, dans le fichier app.sccs, nous rajoutons le CSS de Bootstrap :
@import "~bootstrap/dist/css/bootstrap.min.css";
Enfin, on importe le JS de Bootstrap dans app.js :
// CSS
import ’../css/app.scss’;
// JS
import ’bootstrap’;
Et voilà ! Nous pouvons maintenant commencer à faire de belles templates Twig.
Nous allons maintenant créer notre première page à l’aide du moteur de template Twig.
Le nouveau template users.html.twig sera ajouté à un nouveau dossier users dans le dossier templates.
Il affichera la liste de nos utilisateurs :
// template users. sauvegardée dans le dossier templates
{% extends "base.html.twig" %}
{% block title %}Tableau utilisateurs{% endblock %}
{% block body %}
<div class="p-5">
<h2>Tableau utilisateurs</h2>
<table class="table table-responsive">
<tr>
<th>Prénom</th>
<th>Nom</th>
<th>Date anniversaire</th>
<th>Description</th>
</tr>
{% for user in users %}
<tr>
<td>{{ user.firstName }}</td>
<td>{{ user.lastName }}</td>
<td>{{ user.birthday|date(’d/m/Y’) }}</td>
<td>{{ user.description }}</td>
</tr>
{% endfor %}
</table>
</div>
{% endblock %}
On peut voir {% extends "base.html.twig" %}
en première ligne du code. Cela va nous permettre de modifier les block renseignés dans base.html.twig.
Ainsi, on peut modifier le block title et le block body de base.html.twig.
Le Controller UserController.php doit être modifié pour retourner le template Twig à la place du JSON actuellement :
...
public function getUsers(UserManager $userManager)
{
$users = $userManager->findAllWithDescription();
return $this->render(’users/users.html.twig’, [’users’ => $users]);
}
...
On utilise la fonction render
pour renseigner le template Twig ainsi que la variable contenant nos utilisateurs accessibles dans la template.
La page listant les utilisateurs doit ressembler à cela si tout se passe bien de votre côté (toujours accessible à l’adresse http://localhost:8000/users) :
Le template user.html.twig sera également ajouté au dossier users dans le dossier templates.
Il affichera la fiche d’un utilisateur :
{% extends "base.html.twig" %}
{% block title %}Fiche utilisateur{% endblock %}
{% block body %}
<div class="p-5">
<div class="row">
<div class="col">
<h2>Fiche utilisateur</h2>
</div>
<div class="col-auto">
<a class="btn btn-primary" href="{{ path(’get-users’) }}"> Retour</a>
</div>
</div>
<p>Prénom : {{ user.firstName }}</p>
<p>Nom : {{ user.lastName }}</p>
<p>Né(e) le : {{ user.birthday|date(’d/m/Y’) }}</p>
<p>Description : {{ user.description }}</p>
</div>
{% endblock %}
Le Controller UserController.php doit également être modifié pour retourner le template Twig :
<?php
...
public function getOneUser(UserManager $userManager, int $id)
{
$user = $userManager->findOneWithDescription($id);
return $this->render(’users/user.html.twig’, [’user’ => $user]);
}
...
La fiche utilisateur devrait ressembler à cela (http://localhost:8000/users/1) :
Nous allons rajouter un bouton à chaque utilisateur pour accéder à sa fiche :
...
<table class="table table-responsive">
<tr>
<th>Prénom</th>
<th>Nom</th>
<th>Date anniversaire</th>
<th>Description</th>
<!-- Ajout d’une entête vide -->
<th></th>
</tr>
{% for user in users %}
<tr>
<td>{{ user.firstName }}</td>
<td>{{ user.lastName }}</td>
<td>{{ user.birthday|date(’d/m/Y’) }}</td>
<td>{{ user.description }}</td>
<!-- Ajout du bouton pour accéder à la fiche d’un user -->
<td>
<a href="{{ path(’get-user’, {id: user.id}) }}" class="btn btn-primary">Voir</a>
</td>
</tr>
{% endfor %}
</table>
...
Un nouveau bouton est disponible pour accéder à la fiche utilisateur :
SymfonyFramework PHP permettant de développer des applications web. nous permet, à travers l’utilisation de Forms, de mettre très facilement en place des formulaires de création / mise à jour.
Nous verrons ici comment modifier un utilisateur à travers un Form que nous créerons.
Il nous faudra tout d’abord ajouter le package form :
composer require symfony/form
Un FormType nous permet d’instancier un Form qui pourra être utilisé plusieurs fois par la suite. Cela évite la redondance de code et donc de créer plusieurs fois le même Form.
Le fichier UserType.php est créé dans le dossier Type du dossier Form (à créer si nécessaire) :
<?php
namespace App\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
class UserType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add(’firstname’, TextType::class, [’label’ => ’Prénom’])
->add(’lastname’, TextType::class, [’label’ => ’Nom’])
->add(’birthday’, DateType::class, [
’label’ => ’Né(e) le’,
’attr’ => [’placeholder’ => ’dd/mm/yyyy’],
’widget’ => ’single_text’,
’format’ => ’dd/MM/yyyy’,
’input’ => ’datetime’,
’html5’ => false
])
->add(’save’, SubmitType::class)
->getForm();
}
}
Nous pouvons voir que le Form comporte :
Si vous avez besoin d’un autre type de champ (textarea, number, datetime, ... ) ou pour découvrir plus en détails la configuration d’un Form, vous pouvez vous référer à la documentation Symfony.
Nous devons maintenant modifier notre UserController.php pour y ajouter le Form que nous venons de créer.
Le formulaire de modification sera visible dans la fiche utilisateur, donc c’est la fonction getOneUser() qui doit être modifiée en conséquence :
<?php
...
public function getOneUser(UserManager $userManager, int $id)
{
$user = $userManager->findOneWithDescription($id);
// Création de notre Form auquel on passe notre objet User.
$form = $this->createForm(UserType::class, $user);
// On rajoute le Form au template de la fiche utilisateur pour pouvoir l’afficher.
return $this->render(’users/user.html.twig’, [’user’ => $user, ’form’ => $form->createView()]);
}
...
Côté template Twig, la nouvelle variable form passée au template va nous permettre d’afficher le formulaire :
{% extends "base.html.twig" %}
{% block title %}Fiche utilisateur{% endblock %}
{% block body %}
<div class="p-5">
<div class="row">
<div class="col">
<h2>Fiche utilisateur</h2>
</div>
<div class="col-auto">
<a class="btn btn-primary" href="{{ path(’get-users’) }}"> Retour</a>
</div>
</div>
<p>Prénom : {{ user.firstName }}</p>
<p>Nom : {{ user.lastName }}</p>
<p>Né(e) le : {{ user.birthday|date(’d/m/Y’) }}</p>
<p>Description : {{ user.description }}</p>
{# Ajout du form #}
<h2>Modifier utilisateur</h2>
{{ form(form) }}
</div>
{% endblock %}
Nous obtenons un formulaire pré-rempli avec le nom, prénom, date anniversaire de notre utilisateur dans sa fiche :
Il serait assez long de rajouter notre style CSS sur notre formulaire mais pas de panique, il est possible d’ajouter automatiquement un thème Bootstrap à tous les formulaires.
Pour cela, il suffit de modifier le fichier twig.yaml dans le dossier packages :
twig:
default_path: ’%kernel.project_dir%/templates’
form_themes: [’bootstrap_4_layout.html.twig’] # Ajout du thème Bootstrap
Le résultat est désormais un peu plus convaincant :
Si nous essayons de cliquer sur le bouton Enregistrer de notre formulaire, nous pouvons constater que la page se recharge sans prendre en compte les modifications dans le formulaire.
Nous allons ajouter une méthode postUser() dans notre UserController.php qui se chargera de recevoir le formulaire soumis et de sauvegarder l’utilisateur :
<?php
/**
* @Route("/users/{id}", name="post-user", requirements={"id"="\d+"}, methods={"POST"})
*
* @param UserManager $userManager
* @param Request $request
* @param int $id
* @return Response
* @throws Exception
*/
public function postUser(UserManager $userManager, Request $request, int $id)
{
$user = $userManager->findOneWithDescription($id);
$form = $this->createForm(UserType::class, $user);
$form->handleRequest($request);
// Si le formulaire est soumis et valide
if ($form->isSubmitted() && $form->isValid()) {
// On récupère l’utilisateur dans le formulaire
/** @var User $user */
$user = $form->getData();
// On sauvegarde l’utilisateur
$em = $this->getDoctrine()->getManager();
$em->persist($user);
$em->flush();
}
// On redirige sur la fiche utilisateur
return $this->redirectToRoute(’get-user’, [’id’ => $user->getId()]);
}
Pour que le formulaire soit soumis dans cette fonction, il faut modifier son action et sa méthode dans le template :
...
{# Modification de l’action et de la méthode du form #}
<h2>Modifier utilisateur</h2>
{{ form(form, {’action’: path(’post-user’, {id: user.id}), ’method’: ’POST’}) }}
...
Il est maintenant temps de modifier le formulaire d’une fiche utilisateur et de valider les modifications :
Maintenant que nous maîtrisons les templates Twig et les Forms, la prochaine partie portera sur la mise en place d’une authentification JWT. Nous créerons une page de connexion et verrons la gestion des rôles utilisateur.
À BIENTÔT ♥