Découverte des notions fondamentales de Laravel à travers un cas concret.
Sommaire
- Création du modèle
- Création du contrôleur
- Création des vues
- Validation des données
- Contrôle d’accès
- Les tests
Le concept
Laravel dispose de son propre moteur de template nommé Blade. Celui-ci permet d’injecter facilement de la dynamique au sein du html.
Voici un exemple d’une variable injecté avec du php pur :
1Bonjour, je m'appelle <?= $name ?>
Et le même résultat avec Blade :
1Bonjour, je m'appelle {{ $name }}
Pour être plus exact avec l'exemple en PHP pur, il aurait fallu englober l’utilisation de la variable par l’appel de la fonction htmlspecialchars
, détail non-négligeable car il permet de se prémunir contre les attaques XSS. C'est aussi ça l'avantage d'utiliser un moteur de template.
Blade offre aussi de nombreuses fonctions appelées directives : des conditions, des boucles, etc.
Mais ce moteur permet surtout de fragmenter ses vues afin de limiter la duplication du code et ainsi permettre de changer un design de manière plus optimisée.
Cette fragmentation est gérable de 2 manières. Historiquement via l’héritage des vues et aussi via la notion de composants introduite à la version 7.
Nous allons dans ce tutoriel utiliser les composants pour la gestion de nos vues. C’est parti !
Avant de continuer assurez-vous d’avoir compris comment, depuis le contrôleur, des variables sont injectées à la vue.
Création du layout
Tout d’abord nous allons commencer par le layout. Le layout définit la structure globale de nos vues. Il contient à peu près tout sauf le contenu spécifique d’une page.
Voici notre fichier resources/views/components/layout.blade.php
:
1<!DOCTYPE html> 2<html lang="fr"> 3 <head> 4 <meta charset="utf8"> 5 <title>{{ $title ?? 'Laravel France : Les bases' }}</title> 6 </head> 7 <body> 8 <header><h1><a href="/">Laravel France: Les bases</a></h1></header> 9 <main>{{ $slot }}</main>10 </body>11</html>
Le point d’attention est la présence de deux variables qui sont toutes deux des slots
c’est à dire qu’elles seront remplacées par du contenu définit dans les vues, c'est ce qu’on va voir dans le paragraphe suivant.
A cet instant, gardons en tête que la variable $title
sera remplacée par 'Laravel France : Les bases'
si elle n’est pas définit au sein d’une vue et que la variable $slot
permet d’injecter le contenu d’une vue.
Afin de simplifier la compréhension des vues au maximum, j’ai volontairement exclu toutes notions de style.
Création des vues de lecture
Maintenant que l’ossature de nos pages est définit, nous allons définir le contenu de deux d’entre elles :
- La page
index
qui liste nos restaurants - La page
show
qui affiche les informations d’un restaurant
Voici le contenu de la page index
définit dans le fichier resources/views/restaurants/index.blade.php
:
1<x-layout> 2 <x-slot:title>Liste des restaurants</x-slot:title> 3 4 <h2>Liste des restaurants</h2> 5 <div style="margin-bottom: 1rem"> 6 <a href="{{ route('restaurants.create') }}">Créer un restaurant</a> 7 </div> 8 <table> 9 <thead>10 <tr>11 <th>Nom</th>12 <th>Type</th>13 <th>Restaurateur</th>14 </tr>15 </thead>16 <tbody>17 @foreach($restaurants as $restaurant)18 <tr>19 <td>20 <a href="{{ route('restaurants.show', $restaurant) }}">{{ $restaurant->name }}</a>21 </td>22 <td>{{ $restaurant->type }}</td>23 <td>{{ $restaurant->user->name }}</td>24 </tr>25 @endforeach26 </tbody>27 </table>28</x-layout>
On distingue plusieurs choses. La première c'est la présence de balises un peu bizarre préfixées par x-
. Ces balises permettent à Blade de les interpréter comme des composants.
On a donc un appel au composant x-layout
qui est celui qu’on a précédemment écrit. Tout le contenu compris entre ses balises sara injecté à la place de la variable $slot
dans le layout.
Tout sauf le contenu de la balise x-slot:title
qui elle permet d’injecter son contenu à la place de la variable $title
définit dans le layout.
Autre point notable est l’utilisation pour la première d’une directive blade: @foreach
qui permet de boucler sur les éléments du tableau $restaurants
qui a été injecté dans la vue via le contrôleur.
Enfin, l’utilisation de la fonction route()
qui permet de résoudre, depuis son nom, le chemin d’une route définit dans le fichier routes/web.php
.
On continue avec la vue show
définit dans le fichier resources/views/restaurants/show.blade.php
1<x-layout> 2 <x-slot:title>{{ $restaurant->name }}</x-slot:title> 3 4 <h2> 5 <a href="{{ route('restaurants.index') }}">Restaurants</a> / {{ $restaurant->name }} 6 </h2> 7 <div style="margin-bottom: 1rem"> 8 <a href="{{ route('restaurants.edit', $restaurant) }}">Editer</a> | 9 <form style="display: inline-block" action="{{ route('restaurants.destroy', $restaurant) }}" method="POST">10 @csrf11 @method('delete')12 <a href="{{ route('restaurants.destroy', $restaurant) }}" onclick="event.preventDefault(); this.closest('form').submit();">Supprimer</a>13 </form>14 </div>15 <ul>16 <li>Type : {{ $restaurant->type }}</li>17 <li>Adresse : {{ $restaurant->address }}</li>18 </ul>19</x-layout>
La particularité de cette page réside dans le fait qu’on y définit un formulaire pour la suppression du restaurant ciblé. Pourquoi ? Parce que le verbe qu’on a définit dans la route de suppression et qui respecte le standard est delete
.
Cela nous permet d’introduire deux nouveautés. La première c’est la directive @csrf
qui créer un champ caché qui contient le jeton qui validera notre formulaire. La seconde c’est l’appel à @method('delete)
qui permet de spécifier à Laravel que le verbe utilisé est bien delete
car en html on ne peut définir uniquement que la method en GET
ou en POST
dans un formulaire.
Le jeton CSRF permet de s’assurer que le site qui a émit la requête est bien celui de notre application.
Création des composants du formulaire
La création de petit composant réutilisable permet de vraiment gagner du temps et d’éviter les oublis lors de modifications de style à apporter de manière globale à l’application.
Nos formulaires de création et d’édition d’un restaurant vont contenir des champs de type texte, on va donc créer un premier composant nommé input
dans le dossier resources/views/components
:
1<input {{ $attributes }}/>
La variable $attributes
contient les attributs définit lors de l’appel du composant, exemple :
1<x-input id="name" name="name" type="text" :value="old('name')"/>
A noter qu’un attribut préfixé de :
permet l’injection de code PHP, utile dans notre cas pour appeler la fonction old()
.
Un autre composant pertinent à créer est celui du libellé d’un champ, on va ainsi créer le fichier resources/views/components/label.blade.php
:
1<label {{ $attributes }}>2 {{ $slot }}3</label>
Que l’on va utiliser de la manière suivante :
1<x-label for="name">Nom</x-label>
Ainsi Nom
viendra remplacer $slot
et l’attribut for
sera injecté dans la variable $attributes
.
Création des vues d’écriture
Maintenant on a tous les éléments à notre disposition pour créer les formulaires.
On commence par le formulaire de création d’un restaurant qu’on va définir dans le fichier resources/views/restaurants/create.blade.php
:
1<x-layout> 2 <x-slot:title>Créer un restaurant</x-slot:title> 3 4 <h2 style="margin-bottom: 2rem"> 5 <a href="{{ route('restaurants.index') }}">Restaurants</a> / Créer un restaurant 6 </h2> 7 <form action="{{ route('restaurants.store') }}" method="POST"> 8 @csrf 9 <div style="margin-bottom: 1rem">10 <x-label for="name">Nom</x-label>11 <x-input id="name" name="name" type="text" :value="old('name')"/>12 </div>13 <div style="margin-bottom: 1rem">14 <x-label for="type">Type</x-label>15 <x-input id="type" name="type" type="text" :value="old('type')"/>16 </div>17 <div style="margin-bottom: 1rem">18 <x-label for="type">Adresse</x-label>19 <x-input id="address" name="address" type="text" :value="old('address')"/>20 </div>21 <button type="submit">Enregistrer</button>22 </form>23</x-layout>
Ici, rien de nouveau à l’horizon si ce n’est l’utilisation de nos deux nouveaux composants x-label
et x-input
.
On termine avec notre formulaire d’édition d’un restaurant resources/views/restaurants/edit.blade.php
:
1<x-layout> 2 <x-slot:title>Edition du restaurant {{ $restaurant->name }}</x-slot:title> 3 4 <h2 style="margin-bottom: 2rem"> 5 <a href="{{ route('restaurants.index') }}">Restaurants</a> / 6 <a href="{{ route('restaurants.show', $restaurant) }}">{{ $restaurant->name }} </a> / 7 Edition 8 </h2> 9 <form action="{{ route('restaurants.update', $restaurant) }}" method="POST">10 @csrf11 @method('put')12 <div style="margin-bottom: 1rem">13 <x-label for="name">Nom</x-label>14 <x-input id="name" name="name" type="text" :value="old('name', $restaurant->name)"/>15 </div>16 <div style="margin-bottom: 1rem">17 <x-label for="type">Type</x-label>18 <x-input id="type" name="type" type="text" :value="old('type', $restaurant->type)"/>19 </div>20 <div style="margin-bottom: 1rem">21 <x-label for="type">Adresse</x-label>22 <x-input id="address" name="address" type="text" :value="old('address', $restaurant->address)"/>23 </div>24 <button type="submit">Enregistrer</button>25 </form>26</x-layout>
Pour cette vue, on définit le verbe put
à travers la directive @method
, car on respecte une nouvelle fois le standard, et on injecte en valeur par défaut dans les champs celles actuelles du restaurant.
Et voilà, l'ensemble de nos vues sont prêtes !
Dans le prochain épisode…
Nous avons parcouru l'ensemble de l’architecture MVC, il est temps de consolider notre application avec la validation des entrées du formulaire via les FormRequest
!
Source : https://github.com/laravel-fr/support-les-bases/tree/v3
A lire
Autres articles de la même catégorie
Effectuer rapidement des benchmarks dans Laravel
Voyons comment le nouveau service Benchmark de Laravel fonctionne !
Mathieu De Gracia
Traquer un utilisateur dans les logs
Laravel offre la possibilité d'ajouter un contexte unique à chaque ligne de log, voyons comment utiliser cette feature pour traquer les erreurs d'un utilisateur !
Mathieu De Gracia
Maîtrisez la relation morphMany
Démystifions les relations polymorphiques morphMany et morphOne à l'aide d'un exercice pratique !
Mathieu De Gracia