<< TP 2
TP 4 >>

3. Design du site web





3.1. Twig

Nous allons mettre en place le design du site web, un design somme toute assez simple.

Pour cela il faut se rendre dans le répertoire templates et modifier le fichier de rendu par défaut qui se nomme base.html.twig

On rappelle que Twig est qualifié de moteur de templates pour le langage de programmation PHP, ce qui ne signifie pas grand chose.

Pour être plus explicite, Twig autorise l'utilisation d'un langage qui permet de manipuler les variables PHP dans une page HTML/PHP avec un formalisme simplifié. Par exemple plutôt que d'écrire le code PHP suivant dans une page HTML :

  1. <?php echo $variable; ?>

On écrira le code Twig suivant dans un fichier d'extension .twig :

  1. {{ variable }}

Le fameux moteur de template est un script PHP qui va transformer le code Twig en code PHP.

Twig permet également d'oragniser la structure d'une page en différents blocks qui peuvent être modifiés en fonction de des besoins. Par exemple on peut créer un fichier list.persons.html.twig qui va étendre base.html.twig et pour lequel on modifie la section main pour afficher une liste de personnes.

3.2. Autre fonctionnalités de Twig pour l'affichage des variables

3.2.1. Les filtres Twig

Les filtres permettent de modifier 7 l'affichage des variables ou la transformation des variables qui sont introduits par la barre verticale '|' ( ou pipe en anglais).

3.2.1.a  Filtres sur les chaînes

Par exemple, upper permet de passer une chaîne en majuscule ou capitalize qui met la première lettre en majuscule.

  1. {{ 'mon titre' | upper }}

Un autre filtre intéressant est raw qui permet de prendre une variable qui contient du code HTML et l'afficher tel quel car, par défaut, une variable avec du code HTML est modifiée et on verra le code correspondant s'afficher. Essayez avec les deux syntaxes suivantes :

  1. // introduisez une variable 'code' au niveau du contrôleur qui contient du code HTML
  2. // puis affichez la avec l'une des deux syntaxes suivantes :
  3. {{ code }}
  4.  
  5. {{ code | raw }}

3.2.1.b  Filtres sur les tableaux

Le filtre join permet de transformer les éléments d'un tableau en chaîne :

  1. {{ [ 2, 3, 5, 7 ] | join( ',' ) }}

Le filtre map permet d'appliquer une fonction à un tableau :

  1. {{ [ 2, 3, 5, 7 ] | map( x => x * x ) | join( ',' ) }}

On obtiendra donc la chaîne "4, 9, 25, 49".

Le filtre filter sélectionne des éléments en fonction d'un critère de choix :

  1. {% for x in [1,2,3,4,5,6] | filter( x => (x % 2) == 0 ) %}
  2.     {{ x }}
  3. {% endfor %}

On obtient donc uniquement les nombres pairs.

On voit qu'on peut utiliser for endfor pour parcourir un tableau ou une collection. Il existe également le if, else, endif.

Ces mots clés sont introduits dans des balises {% %}.

3.2.1.c  Filtres sur les dates

A partir d'un timestamp, on peut obtenir la date et l'afficher au format jour / mois /année :

  1. {{ 23580000 | date('d/m/Y') }}

On peut également choisir d'afficher la date au format jour / mois en lettres / année mais dans ce cas on obtient un mois en anglais.

  1. {{ 23580000 | date('d F Y') }}

Il faut alors utiliser le filtre format_date mais il est alors nécessaire d'installer deux packages : twig/intl-extra et twig/extra-bundle. Pour cela on utilise composer :

symfony composer require twig/intl-extra
symfony composer require twig/extra-bundle

Il existe également format_date qui permet de formater une date avec la locale adaptée :

  1. {{ 23580000 | format_date(  pattern="dd MMMM yyyy", locale='fr' )  }}

Néanmoins, il faut éventuellement ajouter le package Linux correspondant (par exemple php-8.2-intl) et modifier le fichier php.ini adéquat (par exemple dans /etc/php/8.2/apache2) en décommentant l'extension :

...
;extension=gettext
;extension=gmp
extension=intl
;extension=imap
;extension=mbstring
...

