Vous êtes sur la page 1sur 35

Créer un blog avec

Symfony4 - Création des


Vues

FAYCEL EL AYEB
 dans la première partie, nous avons créer le projet et défini
nos routes. Dans cette partie, nous allons définir les
différentes vues pour chacune des routes que nous avons
créées dans la partie précédente.
Le moteur de template Twig

 Symfony utilise un moteur de template qui s'appelle Twig. L’intérêt d'utiliser


un moteur de template c'est d'abord la clarté du code, on écrira pas du
code PHP dans du HTML, mais aussi la rapidité de Twig, tout les templates
sont compilés en PHP et mis en cache, seulement quand vous changez le
code d’un template, Twig le recompile et le met encore en cache, ce qui
est très pratique en production.

 Pour utiliser Twig, il faut retenir ces trois syntaxes

 {{ ... }} Afficher quelque chose, une variable par exemple


 {% ... %} Faire quelque chose, définir une variable, une boucle, structure
conditionnelles
 {# ... #} Commenter du texte
Le moteur de template Twig

 En Symfony 4, les templates se trouvent dans le dossier templates qui se


trouvent à la racine. Les fichiers Twig ont une extension .twig

 Si vous ouvrez le dossier templates, vous verrez un dossier blog et un fichier


base.html.twig. A l’intérieur du dossier blog se trouve un fichier
index.html.twig, si vous vous rappelez bien, ce fichier et le dossier blog ont
été généré lorsque nous avons créer le contrôleur BlogController. Pour le
moment, on laisse tomber le fichier base.html.twig.
 Ouvrez donc le fichier index.html.twig qui se trouve dans templates/blog,
nous allons remplacer son contenu par ce qui suit:
<h1>Page d'accueil depuis une vue Twig</h1>
 Nous avons notre vue, il faut maintenant faire le lien avec le contrôleur
pour lui dire de retourner cette page à chaque fois l'utilisateur visite la
page d'accueil de notre site.
BlogController.php:
 Nos contrôleurs retournent tous un objet Response, on va donc modifier
cela en commençant par le contrôleur index qui retourne la page
d'accueil, nous l’avons déjà créer une vue, nous allons donc l'utiliser (on
va juste écrire la méthode index, le reste du code ne change pas).

<?php
//...
class BlogController extends AbstractController {
public function index()
{
return $this->render('blog/index.html.twig');
}
//...
}
La page d'accueil rendu avec Twig:
 Quand on actualise la page d'accueil de notre site, nous devons
maintenant avoir ceci:
BlogController.php, la méthode show():
 Ce que nous allons faire maintenant c'est de créer les autres vues de
notre site. On va créer la vue pour l'affichage d'un article.
 Première des choses à faire, créer le contrôleur. Mais nous avons déjà
notre contrôleur et c'est la méthode show() dans
src/Controller/BlogController.php, ce que nous allons donc faire c'est de
dire à notre contrôleur de retourner une vue (une page, un fichier) twig
en lieu et place de l'objet Response que nous avons actuellement. Notre
méthode va donc ressembler à ça :
public function show($url)
{
return $this->render('blog/show.html.twig', [
'slug' => $url
]);
}
BlogController.php, la méthode show():
 C'est juste ce qu'il y a devant le return que nous avons changer, nous lui
disons de retourner le fichier blog/show.html.twig, et en plus nous
envoyons un deuxième paramètre à la fonction render(), un tableau qui
contient les variables que nous envoyons à notre page et que nous
pourrons afficher. Si on récupère par exemple un utilisateur avec notre
contrôleur, nous devons l'envoyer à notre vue pour pouvoir afficher son
nom, email, ...

 Ce tableau n'a donc rien de magique, c'est du PHP, la clé (slug) c'est le
nom de la variable que nous utiliserons sur la vue, et la valeur ($url) c'est la
variable que l'on enregistre pour l'afficher sur la vue. Ce tableau peut
contenir n'importe quel type de données, objet, nombres, booléen, ...
C'est un tableau comme on a l'habitude de le voir en PHP.
Création de Vue show.html.twig:
 Maintenant que nous avons notre contrôleur, nous allons donc créer notre
vue, le fichier templates/blog/show.html.twig, voici son contenu
 <h1>Affichage de l'article {{ slug }}</h1>
 Voilà, ce qu’on a sur le lien http://127.0.0.1:8000/show/un-super-article:
Création de Vue show.html.twig:
 Sur la vue, je n'ai pas utiliser $url mais plutôt {{ slug }}, la clé que nous
avions défini dans le tableau au niveau du contrôleur.

 Et là vous pouvez voir l’intérêt du Twig, nous avons juste du HTML, pas
besoin de balise PHP pour les variables. En PHP on aurait écrit:

<h1>Affichage de l'article <?php echo $slug ?></h1>

 Ce qui peut très vite devenir lourd.


Création de reste des Vues :

 ci-dessous les modifications apportées dans le fichier BlogController.php:

public function add()


{return $this->render('blog/add.html.twig'); }
public function edit($id)
{return $this->render('blog/edit.html.twig', [
'slug' => $id
]);}
public function remove($id)
{return new Response('<h1>Delete article: ' .$id. '</h1>');}
Création de reste des Vues :

 add.html.twig

<h1>Ajout d'un article</h1>

 edit.html.twig

<h1>Modification de l'article {{ slug }}</h1>


Modification des Vues :
 Voila à quoi va ressembler notre site quand on aura fini:
Modification des Vues :
 Voila à quoi va ressembler notre site quand on aura fini:
Modification des Vues :

 Si vous regardez bien, nos pages ont quelque chose en commun, c'est la
barre de navigation, en tant normal c'est soit on la recrée sur toutes le
pages en HTML ou on utilise PHP avec la fonction require(), mais nous,
nous n'allons faire rien de ceux là.

 L’intérêt avec les moteurs de templates comme Twig, c'est qu'un


template peut hériter d'un autre, comme les classes, un template peut
aussi inclure un ou plusieurs qutres templates. L’héritage et l'inclusion sont
totalement différents. Voyons cela tout de suite.
L’héritage de templates:

 Quand on travaille sur un projet, généralement nous avons des blocs de


nos pages qui se ressemblent, c'est le cas de la barre de navigation ou du
pied de page. Avec Twig, nous n'allons pas redéfinir ces blocs sur toutes le
pages, nous allons définir un template mère qui va contenir l'architecture
de base de nos pages et dont les pages de notre site vont hérités. Le
template mère va définir des blocs (block) dans les quels on pourra
rajouter du contenu spécifique pour chaque page. Cela fonctionne
comme l’héritage en PHP, on peut redéfinir les variables et méthodes de
la classe mère.

 Dans notre cas, nous allons utiliser le fichier templates/base.html.twig


comme template mère, il va donc contenir la barre de navigation de
notre site et définir un bloc pour le contenu de nos pages.
Templates/base.html.twig:
{# templates/base.html.twig #}
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}Symfony Blog{% endblock %}</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">

{% block stylesheets %}
<link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.
min.css">
{% endblock %}
</head>
Templates/base.html.twig (suite):
<body>
<nav>
<div class="nav-wrapper">
<div class="container">
<a href="#" class="brand-logo">Symfony Blog</a>
<ul id="nav-mobile" class="right hide-on-med-and-down">
<li><a href="#">Home</a></li>
<li><a href="#">Login</a></li>
</ul>
</div></div></nav>
{% block content %} {% endblock %}
{% block scripts %}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
{% endblock %}
</body>
</html>
Templates/base.html.twig (suite):
 Ce fichier défini le template de base de toutes les pages de notre site, toutes nos
pages devront donc hériter de ce fichier. Nous définissons ici 4 blocs (block) à
savoir title, stylesheets, content et scripts.
 Les blocs vont nous servir à quoi au juste? A pouvoir les remplacer dans les
templates enfants, dites vous que ce sont les méthodes publics d'une classe.
 Tout le contenu qui ne se trouve pas dans un bloc est une méthode privé, on ne
peut donc pas le modifier dans les templates enfants, ce qui veut donc dire
qu'on ne peut pas modifier la barre de navigation dans les templates enfants.
 Maintenant pour pouvoir voir les modifications, nous allons faire hériter notre
page d'accueil (index.html.twig) de ce template

{% extends "base.html.twig" %}

 On utilise extends comme en PHP aussi. Nous mettons juste le nom du fichier, le
chemin de base pour tout les templates c'est le dossier templates, le fichier
base.html.twig se trouve directement dans ce dossier, pas dans un sous dossier,
donc on ne spécifie aucun chemin ici. Si on actualise la page d'accueil on
obtient:
Templates/base.html.twig (suite):
Templates/base.html.twig (suite):
 Nous avons bien la barre de navigation, avec le style par défaut de
materialize. Une autre chose, tout en bas nous avons la debug bar de
Symfony, cette barre est créer par Symfony et reste afficher quand nous
sommes en mode développement, nous pouvons voir la bas la route sur la
quelle on est, les requêtes qui sont faites a la BDD, le temps de
chargement de la page, ...

 La barre de navigation vient avec le style par défaut de materialize, pour


changer cela on doit charger notre fichier de style.

 Pour changer cela, on utilisera le fichier de style blog.css ci-joint.


Templates/base.html.twig (suite):
 Le fichier de style doit être placer dans le dossier public/assets/css/, son
chemin complet c'est donc public/assets/css/blog.css et on le charge
dans le ficher base.html.twig:

{% block stylesheets %}
<link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.
min.css">
<link rel="stylesheet" type="text/css" href="{{ asset('assets/css/blog.css') }}">
{% endblock %}

 Si nous actualisons la page, notre barre de navigation est meilleure


maintenant.
index.html.twig :
 Maintenant on ajoutera du texte à notre page d'accueil:
{# templates/blog/index.html.twig #}
{% extends "base.html.twig" %}

{% block content %}
<div class="container">
<div class="row">
<div class="col s12 m12 l12">
<h1>Hello, c'est la page d'accueil</h1>
</div>
</div>
</div>
{% endblock %}
 On écrit dans le bloc content, si nous essayons d’écrire en dehors de ce bloc, on
a une erreur qui dit qu'un template qui hérite d'un autre ne peut pas définir du
contenu en dehors des blocs défini par le template parent.
index.html.twig :
 Si vous définissez un autre bloc, en dehors du bloc content, le contenu de ce
dernier ne sera pas afficher sur cette page.
 Mais rien ne vous interdit de le définir à l’intérieur du bloc content:
{% block content %}
<div class="container">
<div class="row">
<div class="col s12 m12 l12">
<h1>Hello, c'est la page d'accueil</h1>
</div>
<div class="col s12 m12 l12">
{% block another_block %}
<h2>Ce contenu sera afficher</h2>
{% endblock %}
</div></div></div>
{% endblock %}
index.html.twig :

 Modifions maintenant le titre de notre page, au lieu de Symfony Blog, on


veut avoir Accueil | Symfony Blog, on fait comment?

 La solution, on utilise une fonction de Twig qui permet de récupérer la


valeur qui se trouve dans le bloc de la classe mère.

 Dans templates/blog/index.html.twig ajouter :

{% block title %}Accueil | {{ parent() }}{% endblock %}

 On utilise la fonction parent(), elle nous permet de récupérer la valeur du


bloc dans la classe mère.
Inclure un template

 L'inclusion de template va nous permettre d’éviter de dupliquer du


code sur deux pages différentes. C'est différent de l’héritage dans le
sens ou avec l'inclusion on injecte du code dans un bloc spécifique
par exemple, et nous pouvons aussi envoyer des variables avec
l'inclusion de template.

 Dans notre cas, nous allons écrire le code du formulaire pour l’édition
et la modification d'un article dans
templates/includes/article_form.html.twig
article_form.html.twig
{# templates/includes/article_form.html.twig #}

<form class="row">
<div class="input-field col s12 m12 l12">
<input type="file" name="">
</div>
<div class="input-field col s12 m6 l6">
<input type="text" name="" placeholder="Titre de l'article">
</div>
<div class="input-field col s12 m6 l6">
<input type="text" name="" placeholder="Catégories (php, html, css)">
</div>
<div class="input-field col s12 m12 l12">
<textarea class="materialize-textarea" placeholder="Contenu de
l'article"></textarea>
</div>
article_form.html.twig (Suite)
<div class="input-field col s12 m12 l12">
<p>
<label>
<input type="checkbox" class="filled-in" />
<span>Publier</span>
</label>
</p>
</div>
<div class="input-field col s12 m12 l12">
<input type="submit" name="" value="Enregistrer" class="btn btn-
primary btn-large">
</div>
</form>
edit.html.twig:
 Nous avons juste le formulaire et nous allons l'inclure dans nos vue edit.html.twig
et add.html.twig comme suit.
{# templates/blog/edit.html.twig #}
{% extends "base.html.twig" %}
{% block title %}Modifier{% endblock %}
{% block content %}
<div class="container">
<div class="row">
<div class="col s12 m12 l12">
<h4>Modifier l'article {{ slug }}</h4>
</div>
</div>
{% include "includes/article_form.html.twig" %}
</div>
{% endblock %}
add.html.twig:
{# templates/blog/add.html.twig #}
{% extends "base.html.twig" %}

{% block title %}{{ parent() }} | Ajouter un article{% endblock %}

{% block content %}
<div class="container">
<div class="row">
<div class="col s12 m12 l12">
<h4>Ajout d'un article</h4>
</div>
</div>
{% include "includes/article_form.html.twig" %}
</div>
{% endblock %}
index.html.twig:
{# templates/blog/index.html.twig #}
{% extends "base.html.twig" %}
{% block title %}Accueil | {{ parent() }}{% endblock %}
{% block content %}
<div class="container"><div class="row">
<div class="col s12 m7 l9">
<div class="article-card image-card" style="background:
url('https://images.pexels.com/photos/276452/pexels-photo-
276452.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260');">
<h2><a href="">Another Title</a></h2>
<span class="date">14/01/2019</span>
</div></div>
<div class="col s12 m5 l3"><div class="row"><div class="col s12 m12 l12">
<div class="article-card image-card" style="background:
url('https://images.pexels.com/photos/276452/pexels-photo-
276452.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260');">
<h2><a href="">Another Title</a></h2>
<span class="date">14/01/2019</span>
</div></div></div></div></div></div>
index.html.twig (Suite):
<div class="container">
<div class="row">
<div class="col s12 m4 l3">
<div class="article-card">
<img src="https://images.pexels.com/photos/276452/pexels-photo-
276452.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260" class="responsive-img">
<h2><a href="">Another Title</a></h2>
<span class="date">14/01/2019</span>
</div></div>
<div class="col s12 m4 l3">
<div class="article-card">
<img src="https://images.pexels.com/photos/276452/pexels-photo-
276452.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260" class="responsive-img">
<h2><a href="">Another Title</a></h2>
<span class="date">14/01/2019</span>
</div></div></div></div>
{% endblock %}
show.html.twig:
{# templates/blog/show.html.twig #}
{% extends "base.html.twig" %}

{% block title %}{{ slug }}{% endblock %}

{% block content %}
<article class="container">
<div class="row">
<div class="col s12 m12 l8 offset-l2">
<h2>{{ slug }}</h2>
<span>14/01/2019</span>
<p>
<img src="https://images.pexels.com/photos/276452/pexels-photo-
276452.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260" class="responsive-img">
</p>
<span class="categories">php, html, css</span>
</div>
</div>
show.html.twig (Suite):
<div class="row">
<div class="col s12 m12 l8 offset-l2">
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,

</p>
</div>
</article>
{% endblock %}
 Nous avons maintenant nos vues. La prochaine fois nous
verrons comment ajouter, lire, modifier et supprimer un
article.