Templating: Razor
Templating Razor
Afficher de l'HTML et du CSS statique a ses limites. Si tu souhaites créer une application web qui gère des e-mails, comment ferais-tu pour: • afficher le nom de l'utilisateur connecté ? • afficher la liste de ses emails ? • afficher le contenu d'un email spécifique ?
En effet, toutes ces données sont dynamiques. Tu vas découvrir avec cette quête le moteur de template Razor, qui va te permettre de gérer tous ces cas !
Objectifs
- Comprendre le principe du templating
- Pouvoir afficher une liste d'éléments
- Comprendre le concept de modèle
- Aborder l'architecture MVC
- Connaître l'histoire et l'héritage d'ASP
Moteur de template
Avec ASP Classic - l'ancêtre d'ASP.NET - il était d'usage de méler le code qui gère la logique et celui qui gère la présentation graphique. Effectivement, à l'époque Microsoft a désiré conquérir le Web avec une nouvelle technologie qui était très utilisée avant que les frameworks MVC open-source (Spring, Symfony, Django ...) ne se popularisent .
Mélanger code exécutable et présentation graphique est aujourd'hui une hérésie et ne devrait plus apparaître dans le moindre code moderne.
Voici un exemple:
<html>
<body>
<%
For i = 0 To 5
response.write("The number is " & i & "<br />")
Next
%>
</body>
</html>
A l'époque, VBScript était l'unique langage de programmation avec lequel on pouvait utiliser ASP Classic. On voit qu'entre les délimiteurs <% et %>, du code VBScript est directement ajouté à la page et s'exécute comme dans un fichier VBScript pur.
Ainsi, la puissance du langage de programmation se couplait à celle de la vue et on arrivait à générer des pages puissantes assez rapidement, au prix de la flexibilité et de la qualité logicielle (car les responsabilités n'étaient pas bien séparées dans le code).
Article présentant les principales différences à connaître entre ASP Classic et ASP.NET
Tutoriel W3Schools sur ASP Classic (à des fins de culture uniquement)
Contenu dynamique & statique
Tu te doutes bien que nous n'allons pas travailler comme dans l'ancien temps et que tu vas apprendre des nouveautés, donc laissons ASP Classic et ses hérésies de côté et concentrons-nous sur ASP.NET et son moteur de template Razor.
Razor est le moteur de template utilisé par défaut par ASP.NET. Ainsi, il est présent d'office dans le package ASP.NET, donc pas besoin d'installer de dépendances.
Le principe de Razor est d'afficher du contenu dynamique en utilisant des propriétés HTML. Imaginons que tu veuilles créer une page web qui affiche le nom de l'utilisateur connecté : selon l'utilisateur, le contenu sera différent.
À partir du moment où tu utiliseras Razor, tu n'utiliseras quasiment plus de fichiers html pour une raison simple : il ne s'agit plus de simples fichiers statiques mais de fichiers dynamiques, appelés templates !
Les templates en ASP.NET ont pour extension .cshtml, et non .html.
Commençons par créer un template nommé Index.cshtml dans le dossier View/Home. Il contient le code nécessaire à l'affichage de "Hello World!" :
<!DOCTYPE HTML>
<html>
<head>
<title>Razor</title>
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
</head>
<body>
<h1>Hello World!</h1>
</body>
</html>
La correspondance entre templates et contrôleurs se fait grâce à des conventions de nommage (c'est paramétrable mais nous nous contenterons de ça durant cette quête). Ainsi, pour que le contrôleur HomeController - placé dans le dossier Controllers - sache quel template afficher lors de l'appel à une route, il faut que dans le dossier Views, un dossier Home soit crée avec un l'intérieur un fichier Index.cshtml. Le nom de la vue doit correspondre au nom de la méthode dans le contrôleur.
Donc, si on veut afficher le fichier CSHTML défini plus haut:
using HelloMVCWorld.Models;
using Microsoft.AspNetCore.Mvc;
namespace Controllers.HelloMVCWorld
{
public class HomeController : Controller
{
// GET: /<controller>/
public IActionResult Index()
{
return View();
}
}
}
Comme le contrôleur s'apelle HomeController, ASP.NET va rechercher dans le dossier Views un dossier s'appelant Home, et comme la méthode s'appelle Index, ASP.NET va rechercher dans le dossier Views/Home un fichier Index.cshtml. Bien entendu, ceci n'est pas le seul chemin et par défaut ASP.NET dispose d'autres chemins de recherche par défaut.
Documentation officielle de ASP.NET traitant des vues en Razor et de leur liaison à un contrôleur
Transmettre la valeur d'une variable
En l'état actuel, ta page, bien que dynamique, affiche un contenu statique : en effet, le texte sera toujours le même : "Hello World!".
Imagines que tu veuilles modifier le fichier pour afficher "Hello $name!", où $name serait remplacé par la valeur d'une variable envoyée depuis le contrôleur (information qui serait issue par exemple d'une base de données).
La première étape va consister à créer une route qui initialise une variable contenant le nom de la personne.
Dans le contrôleur précédemment écrit, il faut créer une variable puis l'envoyer à la vue:
using HelloMVCWorld.Models;
using Microsoft.AspNetCore.Mvc;
namespace Controllers.HelloMVCWorld
{
public class HomeController : Controller
{
// GET: /<controller>/
public IActionResult Index()
{
String name = "Bernard";
return View(name);
}
}
}
La variable name est passée en paramètre lors de l'appel de la vue. Ainsi, la vue va pouvoir récupérer les informations dynamiques fournies par le contrôleur.
Et dans le fichier Views/Home/Index.cshtml (la vue):
@model String
<!DOCTYPE HTML>
<html>
<head>
<title>Razor</title>
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
</head>
<body>
<h1>Hello @Model</h1>
</body>
</html>
Plusieurs nouveautés apparaissent dans notre fichier Views/Home/Index.cshtml:
- @model String: La première ligne du fichier permet à Razor de savoir de quel type sera le modèle qu'il recevra. Cela permet à Razor de savoir que l'objet qu'il reçoit est de type String. Il sait donc comment l'afficher et quelles opérations il est possible de faire sur ce type.
- Hello @Model: Le caractère @ permet d'inclure du code C# dans une vue. Ainsi, puisque le modèle est une chaîne de caractères, on peut directement afficher le modèle qui est le nom passé par le contrôleur à la vue.
Documentation officielle de Razor sur la syntaxe @ et autres
Les expressions
Razor possède des expressions qui permettent d'afficher tout un tas de choses utiles. Il est possible d'ajouter encore plus de dynamisme à notre page en créant des boucles et des conditions.
Tu pourras par exemple parcourir une liste d'objets afin d'afficher les valeurs de ses attributs, en utilisant la syntaxe d'une boucle C# précédée d'un caractère @.
D'abord, il faut modifier le contrôleur pour qu'il envoie une liste:
using HelloMVCWorld.Models;
using Microsoft.AspNetCore.Mvc;
namespace Controllers.HelloMVCWorld
{
public class HomeController : Controller
{
// GET: /<controller>/
public IActionResult Index()
{
List<String> names = { "Bernard", "Roger", "Jean-Paul" };
return View(name);
}
}
}
Et la vue:
@model IEnumerable<String>
<HTML>
<body>
@foreach (var name in Model)
{
<div class="username">
@name
</div>
}
</body>
Il n'est pas du ressort de la vue de contrôler les données qu'elle affiche. La seule responsabilté de la vue est de présenter des données, non de les acquérir et/ou de les traiter. Ainsi, dans l'exemple précédent on passe une liste de noms crée dans un contrôleur. En aucun cas la vue ne doit produire ses propres données dynamiques.
Court tutoriel présentant les fonctionnalités basiques de Razor
Challenge
Une liste de prix
Créé une page qui présente une liste de dépenses. Chaque dépense est affichée dans un tableau qui permet une lecture agréable.
- Crée une classe "Expenditure" (dépense) qui représente une dépense. La classe Expenditure contient un nom, une date et un prix en €.
- Crée un contrôleur qui envoie une liste de 3 dépenses minimum à une vue
- Crée une vue qui reçoit un IEnumerable en type de modèle et affiche chaque info sur chaque dépense dans un tableau HTML
- Le total des prix est affiché en fin de tableau