3.2.1.d  Réutilisation des templates

Il est possible de créer un template Twig et de l'inclure dans un autre template, en passant des paramètres :

  1. {{ include( "template_a_inclure.twig", { var : nom_var }  ) }}

3.2.1.e  Extension de page

Le code de base d'une page est donné par le fichier templates/base.html.twig. Celui ci peut être réutilisé (hérité) et modifié pour certaines parties.

  1. <!DOCTYPE html>
  2. <html>
  3.     <head>
  4.         <meta charset="UTF-8">
  5.         <title>{% block title %}Welcome!{% endblock %}</title>
  6.         <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 128 128%22><text y=%221.2em%22 font-size=%2296%22>⚫️</text></svg>">
  7.        
  8.         {% block stylesheets %}
  9.             <link rel="stylesheet"
  10.              href="{{ asset('css/style.css') }}">
  11.         {% endblock %}
  12.  
  13.         {% block javascripts %}
  14.             <script src="{{ asset('js/javascript.js') }}"></script>
  15.         {% endblock %}
  16.     </head>
  17.     <body>
  18.         {% block body %}{% endblock %}
  19.     </body>
  20. </html>
  21.  

Cette page contient des blocks qui peuvent être modifiés, notamment le block body pour créer de nouvelles pages. On aura donc juste à redéfinir le block body pour toute nouvelle page ce qui permet à chaque fois d'inclure la même partie head avec les références aux fichiers CSS et Javascript.

  1. {{% extends( './base.html.twig") %}}
  2.  
  3. {% block body %}
  4.  
  5. mon code HTML spécifique à la page
  6.  
  7. {% endblock %}
  8.  
  9.  

3.2.1.f  La variable app

Cette variable permet d'avoir accès à différentes informations comme l'utilisateur connecté, les paramètres passés, environnement (développement, production), les variables de session.

On peut notamment afficher la requête en tapant :

{{ dump( app.request ) }}
{{ dump( app.request.method ) }}
{{ dump( app.request.environment ) }}
{{ dump( app.request.session ) }}

3.3. Modification de base.html.twig

La page principale de notre site sera composée d'un header, d'un footer d'une barre de navigation ainsi que d'une partie centrale (balise main) qui sera variable.

La barre de navigation située en dessous du header contient un menu avec les options :

On obtient donc quelque chose similaire à ceci (cliquez sur l'image pour l'agrandir) :

Département des Véhicules à Moteur

Dont le code est :

  1.  
  2. <!DOCTYPE html>
  3. <html>
  4.     <head>
  5.         <meta charset="UTF-8">
  6.         <title>{% block title %}DVM{% endblock %}</title>
  7.        
  8.         <link rel="stylesheet" href="{{ asset('css/style.css') }}">
  9.        
  10.         {% block javascripts %}
  11.             <script src="{{ asset('js/javascript.js') }}"></script>
  12.         {% endblock %}
  13.     </head>
  14.     <body>
  15.         <header>
  16.             <h1>Département des Véhicules à Moteur</h1>
  17.         </header>
  18.  
  19.         <nav>
  20.             <ul>
  21.                 <li><a href="/">Accueil</a></li>
  22.                 <li><a href="/conducteur/list">Conducteurs</a></li>
  23.                 <li><a href="/vehicule/list">Véhicules</a></li>
  24.                 <li><a href="/equipement/list">Equipements</a></li>
  25.                 <li><a href="/connexion">Connexion</a></li>
  26.                
  27.             </ul>
  28.         </nav>
  29.         <main>
  30.         {% block main %}
  31.             <section>
  32.                 <h2>Bienvenue sur le site DVM !</h2>
  33.  
  34.                 <p>Nous gérons tous les véhicules ainsi que leurs conducteurs.</p>
  35.  
  36.                 <p>Un conducteur peut détenir plusieurs véhicules.</p>
  37.  
  38.                 <p>Un véhicule possède 0 à plusieurs équipements et un équipement peut
  39.                 appartenir à 0 ou plusieurs véhicules.</p>
  40.  
  41.             </section>
  42.         {% endblock %}
  43.         </main>
  44.  
  45.         <footer>
  46.             <p>Copyright 2024 by Jean-Michel Richer</p>
  47.         </footer>
  48.  
  49.     </body>
  50. </html>
  51.  

La mise en forme est donnée par le fichier CSS public/css/style.css :

  1. * {
  2.     margin: 0;
  3. }
  4.  
  5. html {
  6.     background-color: white;
  7. }
  8.  
  9. body {
  10.     font-family: Verdana, sans-serif;
  11.     font-size: 14px;
  12.     background-color: white;
  13.     display: flex;
  14.     flex-direction: column;
  15.     align-items: start;
  16.     justify-content: center;
  17. }
  18.  
  19. /* HEADER avec image à droite */
  20.  
  21. header {
  22.     height: 200px;
  23.     background: black;
  24.     width: 100%;
  25.     display: flex;
  26.     align-items: center;
  27.     justify-content: center;
  28. }
  29.  
  30. header h1 {
  31.     color: white;
  32.     font-size: 40px;
  33. }
  34.  
  35. header img {
  36.     margin-right: 40px;
  37. }
  38.  
  39. /* FOOTER */
  40.  
  41. footer {
  42.     height: 40px;
  43.     background-color: darkgray;
  44.     width: 100%;
  45.     display: flex;
  46.     align-items: center;
  47.     justify-content: center;
  48. }
  49.  
  50. footer p {
  51.     color: black;
  52.     font-size: 18px;
  53.     text-align: center;
  54. }
  55.  
  56. /* NAVIGATION BAR */
  57.  
  58. nav {
  59.     display: flex;
  60.     align-items: center;
  61.     justify-content: center;
  62.     background-color: darkgray;
  63.     width: 100%;
  64.     height: 40px;
  65.     border-top: 1px solid lightgray;
  66.     border-bottom: 1px solid black;
  67. }
  68.  
  69. nav ul {
  70.     list-style-type: none;
  71.     display: flex;
  72.     flex-direction: row;
  73.     margin: 0;
  74.     padding: 0;
  75. }
  76.  
  77. nav ul li {
  78.     width: 150px;
  79.     margin: 5px 2px;
  80.     padding: 3px auto;
  81.     font-size: 20px;
  82.     text-align: center;
  83. }
  84.  
  85. nav ul li a {
  86.     text-decoration: none;
  87.     font-size: 18px;
  88.     font-weight: bold;
  89.     color: black;
  90. }
  91.  
  92. /* MAIN */
  93.  
  94. main {
  95.     width: 100%;
  96.     min-height: calc(100vh - 310px);
  97.     display: flex;
  98.     flex-direction: column;
  99.     align-items: center;
  100.     justify-content: start;
  101.     background: white;
  102. }
  103.  
  104. main section {
  105.     width: 80%;
  106.     margin-top: 40px;
  107. }
  108.  
  109. main section h2 {
  110.     font-size: 34px;
  111.     margin: 10px auto;
  112.     padding-bottom: 20px;
  113.     text-align: center;
  114.     color:  #D52315 ; /*#D7240F; */
  115. }
  116.  
  117. main section p {
  118.     font-size: 18px;
  119.     margin: 20px auto;
  120.     text-align: justify;
  121.     width: 600px;
  122. }
  123.  
  124. main section p.center {
  125.     text-align: center;
  126.     padding: 10px;
  127. }
  128.  
  129.  

On notera que tout ce qui concerne les CSS, le Javascript et les images sera placé dans le répertoire public/ du projet Symfony.

public/
├── css
│   └── style.css
├── images
│   ├── audi_r8.png
│   ├── car_icon.png
│   ├── delete.png
│   ├── error-icon.png
│   └── modify.png
├── index.php
└── js
    └── javascript.js

Vous pouvez également récupérer les images images.tgz et les placer dans le répertoire public/images/ que vous créerez. Pour cela vous pouvez décompresser l'archive dans le répertoire public.

N'oubliez pas de créer également le répertoire public/js/ ainsi que le fichier public/js/javascript.js qui contiendra des traitements Javascript qui vont permettre de dynamiser le site.






<< TP 2
TP 4 >>