aboutsummaryrefslogtreecommitdiff
path: root/files/fr/learn
diff options
context:
space:
mode:
authorPeter Bengtsson <mail@peterbe.com>2020-12-08 14:40:17 -0500
committerPeter Bengtsson <mail@peterbe.com>2020-12-08 14:40:17 -0500
commit33058f2b292b3a581333bdfb21b8f671898c5060 (patch)
tree51c3e392513ec574331b2d3f85c394445ea803c6 /files/fr/learn
parent8b66d724f7caf0157093fb09cfec8fbd0c6ad50a (diff)
downloadtranslated-content-33058f2b292b3a581333bdfb21b8f671898c5060.tar.gz
translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.tar.bz2
translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.zip
initial commit
Diffstat (limited to 'files/fr/learn')
-rw-r--r--files/fr/learn/css/first_steps/getting_started/index.html266
-rw-r--r--files/fr/learn/css/first_steps/how_css_is_structured/index.html517
-rw-r--r--files/fr/learn/css/first_steps/how_css_works/index.html163
-rw-r--r--files/fr/learn/css/first_steps/index.html63
-rw-r--r--files/fr/learn/css/first_steps/qu_est_ce_que_css/index.html132
-rw-r--r--files/fr/learn/css/first_steps/using_your_new_knowledge/index.html106
-rw-r--r--files/fr/learn/css/styling_text/index.html50
-rw-r--r--files/fr/learn/css/styling_text/initiation-mise-en-forme-du-texte/index.html756
-rw-r--r--files/fr/learn/css/styling_text/mise_en_forme_des_liens/index.html448
-rw-r--r--files/fr/learn/css/styling_text/styling_lists/index.html396
-rw-r--r--files/fr/learn/css/styling_text/typesetting_a_homepage/index.html126
-rw-r--r--files/fr/learn/css/styling_text/web_fonts/index.html203
-rw-r--r--files/fr/learn/javascript/first_steps/a_first_splash/index.html708
-rw-r--r--files/fr/learn/javascript/first_steps/index.html70
-rw-r--r--files/fr/learn/javascript/first_steps/math/index.html449
-rw-r--r--files/fr/learn/javascript/first_steps/methode_chaine_utile/index.html479
-rw-r--r--files/fr/learn/javascript/first_steps/silly_story_generator/index.html143
-rw-r--r--files/fr/learn/javascript/first_steps/strings/index.html278
-rw-r--r--files/fr/learn/javascript/first_steps/tableaux/index.html528
-rw-r--r--files/fr/learn/javascript/first_steps/testes_vos_competence_colon__tableaux/index.html87
-rw-r--r--files/fr/learn/javascript/first_steps/variables/index.html434
-rw-r--r--files/fr/learn/javascript/first_steps/what_is_javascript/index.html397
-rw-r--r--files/fr/learn/javascript/first_steps/what_went_wrong/index.html254
-rw-r--r--files/fr/learn/javascript/objects/ajouter_des_fonctionnalités_à_notre_démo_de_balles_rebondissantes/index.html208
-rw-r--r--files/fr/learn/javascript/objects/basics/index.html258
-rw-r--r--files/fr/learn/javascript/objects/heritage/index.html260
-rw-r--r--files/fr/learn/javascript/objects/index.html70
-rw-r--r--files/fr/learn/javascript/objects/js_orienté-objet/index.html278
-rw-r--r--files/fr/learn/javascript/objects/json/index.html338
-rw-r--r--files/fr/learn/javascript/objects/la_construction_d_objet_en_pratique/index.html316
-rw-r--r--files/fr/learn/javascript/objects/prototypes_objet/index.html244
-rw-r--r--files/fr/learn/performance/css/index.html100
-rw-r--r--files/fr/learn/performance/index.html81
-rw-r--r--files/fr/learn/performance/pourquoi_performance_web/index.html101
-rw-r--r--files/fr/learn/server-side/django/admin_site/index.html371
-rw-r--r--files/fr/learn/server-side/django/development_environment/index.html423
-rw-r--r--files/fr/learn/server-side/django/forms/index.html651
-rw-r--r--files/fr/learn/server-side/django/home_page/index.html429
-rw-r--r--files/fr/learn/server-side/django/index.html65
-rw-r--r--files/fr/learn/server-side/django/introduction/index.html277
-rw-r--r--files/fr/learn/server-side/django/models/index.html468
-rw-r--r--files/fr/learn/server-side/django/skeleton_website/index.html403
-rw-r--r--files/fr/learn/server-side/django/testing/index.html956
-rw-r--r--files/fr/learn/server-side/django/tutorial_local_library_website/index.html101
-rw-r--r--files/fr/learn/server-side/django/vues_generiques/index.html634
-rw-r--r--files/fr/learn/server-side/express_nodejs/index.html71
-rw-r--r--files/fr/learn/server-side/express_nodejs/introduction/index.html537
-rw-r--r--files/fr/learn/server-side/index.html58
-rw-r--r--files/fr/learn/server-side/premiers_pas/client-serveur/index.html316
-rw-r--r--files/fr/learn/server-side/premiers_pas/index.html45
-rw-r--r--files/fr/learn/server-side/premiers_pas/introduction/index.html234
-rw-r--r--files/fr/learn/server-side/premiers_pas/web_frameworks/index.html306
-rw-r--r--files/fr/learn/server-side/premiers_pas/website_security/index.html162
-rw-r--r--files/fr/learn/tools_and_testing/client-side_javascript_frameworks/index.html175
-rw-r--r--files/fr/learn/tools_and_testing/client-side_javascript_frameworks/introduction/index.html405
-rw-r--r--files/fr/learn/tools_and_testing/client-side_javascript_frameworks/main_features/index.html354
-rw-r--r--files/fr/learn/tools_and_testing/client-side_javascript_frameworks/react_getting_started/index.html468
-rw-r--r--files/fr/learn/tools_and_testing/client-side_javascript_frameworks/react_todo_list_beginning/index.html603
-rw-r--r--files/fr/learn/tools_and_testing/client-side_javascript_frameworks/vue_getting_started/index.html295
-rw-r--r--files/fr/learn/tools_and_testing/cross_browser_testing/accessibilité/index.html684
-rw-r--r--files/fr/learn/tools_and_testing/cross_browser_testing/html_et_css/index.html509
-rw-r--r--files/fr/learn/tools_and_testing/cross_browser_testing/index.html48
-rw-r--r--files/fr/learn/tools_and_testing/cross_browser_testing/introduction/index.html207
-rw-r--r--files/fr/learn/tools_and_testing/cross_browser_testing/javascript/index.html519
-rw-r--r--files/fr/learn/tools_and_testing/cross_browser_testing/testing_strategies/index.html362
-rw-r--r--files/fr/learn/tools_and_testing/understanding_client-side_tools/index.html39
-rw-r--r--files/fr/learn/tools_and_testing/understanding_client-side_tools/ligne_de_commande/index.html487
67 files changed, 20969 insertions, 0 deletions
diff --git a/files/fr/learn/css/first_steps/getting_started/index.html b/files/fr/learn/css/first_steps/getting_started/index.html
new file mode 100644
index 0000000000..999acf147b
--- /dev/null
+++ b/files/fr/learn/css/first_steps/getting_started/index.html
@@ -0,0 +1,266 @@
+---
+title: Démarrer avec CSS
+slug: Learn/CSS/First_steps/Getting_started
+tags:
+ - CSS
+ - Classes
+ - Débutant
+ - Element
+ - Etat
+ - Syntaxe
+ - Sélecteurs
+translation_of: Learn/CSS/First_steps/Getting_started
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/CSS/First_steps/What_is_CSS", "Learn/CSS/First_steps/How_CSS_is_structured", "Learn/CSS/First_steps")}}</div>
+
+<p class="summary">Dans cet article nous vous montrons comment appliquer un style CSS à un document HTML simple. Vous apprendrez des choses pratiques concernant CSS.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Prérequis :</th>
+ <td>Connaissances élémentaires en informatique, <a href="/fr/docs/Apprendre/Commencer_avec_le_web/Installation_outils_de_base">suite logicielle de base installée</a>, compréhension élémentaire du <a href="/fr/docs/Apprendre/Commencer_avec_le_web/Gérer_les_fichiers"> travail avec des fichiers</a>, des bases en HTML (cf. <a href="/fr/docs/Apprendre/HTML/Introduction_à_HTML">Introduction à HTML</a>.)</td>
+ </tr>
+ <tr>
+ <th scope="row">Objectif :</th>
+ <td>Comprendre comment associer une feuille de style CSS à un document HTML, savoir appliquer quelques règles simples de mise en forme d'un texte.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Dabord_un_peu_de_HTML">D'abord un peu de HTML</h2>
+
+<p>Notre point de départ est un document HTML. Pour suivre la leçon en travaillant sur votre ordinateur, vous pouvez copier le code ci-dessous. Collez le dans un fichier en utilisant un éditeur de code, puis sauvegardez le sous le nom <code>index.html</code>.</p>
+
+<pre class="brush: html notranslate">&lt;!doctype html&gt;
+&lt;html lang="fr"&gt;
+&lt;head&gt;
+ &lt;meta charset="utf-8"&gt;
+ &lt;title&gt;Démarrer avec CSS&lt;/title&gt;
+&lt;/head&gt;
+
+&lt;body&gt;
+
+ &lt;h1&gt;Je suis un titre de niveau un&lt;/h1&gt;
+
+ &lt;p&gt;Ceci est un paragraphe. Dans ce texte il y a un &lt;span&gt;élément span&lt;/span&gt;
+ et aussi un &lt;a href="http://example.com"&gt;lien&lt;/a&gt;.&lt;/p&gt;
+
+ &lt;p&gt;Ceci est un second paragraphe. On y trouve un élément &lt;em&gt;mis en valeur&lt;/em&gt;.&lt;/p&gt;
+
+ &lt;ul&gt;
+ &lt;li&gt;Item un&lt;/li&gt;
+ &lt;li&gt;Item deux&lt;/li&gt;
+ &lt;li&gt;Item &lt;em&gt;trois&lt;/em&gt;&lt;/li&gt;
+ &lt;/ul&gt;
+
+&lt;/body&gt;
+
+&lt;/html&gt;
+</pre>
+
+<div class="blockIndicator note">
+<p><strong>Note </strong>: Si vous lisez cet article sur un appareil ou dans un environnement où il n'est pas aisé de créer des fichiers, pas de soucis — des éditeurs de code live sont proposés ci-dessous ; vous pourrez ainsi tester les exemples de code directement dans cette page.</p>
+</div>
+
+<h2 id="Ajouter_CSS_à_notre_document">Ajouter CSS à notre document</h2>
+
+<p>Pour commencer, on doit signaler au document HTML que nous souhaitons utiliser des règles CSS. Vous rencontrerez trois possibilités pour appliquer CSS à un document HTML. Nous nous contenterons de présenter la méthode la plus utilisée  — créer un lien vers la feuille de style CSS depuis l'en-tête du document HTML.</p>
+
+<p>Avec votre éditeur de code, dans le dossier où se trouve le document HTML, créez un fichier et sauvegardez le sous le nom <code>styles.css</code>. L'extension <code>.css</code> indique que c'est un fichier CSS.</p>
+
+<p>Pour lier <code>styles.css</code> à <code>index.html</code> ajoutez la ligne suivante dans la section {{htmlelement("head")}} du document HTML :</p>
+
+<pre class="brush: html notranslate">&lt;link rel="stylesheet" href="styles.css"&gt;</pre>
+
+<p>Cet élément {{htmlelement("link")}} indique au navigateur la présence d'une feuille de style, grâce à l'attribut <code>rel</code> ; la valeur de l'attribut <code>href</code> donne la localisation du fichier CSS. Pour tester que le lien fonctionne, nous allons définir une règle dans <code>styles.css</code>. Grâce à votre éditeur de code, ajoutez les lignes suivantes à la feuille de style CSS :</p>
+
+<pre class="brush: css notranslate">h1 {
+ color: red;
+}</pre>
+
+<p>Dans votre éditeur de code, sauvegardez vos documents HTML et CSS puis rechargez la page HTML dans votre navigateur. Le titre de niveau un en haut du document devrait maintenant apparaître en rouge. Si c'est le cas, félicitations — vous avez appliqué avec succès une règle CSS à votre document HTML. Si ce n'est pas le cas, vérifiez scrupuleusement que vous avez tout bien fait comme indiqué.</p>
+
+<p>Pour suivre le reste de ce tutoriel, vous pouvez continuer à éditer <code>styles.css</code> sur votre machine, ou utiliser l'éditeur interactif proposé ci-dessous. L'éditeur interactif se comporte comme si le CSS dans le premier cadre était lié au document HTML, exactement comme sur votre machine après les manipulations précédentes.</p>
+
+<h2 id="Mettre_en_forme_des_éléments_HTML">Mettre en forme des éléments HTML</h2>
+
+<p>En passant la couleur de police des titres en rouge nous avons vu comment sélectionner et mettre en forme un élément HTML.</p>
+
+<p>Cela est réalisé grâce à un sélecteur d'élément — dans la règle CSS, le sélecteur correspond au nom d'un élément HTML. Pour appliquer un style à tous les paragraphes du document HTML on utilisera le sélecteur <code>p</code>. Voilà la règle pour passer en vert tous les paragraphes :</p>
+
+<pre class="brush: css notranslate">p {
+ color: green;
+}</pre>
+
+<p>On peut cibler plusieurs éléments d'un coup en les listant, séparés par une virgule. Si je veux que tous les paragraphes et tous les items de liste soient verts j'écrirai la règle suivante :</p>
+
+<pre class="brush: css notranslate">p, li {
+ color: green;
+}</pre>
+
+<p>Testez cela dans l'éditeur interacif ci-dessous (éditer les boîtes de code) ou sur votre machine en local.</p>
+
+<p>{{EmbedGHLiveSample("css-examples/learn/getting-started/started1.html", '100%', 900)}} </p>
+
+<h2 id="Changer_le_comportement_par_défaut_des_éléments">Changer le comportement par défaut des éléments</h2>
+
+<p>Quand on observe un document HTML bien formé, même simple comme notre exemple, on peut voir comment un navigateur le rend lisible par une mise en forme par défaut. Les titres sont écrits en gras dans une taille plus grande, les items des listes sont précédés d'une puce. Les navigateurs ont leurs feuilles de style internes qu'ils appliquent par défaut à toutes les pages ; sans cela, tout le texte s'agglutinerait en paquet et il faudrait tout mettre en forme à partir de zéro. Tous les navigateurs modernes rendent les contenus HTML par défaut essentiellement de la même manière.</p>
+
+<p>On recherche pourtant souvent autre chose que ce rendu par défaut. Il suffit alors de sélectionner l'élément HTML dont on veut modifier le rendu et d'écrire la règle CSS pour réaliser cette mise en forme.  Un bon exemple est notre <code>&lt;ul&gt;</code>, une liste non ordonnée. Ses items sont marqués par des puces et si on décide de se débarrasser de ces puces, on peut le faire comme suit :</p>
+
+<pre class="brush: css notranslate">li {
+ list-style-type: none;
+}</pre>
+
+<p>Ajoutez cette règle dans votre CSS et testez en l'effet.</p>
+
+<p>Cherchez maintenant sur MDN quelles sont les valeurs possibles pour la propriété <code>list-style-type</code>. Dans la page pour <code><a href="/fr/docs/Web/CSS/list-style-type">list-style-type</a></code> vous trouverez un exemple interactif en haut de page, vous pourrez tester quelques valeurs ; toutes les valeurs autorisées sont détaillées dans le reste de la page.</p>
+
+<p>En parcourant la page de documentation, vous découvrirez qu'au lieu de supprimer les puces, vous pouvez en changer l'aspect — essayez la valeur <code>square</code> pour obtenir des puces carrées.</p>
+
+<h2 id="Ajouter_une_classe">Ajouter une classe</h2>
+
+<p>Jusqu'ici, nous avons mis en forme des éléments HTML repérés par leur nom de balise. Cela fonctionne tant que vous voulez appliquer le même style à tous les éléments de ce type dans le document. La plupart du temps ce n'est pas le comportement désiré ; il faut donc trouver une méthode pour sélectionner un sous-ensemble des éléments à mettre en forme sans changer l'apparence des autres éléments du même type. L'approche la plus commune pour obtenir ce comportement est d'ajouter une classe (pensez à une étiquette) aux éléments HTML à mettre en forme puis de sélectionner cette classe.</p>
+
+<p>Dans le document HTML, ajouter un  <a href="/fr/docs/Web/HTML/Attributs_universels/class">attribut class</a> au deuxième item de la liste :</p>
+
+<pre class="brush: html notranslate">&lt;ul&gt;
+ &lt;li&gt;Item un&lt;/li&gt;
+ &lt;li <strong>class="special"</strong>&gt;Item deux&lt;/li&gt;
+ &lt;li&gt;Item &lt;em&gt;trois&lt;/em&gt;&lt;/li&gt;
+&lt;/ul&gt;</pre>
+
+<p>Dans votre CSS vous pouvez maintenant cibler la classe <code>special</code> grâce à un sélecteur fait du nom de la classe précédé d'un point. Ajoutez le code suivant à votre feuille de style :</p>
+
+<pre class="brush: css notranslate">.special {
+ color: orange;
+ font-weight: bold;
+}</pre>
+
+<p>Sauvegardez et rechargez la page HTML dans votre navigateur pour observer le résultat.</p>
+
+<p>Vous pouvez attribuer la classe <code>special</code> à tout élément dans votre document HTML, dans le navigateur il sera rendu comme le deuxième item de la liste. Par exemple, vous pourriez appliquer ce style à l'élément <code>&lt;span&gt;</code> du premier paragraphe.</p>
+
+<p>Vous verrez parfois des règles avec un sélecteur qui combine le nom de l'élément HTML avec celui de la classe  :</p>
+
+<pre class="brush: css notranslate">li.special {
+ color: orange;
+ font-weight: bold;
+}</pre>
+
+<p>Cette syntaxe signifie "s'applique à tous les éléments <code>li</code> dont l'attribut <code>class</code> a la valeur <code>special</code><em> </em>". Cette règle ne s'applique alors plus à l'élément <code>&lt;span&gt;</code> ou à tout autre élément dont l'attribut <code>class</code> a la valeur <code>special</code><em> </em>mais<em> </em>qui n'est pas un <code>&lt;li&gt;.</code> Pour que la règle s'applique aussi au <code>&lt;span&gt;</code>  il faudrait l'ajouter dans la liste des sélecteurs :</p>
+
+<pre class="brush: css notranslate">li.special,
+span.special {
+ color: orange;
+ font-weight: bold;
+}</pre>
+
+<p>Comme vous pouvez bien l'imaginer, certaines classes s'appliquent à un grand nombre d'éléments et il n'est pas pensable de devoir éditer la feuille de style à chaque modification du document HTML. Les sélecteurs composé du nom de l'élément suivi de celui de la classe sont donc plutôt réservés aux situations où la règle ne s'applique qu'à un élément unique.</p>
+
+<h2 id="Style_en_fonction_de_la_position">Style en fonction de la position</h2>
+
+<p>Il y a des situations où vous voudrez que le style d'un élément s'adapte en fonction de sa position dans le document. De nombreux sélecteurs permettent de réaliser ce type de comportement, voyons les plus simples. Dans notre document HTML il y a deux éléments <code>&lt;em&gt;</code> — l'un dans un paragraphe l'autre dans l'item d'une liste. On peut cibler le <code>&lt;em&gt;</code> imbriqué dans l'élément <code>&lt;li&gt;</code> avec un <strong>combinateur descendant </strong>qui prend la forme suivante<strong> : </strong>deux sélecteurs séparés par un espace.</p>
+
+<p>Ajoutez la règle suivante à votre feuille de style :</p>
+
+<pre class="brush: css notranslate">li em {
+ color: rebeccapurple;
+}</pre>
+
+<p>Ce sélecteur cible tout élément <code>&lt;em&gt;</code> à l'intérieur (descendant) d'un <code>&lt;li&gt;</code>. Ainsi, dans notre exemple, le <code>&lt;em&gt;</code> dans le troisième item de la liste sera maintenant pourpre, alors que celui du paragraphe est inchangé.</p>
+
+<p>On pourrait maintenant essayer d'appliquer un style à un paragraphe quand il vient juste après un titre de niveau un dans le HTML. Pour obtenir cela, on place un <code>+</code>  (le <strong>combinateur de frères et sœurs adjacents</strong>) entre les sélecteurs.</p>
+
+<p>Ajoutez cette règle à votre feuille de style :</p>
+
+<pre class="brush: css notranslate">h1 + p {
+ font-size: 200%;
+}</pre>
+
+<p>L'exemple live ci-dessous inclut les deux règles précédentes. Essayez d'ajouter une règle qui passe &lt;span&gt; en rouge s'il est dans un paragraphe. Votre règle est correcte, si après sauvegarde du CSS et rafraîchissement du HTML dans le navigateur, le &lt;span&gt; du premier paragraphe est rouge mais celui du premier item de la liste est inchangé.</p>
+
+<p>{{EmbedGHLiveSample("css-examples/learn/getting-started/started2.html", '100%', 1100)}}</p>
+
+<div class="blockIndicator note">
+<p><strong>Note </strong>:  A ce point, on a déjà découvert plusieurs méthodes CSS pour cibler les éléments et pourtant on vient à peine de commencer ! Nous passerons en revue plus systématiquement tous ces sélecteurs dans la leçon <a href="/en-US/docs/Learn/CSS/Building_blocks/Selectors">CSS Selectors</a> du cours suivant.</p>
+</div>
+
+<h2 id="Mise_en_forme_basée_sur_létat">Mise en forme basée sur l'état</h2>
+
+<p>Pour finir ce tutoriel, voyons comment on peut appliquer une mise en forme basée sur l'état d'un élément. La mise en forme des liens illustre cela à merveille. Pour appliquer un style sur un lien, on doit cibler l'élément <code><a href="/en-US/docs/Web/HTML/Element/a">&lt;a&gt;</a></code> (ancre). Cet élément a différents états selon que le lien a ou n'a pas été visité (<code>visited</code>), est survolé par le curseur (<code>hover</code>), a le focus clavier (<code>focus</code>), ou si l'utilisateur est en train de cliquer sur ce lien (<code>active</code>). CSS permet de cibler ces différents états — les règles ci-dessous colorent en rose les liens non visités et en vert ceux qui l'ont été.</p>
+
+<pre class="brush: css notranslate">a:link {
+ color: pink;
+}
+
+a:visited {
+ color: green;
+}</pre>
+
+<p>On peut changer l'aspect des liens survolés, par exemple en supprimant le soulignement, avec la règle suivante :</p>
+
+<pre class="brush: css notranslate">a:hover {
+ text-decoration: none;
+}</pre>
+
+<p>Dans l'exemple live ci-dessous, vous pouvez explorer les valeurs des différents états d'un lien. J'ai rajouté les règles précédentes à la feuille de style, notez comment le rose est très clair, peu lisible — pourquoi ne pas trouver une meilleure couleur ? Pourriez-vous passer les liens en gras ?</p>
+
+<p>{{EmbedGHLiveSample("css-examples/learn/getting-started/started3.html", '100%', 900)}} </p>
+
+<p>Nous avons supprimé le soulignement quand le lien est survolé.Vous pourriez supprimer le soulignement quel que soit l'état du lien. Dans un vrai site, il est quand même important que le visiteur sache qu'un lien est un lien. Le soulignement donne un indice important aux visiteurs pour réaliser qu'un bout de texte dans un paragraphe est cliquable — c'est le comportement auquel ils sont habitués. Avec le contrôle que donne CSS, les changements de style peuvent parfois rendre le document moins accessible — à chaque fois que nécessaire nous nous efforcerons de signaler les pièges classiques dans cette direction.</p>
+
+<div class="blockIndicator note">
+<p><strong>Note </strong>: dans ce cours et à travers le site MDN, vous rencontrerez souvent la notion d'<a href="/fr/docs/Apprendre/a11y">accessibilité</a> : les règles pour que nos pages soient compréhensibles et utilisables par tous.</p>
+
+<p>Vos visiteurs peuvent consulter votre page depuis un ordinateur équipé d'une souris ou d'un trackpad, ou depuis un téléphone avec un écran tactile. Ils peuvent aussi utiliser un lecteur d'écran qui parcourt le contenu du document. Ils pourraient avoir besoin d'un affichage en grands caractères, ou parcourir votre site en ne naviguant qu'avec le clavier.</p>
+
+<p>Un document HTML pur est généralement accessible à tous — il est important que les mises en forme appliquées ne le rendent pas moins accessible.</p>
+</div>
+
+<h2 id="Associer_sélecteurs_et_combinateurs">Associer sélecteurs et combinateurs</h2>
+
+<p>On peut associer sélecteurs et combinateurs. Par exemple :</p>
+
+<pre class="brush: css notranslate">/* sélectionne tout &lt;span&gt; à l'intérieur d'un &lt;p&gt;, lui-même à l'intérieur d'un &lt;article&gt; */
+article p span { ... }
+
+/* sélectionne tout &lt;p&gt; qui vient juste après un &lt;ul&gt;, lui-même venant just après un &lt;h1&gt; */
+h1 + ul + p { ... }</pre>
+
+<p>On peut aussi combiner les types multiples. Essayez d'ajouter les règles suivantes à votre feuille de style :</p>
+
+<pre class="brush: css notranslate">body h1 + p .special {
+ color: yellow;
+ background-color: black;
+ padding: 5px;
+}</pre>
+
+<p>Cette règle cible tout élément dont l'attribut class vaut <code>special</code>, à l'intérieur d'un <code>&lt;p&gt;</code>, qui vient juste après un <code>&lt;h1&gt;</code>, à l'intérieur de <code>&lt;body&gt;</code>. Ouf !</p>
+
+<p>Dans notre document HTML le seul élément mis en forme selon la règle ci-dessus est <code>&lt;span class="special"&gt;</code>.</p>
+
+<p>Pas de panique, cela peut sembler compliqué pour le moment — avec un peu de pratique du CSS, vous maîtriserez très bientôt tout cela.</p>
+
+<h2 id="Bilan">Bilan</h2>
+
+<p>Dans ce tutoriel nous avons vu plusieurs façons de mettre en forme un document grâce aux règles CSS. En progressant dans les leçons de ce cours, nous développerons ces connaissances.</p>
+
+<p>Vous en savez pourtant déjà assez pour : mettre en forme un texte ; utiliser différentes méthodes pour sélectionner les éléments HTML visés ; et recherchez les propriétés et les valeurs dans la documentation MDN.</p>
+
+<p>Dans la leçon suivante, nous étudirons comment CSS est structuré.</p>
+
+<p>{{PreviousMenuNext("Learn/CSS/First_steps/What_is_CSS", "Learn/CSS/First_steps/How_CSS_is_structured", "Learn/CSS/First_steps")}}</p>
+
+<h2 id="Dans_ce_cours">Dans ce cours</h2>
+
+<ol>
+ <li><a href="/fr/docs/Learn/CSS/First_steps/Qu_est_ce_que_CSS">Qu'est ce que  CSS?</a></li>
+ <li><a href="/fr/docs/Learn/CSS/First_steps/Getting_started">Démarrer avec CSS</a></li>
+ <li><a href="/fr/docs/Learn/CSS/First_steps/How_CSS_is_structured">Comment CSS est structuré</a></li>
+ <li><a href="/fr/docs/Learn/CSS/First_steps/How_CSS_works">CSS comment ça marche ?</a></li>
+ <li><a href="/fr/docs/Learn/CSS/First_steps/Using_your_new_knowledge">Utiliser vos connaissances</a></li>
+</ol>
diff --git a/files/fr/learn/css/first_steps/how_css_is_structured/index.html b/files/fr/learn/css/first_steps/how_css_is_structured/index.html
new file mode 100644
index 0000000000..c8dd73edb2
--- /dev/null
+++ b/files/fr/learn/css/first_steps/how_css_is_structured/index.html
@@ -0,0 +1,517 @@
+---
+title: Comment CSS est structuré
+slug: Learn/CSS/First_steps/How_CSS_is_structured
+tags:
+ - Apprendre
+ - CSS
+ - Commentaires
+ - Débutant
+ - HTML
+ - Propriétés
+ - Structure
+ - Sélecteurs
+ - espace
+ - raccourci
+ - valeurse
+translation_of: Learn/CSS/First_steps/How_CSS_is_structured
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/CSS/First_steps/Getting_started", "Learn/CSS/First_steps/How_CSS_works", "Learn/CSS/First_steps")}}</div>
+
+<p class="summary">Vous avez maintenant une idée plus claire de CSS. Vous connaissez les bases de son fonctionnement. Il est temps d'explorer plus avant la structure du langage lui-même. Nous avons déjà rencontré nombre des concepts apparaissant dans ce tutoriel ; reportez vous aux leçons précédentes si un concept vous semble peu clair.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Prérequis :</th>
+ <td>Maîtrise élémentaire de l'informatique, <a href="https://developer.mozilla.org/fr/docs/Apprendre/Commencer_avec_le_web/Installation_outils_de_base">suite logicielle de base installée</a>, compétences élémentaires pour <a href="/fr/docs/Apprendre/Commencer_avec_le_web/Gérer_les_fichiers">travailler avec des fichiers</a>, connaissance de base du HTML  (cf. <a href="/fr/docs/Apprendre/HTML/Introduction_à_HTML">Introduction à HTML</a>), et une idée de <a href="/fr/docs/Learn/CSS/First_steps/How_CSS_works">Comment fonctionne CSS</a>.</td>
+ </tr>
+ <tr>
+ <th scope="row">Objectif :</th>
+ <td>Approfondir les structures syntaxiques fondamentales de CSS</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Appliquer_CSS_à_votre_document_HTML">Appliquer CSS à votre document HTML</h2>
+
+<p>Regardons d'abord les trois méthodes pour appliquer CSS à un document.</p>
+
+<h3 id="Feuille_de_style_externe">Feuille de style externe</h3>
+
+<p>Dans la leçon <a href="/fr/docs/Learn/CSS/First_steps/Getting_started">Démarrer avec CSS</a> nous avons lié une feuille de style externe à notre document. C'est la méthode la plus commune pour appliquer CSS à un document. C'est aussi la plus utile : dans la plupart des cas, les différentes pages d'un site ont à peu près la même apparence, on peut donc utiliser le même jeu de règles pour l'apparence de base. Il est dans ce cas commode d'écrire ces règles une seule fois dans une feuille de style commune à toutes les pages.</p>
+
+<p>Dans le cas d'une feuille de style externe, les règles CSS sont écrites dans un fichier séparé, avec l'extension <code>.css</code>. Un élement HTML <code>&lt;link&gt;</code> fait référence à ce fichier.</p>
+
+<pre class="brush: html notranslate">&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+ &lt;head&gt;
+ &lt;meta charset="utf-8"&gt;
+ &lt;title&gt;Une expérience avec CSS&lt;/title&gt;
+ &lt;link rel="stylesheet" href="styles.css"&gt;
+ &lt;/head&gt;
+ &lt;body&gt;
+ &lt;h1&gt;Hello World!&lt;/h1&gt;
+ &lt;p&gt;ceci est mon premier exemple CSS&lt;/p&gt;
+ &lt;/body&gt;
+&lt;/html&gt;</pre>
+
+<p>Le fichier CSS devrait ressembler à cela :</p>
+
+<pre class="brush: css notranslate">h1 {
+ color: blue;
+ background-color: yellow;
+ border: 1px solid black;
+}
+
+p {
+ color: red;
+}</pre>
+
+<p>L'attribut <code>href</code> de l'élement {{htmlelement("link")}} doit pointer vers un fichier dans votre système de fichiers.</p>
+
+<p>Dans l'exemple ci-dessus, le fichier CSS et le document HTML sont dans le même dossier, mais vous pouvez le placer ailleurs et ajuster le chemin, par exemple :</p>
+
+<pre class="brush: html notranslate">&lt;!-- Dans un sous répertoire nommé styles dans le répertoire courant --&gt;
+&lt;link rel="stylesheet" href="styles/style.css"&gt;
+
+&lt;!-- Dans un sous répertoire nommé general, lui-même dans un sous répertoire nommé styles, dans le répertoire courant --&gt;
+&lt;link rel="stylesheet" href="styles/general/style.css"&gt;
+
+&lt;!-- Dans un sous répertoire nommé styles, un niveau plus haut --&gt;
+&lt;link rel="stylesheet" href="../styles/style.css"&gt;</pre>
+
+<h3 id="Feuille_de_style_interne">Feuille de style interne</h3>
+
+<p>Les règles CSS peuvent être écrites directement dans l'en-tête HTML {{htmlelement("head")}} dans un élément {{htmlelement("style")}}. On parle alors de feuille de style interne.</p>
+
+<p>Le code HTML ci-dessous illustre cette technique :</p>
+
+<pre class="brush: html notranslate">&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+ &lt;head&gt;
+ &lt;meta charset="utf-8"&gt;
+ &lt;title&gt;Mes experimentations CSS&lt;/title&gt;
+ &lt;style&gt;
+ h1 {
+ color: blue;
+ background-color: yellow;
+ border: 1px solid black;
+ }
+
+ p {
+ color: red;
+ }
+ &lt;/style&gt;
+ &lt;/head&gt;
+ &lt;body&gt;
+ &lt;h1&gt;Hello World!&lt;/h1&gt;
+ &lt;p&gt;Ceci est mon premier exemple CSS&lt;/p&gt;
+ &lt;/body&gt;
+&lt;/html&gt;</pre>
+
+<p>Cette méthode peut être utile dans certaines circonstances (un système de gestion de contenu (CMS) qui n'autoriserait pas la modification du fichier <code>style.css</code>). Cette solution est un pis-aller, on préfèrera quand c'est possible une feuille de style externe — dans un site web, avec la méthode de styles internes, le CSS doit être recopié dans chaque page : la mise à jour des styles nécessite donc de modifier chaque fichier.</p>
+
+<h3 id="Styles_en_ligne">Styles en ligne</h3>
+
+<p>Les styles en ligne sont des déclarations CSS qui n'affectent qu'un seul élement, elles sont déclarées grâce à l'attribut <code>style</code>:</p>
+
+<pre class="brush: html notranslate">&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+ &lt;head&gt;
+ &lt;meta charset="utf-8"&gt;
+ &lt;title&gt;Mes experimentations CSS&lt;/title&gt;
+ &lt;/head&gt;
+ &lt;body&gt;
+ &lt;h1 style="color: blue;background-color: yellow;border: 1px solid black;"&gt;Hello World!&lt;/h1&gt;
+ &lt;p style="color:red;"&gt;Ceci est mon premier exemple CSS&lt;/p&gt;
+ &lt;/body&gt;
+&lt;/html&gt;</pre>
+
+<p><strong>Cette approche est vraiment à proscrire ! </strong>Le code produit n'est pas maintenable (les modifications ne doivent plus se faire pour chaque page, mais dans chaque page, élément par élément !). Par ailleurs, mélanger le CSS  avec le HTML rend la lecture du code plus difficile. En plus d'une meilleure lisibilité du code, séparer le fond de la forme rend le travail d'équipe plus facile.</p>
+
+<p>Il existe quelques endroits où les styles en ligne sont communs, voire recommandés. Vous devrez peut-être les utiliser si votre environnement de travail est vraiment restrictif (votre CMS ne vous permet peut-être que de modifier le corps du  HTML). Vous les verrez également beaucoup utilisés dans les e-mails HTML afin d’être compatibles avec autant de clients de messagerie que possible.</p>
+
+<h2 id="Jouer_avec_le_CSS_de_cet_article">Jouer avec le CSS de cet article</h2>
+
+<p>Les exemples de cet article sont autant d'occasions pour faire vos premiers tests. Pour ce faire, nous vous recommandons de créer un nouveau répertoire sur votre ordinateur et d'y créer une copie des deux fichiers suivants :</p>
+
+<p><strong>index.html</strong> :</p>
+
+<pre class="brush: html notranslate">&lt;!DOCTYPE html&gt;
+&lt;html lang="en"&gt;
+ &lt;head&gt;
+ &lt;meta charset="utf-8"&gt;
+ &lt;title&gt;Mes expériences CSS&lt;/title&gt;
+ &lt;link rel="stylesheet" href="styles.css"&gt;
+ &lt;/head&gt;
+ &lt;body&gt;
+
+ &lt;p&gt;Créez votre test ici !&lt;/p&gt;
+
+ &lt;/body&gt;
+&lt;/html&gt;</pre>
+
+<p><strong>styles.css</strong> :</p>
+
+<pre class="brush: css notranslate">/* Créez votre test CSS ici */
+
+p {
+ color: red;
+}</pre>
+
+<p>Ensuite, lorsque vous rencontrez du code à tester : collez le HTML à mettre en forme entre les balises <code>&lt;body&gt;</code> ... <code>&lt;/body&gt;</code> dans le fichier  <code>index.html</code> ;  ajoutez les règles CSS dans la feuille <code>styles.css</code>.</p>
+
+<p>Si le système que vous utilisez rend difficile la création de fichiers, vous pouvez utiliser l'éditeur interactif ci-dessous pour vos expériences.</p>
+
+<p>{{EmbedGHLiveSample("css-examples/learn/getting-started/experiment-sandbox.html", '100%', 800)}} </p>
+
+<p>Bonne lecture !</p>
+
+<h2 id="Sélecteurs">Sélecteurs</h2>
+
+<p>Vous ne pouvez pas parler de CSS sans rencontrer les sélecteurs et nous en avons déjà découvert différents types dans le tutoriel <a href="/fr-FR/docs/Learn/CSS/First_steps/Getting_started">Démarrer avec CSS</a>.  Un sélecteur cible quelque chose dans le document HTML afin de lui appliquer des styles. Quand une mise en forme ne ne s'applique pas comme prévu, il est probable que le sélecteur concerné ne fonctionne pas comme vous l'attendiez.</p>
+
+<p>Chaque règle CSS commence par un sélecteur ou une liste de sélecteurs afin d'indiquer au navigateur les éléments auxquels les règles doivent s'appliquer. Tous les exemples suivants sont des exemples de sélecteurs valides ou de listes de sélecteurs.</p>
+
+<pre class="brush: css notranslate">h1
+a:link
+.manythings
+#onething
+*
+.box p
+.box p:first-child
+h1, h2, .intro</pre>
+
+<p><strong>Essayez de créer des règles CSS qui utilisent les sélecteurs ci-dessus et du code HTML à styler. Si vous ne savez pas ce que signifie la syntaxe ci-dessus, essayez de la rechercher sur MDN !</strong></p>
+
+<div class="blockIndicator note">
+<p><strong>Note </strong>: Vous en apprendrez beaucoup plus sur les sélecteurs dans nos tutoriels sur <a href="/fr-FR/docs/Learn/CSS/Building_blocks/Selectors">les sélecteurs CSS</a>, dans un prochain cours.</p>
+</div>
+
+<h3 id="Spécificité">Spécificité</h3>
+
+<p>Dans de nombreux cas, deux sélecteurs différents peuvent cibler le même élément HTML. Considérons la feuille de style ci-dessous où j'ai une règle avec un sélecteur <code>p</code> qui colore les paragraphes en bleu, puis une règle qui colore en rouge les éléments dans la classe <code>special</code>.</p>
+
+<pre class="brush: css notranslate">.special {
+ color: red;
+}
+
+p {
+ color: blue;
+}</pre>
+
+<p>Disons que dans notre document HTML, nous avons un paragraphe avec un attribut <code>class</code> valant <code>special</code>. Les deux règles pourraient s'appliquer. Selon vous, quelle sera la couleur du paragraphe ?</p>
+
+<pre class="brush: html notranslate">&lt;p class="special"&gt;De quelle couleur suis-je?&lt;/p&gt;</pre>
+
+<p>Le langage CSS a des règles pour déterminer quelle mise en forme appliquer en cas de collision de sélecteurs — elles sont appelées <strong>cascade</strong> et <strong>spécificité</strong>. Dans le bloc de code ci-dessous, nous avons défini deux règles pour le sélecteur <code>p</code>, mais le paragraphe finit par être coloré en bleu. En effet, la déclaration qui l'a défini en bleu apparaît plus tard dans la feuille de style et les styles ultérieurs remplacent les précédents. C'est la <em>cascade</em> en action.</p>
+
+<pre class="brush: css notranslate">p {
+ color: red;
+}
+
+p {
+ color: blue;
+}</pre>
+
+<p>Cependant, dans l'exemple plus haut avec le sélecteur de classe et le sélecteur d'élément, la classe l'emportera, rendant le paragraphe rouge — même s'il apparaît plus tôt dans la feuille de style. Une classe est décrite comme étant plus spécifique ou ayant plus de <em>spécificité</em> que le sélecteur d'élément, elle gagne donc.</p>
+
+<p><strong>Tentez vous-même l'expérience ci-dessus </strong>—<strong> ajoutez le code HTML à votre expérience, puis ajoutez les deux règles <code>p {...}</code> à votre feuille de style. Ensuite, changez le premier sélecteur <code>p</code> en <code>.special</code> pour voir comment il affecte le style.</strong></p>
+
+<p>Au premier abord, les règles de cascade et de spécificité peuvent sembler compliquées ; avec une meilleure connaissance de CSS, elles vous paraîtront plus naturelles. Dans le prochain module, l'article <a href="/en-US/docs/Learn/CSS/Building_blocks/Cascade_and_inheritance">Cascade et héritage</a> vous détaillera ces principes et expliquera notamment comment calculer la spécificité. Pour le moment, rappelez vous que de tels cas existent et que le CSS peut parfois ne pas s'appliquer comme prévu. Dans une telle situation, souvenez-vous qu'un même élément peut être la cible de plusieurs sélecteurs concurrents.</p>
+
+<h2 id="Propriétés_et_valeurs">Propriétés et valeurs</h2>
+
+<p>Au niveau le plus fondamental, CSS se compose de deux blocs de construction :</p>
+
+<ul>
+ <li><strong>Propriétés </strong>: des identifiants lisibles par l'homme indiquant les caractéristiques stylistiques (<code><a href="/en-US/docs/Web/CSS/font-size">font-size</a></code>, <code><a href="/en-US/docs/Web/CSS/width">width</a></code>, <code><a href="/en-US/docs/Web/CSS/background-color">background-color</a></code>, par exemple) que vous souhaitez modifier ;</li>
+ <li><strong>Valeurs </strong>: une valeur est attribuée à chaque propriété spécifiée. Elle indique comment vous souhaitez modifier ces caractéristiques stylistiques (par exemple, en modifiant la couleur de la police, la largeur ou l’arrière-plan).</li>
+</ul>
+
+<p>L'image ci-dessous met en évidence une propriété et une valeur uniques. Le nom de la propriété est <code>color</code> et la valeur <code>blue</code>.</p>
+
+<p><img alt="A declaration highlighted in the CSS" src="https://mdn.mozillademos.org/files/16498/declaration.png" style=""></p>
+
+<p>Une propriété associée à une valeur s'appelle une <em>déclaration CSS</em>. Les déclarations CSS sont placées dans des <em>blocs de déclaration CSS</em>. L'image suivante montre notre CSS avec le bloc de déclaration en surbrillance.</p>
+
+<p><img alt="A highlighted declaration block" src="https://mdn.mozillademos.org/files/16499/declaration-block.png" style=""></p>
+
+<p>Enfin, les blocs de déclaration CSS sont associés à des <em>sélecteurs</em> pour produire des <em>ensembles de règles CSS</em> (ou <em>règles CSS</em>). L'image contient deux règles, une pour le sélecteur <code>h1</code> et une pour le sélecteur <code>p</code>. La règle pour <code>h1</code> est mise en surbrillance.</p>
+
+<p><img alt="The rule for h1 highlighted" src="https://mdn.mozillademos.org/files/16500/rules.png" style=""></p>
+
+<p>Définir les propriétés CSS sur des valeurs spécifiques est la fonction principale du langage CSS. Le moteur CSS calcule les déclarations qui s'appliquent à chaque élément d'une page afin de le présenter et de le styler de manière appropriée. Ce qui est important à retenir est que les propriétés et les valeurs sont sensibles à la casse en CSS. La propriété et la valeur de chaque paire sont séparées par deux points (<code>:</code>).</p>
+
+<p><strong>Recherchez différentes valeurs possibles pour les propriétés suivantes puis écrivez des règles CSS qui les appliquent à différents éléments HTML : </strong></p>
+
+<ul>
+ <li><strong>{{cssxref("font-size")}}</strong></li>
+ <li><strong>{{cssxref("width")}}</strong></li>
+ <li><strong>{{cssxref("background-color")}}</strong></li>
+ <li><strong>{{cssxref("color")}}</strong></li>
+ <li><strong>{{cssxref("border")}}</strong></li>
+</ul>
+
+<div class="warning">
+<p><strong>Important </strong>: Si la propriété est inconnue ou si la valeur est invalide pour une propriété donnée, la déclaration est considérée comme <em>invalide</em> et complètement ignorée par le moteur CSS du navigateur.</p>
+</div>
+
+<div class="warning">
+<p><strong>Important </strong>: En CSS (et dans les autres standards web), l'orthographe américaine a été adoptée comme norme à respecter en cas d'incertitude linguistique. Par exemple, la couleur doit <em>toujours</em> être notée <code>color</code>. <code>couleur</code> ne fonctionnera pas.</p>
+</div>
+
+<h3 id="Fonctions">Fonctions</h3>
+
+<p>Bien que la plupart des valeurs soient des mots-clés relativement simples ou des valeurs numériques, on peut aussi appeler une fonction  pour calculer une valeur dans une déclaration CSS. Un exemple serait la fonction <code>calc()</code>. Cette fonction vous permet de faire des calculs simples à partir de CSS, par exemple :</p>
+
+<div id="calc_example">
+<pre class="brush: html notranslate">&lt;div class="outer"&gt;&lt;div class="box"&gt;la boite interne vaut 90% - 30px.&lt;/div&gt;&lt;/div&gt;</pre>
+
+<pre class="brush: css notranslate">.outer {
+ border: 5px solid black;
+}
+
+.box {
+ padding: 10px;
+ width: calc(90% - 30px);
+ background-color: rebeccapurple;
+ color: white;
+}</pre>
+</div>
+
+<p>La page devrait s'afficher comme ceci :</p>
+
+<p>{{EmbedLiveSample('calc_example', '100%', 200)}}</p>
+
+<p>Une fonction est composée du nom de la fonction suivi d'une paire de parenthèses entre lesquelles sont placées les valeurs autorisées pour cette fonction. Dans le cas de l'exemple <code>calc()</code> ci-dessus, on demande que la largeur de cette zone soit égale à 90% de la largeur du bloc conteneur, moins 30 pixels. Ce n'est pas quelque chose que l'on peut calculer à l'avance et simplement entrer la valeur dans le CSS, car on ne sait pas ce que seront 90%. Comme pour toutes les valeurs, chaque fonction a sa page de documentation sur MDN avec des exemples d'utilisation pour en voir le fonctionnement.</p>
+
+<p>Un autre exemple serait les différentes valeurs de la propriété {{cssxref ("&lt;transform&gt;")}}, telles que <code>rotate()</code>.</p>
+
+<div id="transform_example">
+<pre class="brush: html notranslate">&lt;div class="box"&gt;&lt;/div&gt;</pre>
+
+<pre class="brush: css notranslate">.box {
+ margin: 30px;
+ width: 100px;
+ height: 100px;
+ background-color: rebeccapurple;
+ transform: rotate(0.8turn)
+}</pre>
+</div>
+
+<p>La page devrait s'afficher comme ceci :</p>
+
+<p>{{EmbedLiveSample('transform_example', '100%', 200)}}</p>
+
+<p><strong>Essayez de rechercher différentes valeurs des propriétés suivantes et d'écrire des règles CSS qui les appliquent à différents éléments HTML : </strong></p>
+
+<ul>
+ <li><strong>{{cssxref("transform")}}</strong></li>
+ <li><strong>{{cssxref("background-image")}}, in particular gradient values</strong></li>
+ <li><strong>{{cssxref("color")}}, in particular rgb/rgba/hsl/hsla values</strong></li>
+</ul>
+
+<h2 id="rules">@rules</h2>
+
+<p>Nous n'avons pas rencontré jusqu'ici les <code><a href="/en-US/docs/Web/CSS/At-rule">@rules</a></code> (prononcer "at-rules"). Ce sont des règles spéciales dictant un comportement CSS. Certaines <code>@rules</code>  simples sont composées d'un nom et d'une valeur. Par exemple, pour importer une feuille de style additionnelle dans le CSS principal on utilisera  <code>@import</code> :</p>
+
+<pre class="brush: css notranslate">@import 'styles2.css';</pre>
+
+<p>L'une des <code>@rules</code> les plus fréquemment rencontrée est <code>@media</code>, qui permet d'utiliser les <a href="/fr/docs/Web/CSS/Requêtes_média">media queries</a> pour appliquer CSS seulement quand certaines conditions sont vérifiées (par ex. quand la résolution de l'écran dépasse une certaine valeur, ou quand l'écran dépasse une certaine largeur).</p>
+
+<p>Dans le CSS ci-dessous, une règle donne à l'élément <code>&lt;body&gt;</code> un fond rose. La section <code>@media</code> ne s'appliquera que dans les navigateurs dont la fenêtre est plus large que 30em. Dans ce cas la couleur de fond sera redéfinie à bleue.</p>
+
+<pre class="brush: css notranslate">body {
+ background-color: pink
+}
+
+@media (min-width: 30em) {
+ body {
+ background-color: blue;
+ }
+}</pre>
+
+<p>Tout au long de nos tutoriels CSS, vous rencontrerez d'autres <code>@rules</code>.</p>
+
+<p><strong>Ajoutez une media query à votre CSS  pour obtenir des changements de styles basés sur la largeur de la fenêtre. Changez la largeur de la fenêtre de votre navigateur pour contrôler le résultat.</strong></p>
+
+<h2 id="Raccourcis">Raccourcis</h2>
+
+<p>Certaines propriétés comme {{cssxref("font")}}, {{cssxref("background")}}, {{cssxref("padding")}}, {{cssxref("border")}}, ou {{cssxref("margin")}} sont appelées <strong>propriétés raccourci</strong> — elles permettent d'attribuer plusieurs couples propriété : valeur en une seule ligne. On gagne du temps et le code est plus joli.</p>
+
+<p>Par exemple, la ligne suivante  :</p>
+
+<pre class="brush: css notranslate">/* Dans les raccourcis à 4 valeurs comme padding ou margin, les valeurs sont données
+  dans l'ordre top, right, bottom, left (sens des aiguilles d'une montre depuis top).
+  Il y a d'autres raccourcis, a 2 valeurs par exemple qui padding ou margin
+  pour top/bottom, puis left/right */
+padding: 10px 15px 15px 5px;</pre>
+
+<p>produit le même effet que les quatre lignes suivantes réunies :</p>
+
+<pre class="brush: css notranslate">padding-top: 10px;
+padding-right: 15px;
+padding-bottom: 15px;
+padding-left: 5px;</pre>
+
+<p>Alors que :</p>
+
+<pre class="brush: css notranslate">background: red url(bg-graphic.png) 10px 10px repeat-x fixed;</pre>
+
+<p>produit la même chose que tout ce qui suit :</p>
+
+<pre class="brush: css notranslate">background-color: red;
+background-image: url(bg-graphic.png);
+background-position: 10px 10px;
+background-repeat: repeat-x;
+background-scroll: fixed;</pre>
+
+<p>Ce n'est pas le moment d'apprendre tous ces raccourcis — vous les croiserez à travers de nombreux exemples tout au long de ce cours, vous vous réfèrerez alors à notre <a href="/fr/docs/Web/CSS/Reference">référence CSS</a> pour en savoir plus.</p>
+
+<p><strong>Ajoutez les déclarations précédentes à votre CSS pour voir comment elles affectent la mise en forme de votre document HTML. Testez différentes valeurs.</strong></p>
+
+<div class="blockIndicator warning">
+<p><strong>Attention </strong>: Les raccourcis vous autorisent à ne pas déclarer certaines valeurs, mais dans ce cas, les valeurs non déclarées sont restaurées à leur valeur par défaut. Cela garantit l'usage d'un ensemble de valeurs qui restent raisonnables. Cela peut par contre vous surprendre, si vous pensiez que le rccourci ne changeait que les valeurs passées en argument.</p>
+</div>
+
+<h2 id="Commentaires">Commentaires</h2>
+
+<p>En CSS comme en HTML il est recomandé d'ajouter des commentaires, pour vous permettre de retrouver comment votre code fonctionne quand vous vous y replongez après quelques mois et pour permettre aussi à d'autres personnes de comprendre votre code quand elles sont amenées à travailler dessus.</p>
+
+<p>En CSS le début des commentaires est signalé par  <code>/*</code>  et la fin par <code>*/</code>. Dans le bloc de code ci-dessous, j'ai utilisé des commentaire pour marquer les différentes sections. Cela devient intéressant pour un code de taille importante— on peut alors utiliser les fonctionnalités de recherche de l'éditeur de code pour naviguer dans le fichier.</p>
+
+<pre class="brush: css notranslate">/* mise en forme des éléments de base */
+/* -------------------------------------------------------------------------------------------- */
+body {
+ font: 1em/150% Helvetica, Arial, sans-serif;
+ padding: 1em;
+ margin: 0 auto;
+ max-width: 33em;
+}
+
+@media (min-width: 70em) {
+ /* On donne un traitement conditionnel de la taille de police globale.
+  sur de grands écrans, on augmente la valeur de font-size pour une
+  meilleure lisibilité */
+ body {
+ font-size: 130%;
+ }
+}
+
+h1 {font-size: 1.5em;}
+
+/* mise en forme des éléments imbriqués dans le DOM */
+/* -------------------------------------------------------------------------------------------- */
+div p, #id:first-line {
+ background-color: red;
+ background-style: none
+}
+
+div p{
+ margin: 0;
+ padding: 1em;
+}
+
+div p + p {
+ padding-top: 0;
+}</pre>
+
+<p>Les commentaires sont aussi parfois utiles pour rendre temporairement inactive une zone de code (les sections commentées ne sont pas interprétées par le navigateur), par exemple pour identifier la partie de code responsable d'une erreur. Dans l'exemple suivant, la règle pour le sélecteur  <code>.special</code> a été désactivée par des commentaires :</p>
+
+<pre class="brush: css notranslate">/*.special {
+ color: red;
+}*/
+
+p {
+ color: blue;
+}</pre>
+
+<p><strong>Ajoutez des commentaires à votre CSS, il est bon que cela devienne une habitude.</strong></p>
+
+<h2 id="Espace">Espace</h2>
+
+<p>On parle ici d'espaces laissés blancs dans le texte, de tabulations, de retour à la ligne. Le navigateur tend à ignorer les espaces dans les codes CSS et HTML ; les espaces dans le code CSS sont làa plupart du temps là pour le rendre plus lisible.</p>
+
+<p>L'exemple ci-dessous propose d'écrire une déclaration par ligne — le code produit est facile à comprendre et à maintenir : c'est un bon code.</p>
+
+<pre class="brush: css notranslate">body {
+ font: 1em/150% Helvetica, Arial, sans-serif;
+ padding: 1em;
+ margin: 0 auto;
+ max-width: 33em;
+}
+
+@media (min-width: 70em) {
+ body {
+ font-size: 130%;
+ }
+}
+
+h1 {
+ font-size: 1.5em;
+}
+
+div p,
+#id:first-line {
+ background-color: red;
+ background-style: none
+}
+
+div p {
+ margin: 0;
+ padding: 1em;
+}
+
+div p + p {
+ padding-top: 0;
+}
+</pre>
+
+<p id="Very_compact">On peut écrire le même code CSS en retirant la plupart des espaces — le code ci-dessous est équivalent au précédent pour un navigateur, mais, vous l'admettrez, plus difficile à lire pour un humain !</p>
+
+<pre class="brush: css notranslate">body {font: 1em/150% Helvetica, Arial, sans-serif; padding: 1em; margin: 0 auto; max-width: 33em;}
+@media (min-width: 70em) { body {font-size: 130%;} }
+
+h1 {font-size: 1.5em;}
+
+div p, #id:first-line {background-color: red; background-style: none}
+div p {margin: 0; padding: 1em;}
+div p + p {padding-top: 0;}
+</pre>
+
+<p>La mise en forme de votre code est une question de goût personnel. Si vous travaillez en équipe, vous devrez sans doute vous plier aux conventions admises au sein de cette équipe.</p>
+
+<p>Il n'est pourtant pas possible de supprimer tous les espaces dans un fichier CSS. La suppression ou l'ajout d'espaces dans le code CSS peut produire des erreurs. Par exemple, les déclarations suivantes sont valides en CSS :</p>
+
+<pre class="brush: css notranslate">margin: 0 auto;
+padding-left: 10px;</pre>
+
+<p>Mais les suivantes sont invalides :</p>
+
+<pre class="brush: css notranslate">margin: 0auto;
+padding- left: 10px;</pre>
+
+<p><code>0auto</code> n'est pas reconnu comme une valeur possible pour la propriété <code>margin</code>  (<code>0</code> et <code>auto</code> sont chacune une valeur possible). Deux valeurs attribuées à une même propriété devront toujours être séparées par au moins un espace.</p>
+
+<p>Le navigateur ne connaît pas la propriété <code>padding-</code> . Les noms de propriété ou de valeur doivent être écrits tels quels sans rajouter d'espace.</p>
+
+<p><strong>A votre tour, ajoutez ou supprimez des espaces dans votre CSS pour voir dans quels cas rien ne change et dans quels cas tout est cassé.</strong></p>
+
+<h2 id="À_suivre...">À suivre... </h2>
+
+<p>Il est utile de comprendre, au moins dans les grandes lignes, comment votre navigateur calcule le rendu d'une page web à partir des fichiers HTML et CSS. Dans la prochaine leçon — <a href="/fr/docs/Learn/CSS/First_steps/How_CSS_works">Comment CSS fonctionne</a> — nous examinerons donc ce point.</p>
+
+<p>{{PreviousMenuNext("Learn/CSS/First_steps/Getting_started", "Learn/CSS/First_steps/How_CSS_works", "Learn/CSS/First_steps")}}</p>
+
+<h2 id="Dans_ce_cours">Dans ce cours</h2>
+
+<ol>
+ <li><a href="/fr/docs/Learn/CSS/First_steps/Qu_est_ce_que_CSS">Qu'est ce que CSS?</a></li>
+ <li><a href="/fr/docs/Learn/CSS/First_steps/Getting_started">Démarrer avec CSS</a></li>
+ <li><a href="/fr/docs/Learn/CSS/First_steps/How_CSS_is_structured">Comment CSS est structuré</a></li>
+ <li><a href="/fr/docs/Learn/CSS/First_steps/How_CSS_works">CSS comment ça marche ?</a></li>
+ <li><a href="/fr/docs/Learn/CSS/First_steps/Using_your_new_knowledge">Mettre en œuvre vos connaissances</a></li>
+</ol>
diff --git a/files/fr/learn/css/first_steps/how_css_works/index.html b/files/fr/learn/css/first_steps/how_css_works/index.html
new file mode 100644
index 0000000000..35f603c50d
--- /dev/null
+++ b/files/fr/learn/css/first_steps/how_css_works/index.html
@@ -0,0 +1,163 @@
+---
+title: 'CSS, comment ça marche ?'
+slug: Learn/CSS/First_steps/How_CSS_works
+tags:
+ - Apprendre
+ - CSS
+ - DOM
+ - Débutant
+translation_of: Learn/CSS/First_steps/How_CSS_works
+---
+<p>{{LearnSidebar}}<br>
+ {{PreviousMenuNext("Learn/CSS/First_steps/How_CSS_is_structured", "Learn/CSS/First_steps/Using_your_new_knowledge", "Learn/CSS/First_steps")}}</p>
+
+<p class="summary">Jusqu'ici, nous avons appris les bases du CCS, ses objectifs et comment écrire des feuilles de style élémentaires. Dans cette leçon, nous allons voir comment un navigateur prend du HTML et du CSS pour les transformer en une page web.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Prérequis :</th>
+ <td>Notions de base en l'informatique, <a href="/fr/docs/Apprendre/Commencer_avec_le_web/Installation_outils_de_base">logiciels de base installés</a>, <a href="/fr/docs/Apprendre/Commencer_avec_le_web/Gérer_les_fichiers">savoir manipuler des fichiers</a>, connaissance de base de HTML (cf. <a href="/fr/docs/Apprendre/HTML/Introduction_à_HTML">Introduction à HTML</a>.)</td>
+ </tr>
+ <tr>
+ <th scope="row">Objectif :</th>
+ <td>Comprendre, à un niveau élémentaire, comment un navigateur traite les codes CSS et HTML et ce qui se passe quand le navigateur rencontre du CSS qu'il ne sait pas interpréter.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="CSS_comment_ça_marche_en_fait">CSS comment ça marche, en  fait ?</h2>
+
+<p>Pour afficher un document, un navigateur doit combiner le contenu du document et les informations de mise en forme. Le traitement se fait en plusieurs phases que nous détaillons ci-dessous. Gardez à l'esprit que cette description est simplifiée, selon le modèle du navigateur, les étapes pourraient changer. Mais dans les grandes lignes, voilà ce qui se passe :</p>
+
+<ol>
+ <li>Le navigateur charge le HTML (par ex. il le reçoit à travers le réseau).</li>
+ <li>Il traduit le {{Glossary("HTML")}} en un {{Glossary("DOM")}} (<em>Document Object Model</em>) : une représentation du document HTML stockable en mémoire sur votre ordinateur. Nous expliquons le DOM plus en détails dans la prochaine section.</li>
+ <li>Le navigateur récupère ensuite la plupart des ressources attachées au document HTML, telles les images, les vidéos ajoutées à la page... et  la feuille CSS externe ! JavaScript est traité un peu plus tard et nous n'en parlerons pas ici pour simplifier la présentation.</li>
+ <li>Le navigateur <em>parse</em> le CSS, classe les différentes règles par types de sélecteur (par ex. élément, class, ID, etc...) dans des "buckets". En fonction des sélecteurs trouvés, le navigateur calcule quelle règle s'applique à quel nœud du DOM. Chaque nœud du DOM ciblé par CSS est étiqueté par sa règle de style. L'arbre ainsi obtenu s'appelle l'<em>arbre de rendu</em> (render tree).</li>
+ <li>Pour chaque nœud de l'arbre de rendu, le navigateur calcule l'effet visuel de la règle CSS associée.</li>
+ <li>Le visuel ainsi produit est affiché à l'écran (cette étape s'appelle <em>painting</em>).</li>
+</ol>
+
+<p>Le diagramme suivant propose une vue synthétique de ce traitement.</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/11781/rendering.svg" style="height: auto; max-width: 635px; width: 100%;"></p>
+
+<h2 id="À_propos_du_DOM">À propos du DOM</h2>
+
+<p>Tout DOM a une structure d'arbre. Chaque élément, attribut, bout de texte du langage de balises est traduit en un {{Glossary("Node/DOM","nœud du DOM")}} dans la structure en arbre. Les nœuds sont définis par leurs relations à d'autres nœuds du DOM. Certains éléments sont les <em>parents</em> de <em>nœuds enfants</em> (child nodes) et les nœuds enfants peuvent avoir des <em>frères et sœurs </em>(siblings).</p>
+
+<p>Comprendre le DOM vous aidera à concevoir, débugguer et maintenir votre CSS car le DOM est le point de jonction entre CSS et le contenu HTML du document.</p>
+
+<p>Avec les DevTools  de votre navigateur vous pourrez naviguer à travers le DOM en sélectionnant les items pour les inspecter et voir quelles règles s'appliquent sur eux.</p>
+
+<h2 id="Une_représentation_concrète_du_DOM">Une représentation concrète du DOM</h2>
+
+<p>Plutôt qu'une explication longue et ennuyeuse, regardons comment un fragment de code HTML est converti en un DOM.</p>
+
+<p>Partons du code ci-dessous :</p>
+
+<pre class="brush: html">&lt;p&gt;
+ Let's use:
+ &lt;span&gt;Cascading&lt;/span&gt;
+ &lt;span&gt;Style&lt;/span&gt;
+ &lt;span&gt;Sheets&lt;/span&gt;
+&lt;/p&gt;
+</pre>
+
+<p>Dans le DOM, le nœud correspondant à l'élément <code>&lt;p&gt;</code> est un parent. Ses enfants sont le nœud texte et trois nœuds associés aux éléments <code>&lt;span&gt;</code>. Les nœuds <code>SPAN</code> sont eux-mêmes parents, avec pour enfant le nœud associé à leur texte :</p>
+
+<pre>P
+├─ "Let's use:"
+├─ SPAN
+| └─ "Cascading"
+├─ SPAN
+| └─ "Style"
+└─ SPAN
+ └─ "Sheets"
+</pre>
+
+<p>C'est ainsi que le navigateur interprète notre fragment HTML—il transforme ce DOM en arbre de rendu puis affiche le résultat comme suit :</p>
+
+<p>{{EmbedLiveSample('A_real_DOM_representation', '100%', 55)}}</p>
+
+<div class="hidden">
+<pre class="brush: css">p {margin:0;}</pre>
+</div>
+
+<h2 id="Appliquer_CSS_au_DOM">Appliquer CSS au DOM</h2>
+
+<p>Supposons maintenant que nous avons ajouté du CSS à notre document pour le mettre en forme. Le HTML n'a pas changé :</p>
+
+<pre class="brush: html">&lt;p&gt;
+ Let's use:
+ &lt;span&gt;Cascading&lt;/span&gt;
+ &lt;span&gt;Style&lt;/span&gt;
+ &lt;span&gt;Sheets&lt;/span&gt;
+&lt;/p&gt;</pre>
+
+<p>On lui applique le CSS suivant :</p>
+
+<pre class="brush: css">span {
+ border: 1px solid black;
+ background-color: lime;
+}</pre>
+
+<p>Le navigateur parse le HTML, calcule son DOM, puis parse le CSS. Notre CSS a une unique règle avec un unique sélecteur <code>span</code>, ça va être rapide à trier ! La règle est attachée à chaque nœud <font face="consolas, Liberation Mono, courier, monospace"><span style="background-color: rgba(220, 220, 220, 0.5);">SPAN</span></font> du DOM pour obtenir l'arbre de rendu. Reste à calculer les rendus puis à <em>peindre</em> la représentation visuelle finale à l'écran.</p>
+
+<p>Voilà le résultat après mise à jour :</p>
+
+<p>{{EmbedLiveSample('Applying_CSS_to_the_DOM', '100%', 55)}}</p>
+
+<p>Dans le prochain module, dans l'article <a href="/en-US/docs/Learn/CSS/Building_blocks/Debugging_CSS">Debugging CSS</a>, nous utiliserons les DevTools du navigateur pour débuguer des erreurs CSS. Ce sera aussi l'occasion de mieux comprendre comment le navigateur interprète CSS.</p>
+
+<h2 id="Que_se_passe-t-il_quand_un_navigateur_rencontre_du_CSS_quil_ne_comprend_pas">Que se passe-t-il quand un navigateur rencontre du CSS qu'il ne comprend pas ?</h2>
+
+<p>Les navigateurs n'implémentent pas tous en même temps une fonctionnalité CSS nouvelle, j'avais mentionné ce fait <a href="/fr/docs/Learn/CSS/First_steps/Qu_est_ce_que_CSS#Prise_en_charge_par_les_navigateurs">dans une leçon précédente</a>. Rajoutez à cela le fait que trop de gens n'utilisent pas une version à jour de leur navigateur. CSS, lui, est en développement constant et donc toujours en avance par rapport à ce que les navigateurs peuvent implémenter. On doit donc se demander ce qui se passe quand un navigateur tombe sur un sélecteur ou une déclaration qu'il ne sait pas interpréter.</p>
+
+<p>La réponse : ne rien faire et passer à la suite !</p>
+
+<p>Quand un navigateur parse vos règles et rencontre une propriété ou une valeur qu'il ne comprend pas, il l'ignore et passe à la déclaration suivante. Cela se produit si vous avez mal orthographié le nom de la propriété ou de la valeur, ou s'ils sont trop nouveaux et pas encore pris en charge par le navigateur.</p>
+
+<p>De même quand le navigateur rencontre un sélecteur qu'il ne sait pas interpréter, il ignore la règle correspondante et passe à la suivante.</p>
+
+<p>Dans l'exemple ci-dessous, j'ai utilisé l'orthographe anglaise <code>colour</code> pour le mot <em>couleur.</em> Cela contredit la convention CSS et rend ce code incompréhensible pour le navigateur. En conséquence, le paragraphe n'a pas été colorié en bleu. Par contre, tout le reste du CSS est appliqué, seule la ligne invalide est ignorée.</p>
+
+<div id="Skipping_example">
+<pre class="brush: html">&lt;p&gt; Je veux que ce texte soit grand, gras et bleu.&lt;/p&gt;</pre>
+
+<pre class="brush: css">p {
+ font-weight: bold;
+ colour: blue; /* incorrect spelling of the color property */
+ font-size: 200%;
+}</pre>
+</div>
+
+<p>{{EmbedLiveSample('Skipping_example', '100%', 200)}}</p>
+
+<p>Le comportement décrit ci-dessus est très utile : vous pouvez utiliser du CSS récent pour perfectionner la mise en forme de vos pages, sachant qu'aucune erreur ne se produira quand votre code n'est pas compris — le navigateur interprète la règle... ou ne fait rien. Rappelez vous maintenant la <em>cascade</em> : entre deux règles de même spécificité, le navigateur choisira la dernière rencontrée. La cascade permet d'offrir une alternative pour les navigateurs qui ne prennent pas en charge le CSS le plus récent.</p>
+
+<p>Cela fonctionne particulièrement bien quand on désire utiliser une valeur CSS introduite récemment, pas encore prise en charge partout. Par exemple, quelques vieux navigateurs ne savent pas interpréter <code>calc()</code> pour les valeurs. Je peux donc donner une valeur en pixels pour la largeur de ma boîte, puis proposer une déclaration où la valeur de <code>width</code> est calculée par <code>calc(</code><code>)</code>. Un vieux navigateur interprète la première déclaration, il ne comprend pas la seconde, il l'ignore — il utilisera donc la version pixels. Les navigateurs récents interprètent la déclaration en pixels, puis celle avec  <code>calc()</code> qui, par cascade, écrase la déclaration précédente.</p>
+
+<pre class="brush: css">.box {
+ width: 500px;
+ width: calc(100% - 50px);
+}</pre>
+
+<p>Dans les leçons à venir, nous rencontrerons d'autres méthodes pour adapter le code aux différents navigateurs.</p>
+
+<h2 id="Et_enfin">Et enfin</h2>
+
+<p>Ce cours est presque achevé ; il nous reste un seul point à voir. Dans la prochaine leçon, vous allez <a href="/fr/docs/Learn/CSS/First_steps/Using_your_new_knowledge">mettre en œuvre vos nouvelles connaissances</a> : vous allez remettre en forme un exemple, une occasion d'appliquer tout ce que vous avez appris de CSS.</p>
+
+<p>{{PreviousMenuNext("Learn/CSS/First_steps/How_CSS_is_structured", "Learn/CSS/First_steps/Using_your_new_knowledge", "Learn/CSS/First_steps")}}</p>
+
+<h2 id="Dans_ce_cour">Dans ce cour</h2>
+
+<ol>
+ <li><a href="/fr/docs/Learn/CSS/First_steps/What_is_CSS">CSS, c'est quoi ?</a></li>
+ <li><a href="/fr/docs/Learn/CSS/First_steps/Getting_started">Démarrer avec CSS</a></li>
+ <li><a href="/fr/docs/Learn/CSS/First_steps/How_CSS_is_structured">Comment CSS est structuré</a></li>
+ <li><a href="/fr/docs/Learn/CSS/First_steps/How_CSS_works">CSS ça marche comment ?</a></li>
+ <li><a href="/fr/docs/Learn/CSS/First_steps/Using_your_new_knowledge">Mettre en œuvre vos nouvelles connaissances</a></li>
+</ol>
diff --git a/files/fr/learn/css/first_steps/index.html b/files/fr/learn/css/first_steps/index.html
new file mode 100644
index 0000000000..040887386c
--- /dev/null
+++ b/files/fr/learn/css/first_steps/index.html
@@ -0,0 +1,63 @@
+---
+title: Premiers pas avec CSS
+slug: Learn/CSS/First_steps
+tags:
+ - Apprendre
+ - CSS
+ - Débutant
+ - Module
+ - premiers pas
+translation_of: Learn/CSS/First_steps
+---
+<div>{{LearnSidebar}}</div>
+
+<div class="text-wrap tlid-copy-target">
+<div class="result-shield-container tlid-copy-target"><span class="tlid-translation translation" lang="fr"><span title="">CSS (Cascading Style Sheets ou en français "Feuilles de style en cascade") est utilisé pour styliser et mettre en page des pages Web - par exemple, pour modifier la police, la couleur, la taille et l'espacement de votre contenu, le scinder en plusieurs colonnes ou ajouter des animations et autres éléments décoratifs.</span> <span title="">Ce module vous permet de commencer en douceur votre chemin vers la maîtrise de CSS avec les bases de son fonctionnement, de sa syntaxe et de la façon dont vous pouvez commencer à l'utiliser pour ajouter du style au HTML.</span></span></div>
+</div>
+
+<div class="in-page-callout webdev">
+<h3 id="Vous_voulez_devenir_un_développeur_web_front-end">Vous voulez devenir un développeur web front-end ?</h3>
+
+<p>Nous avons mis au point un cours qui comprend toutes les informations essentielles dont vous avez besoin pour atteindre votre objectif.</p>
+
+<p><a class="cta primary" href="/docs/Learn/Front-end_web_developer">Commencer</a></p>
+</div>
+
+<h2 id="Prérequis">Prérequis</h2>
+
+<p>Avant de commencer ce module, vous devriez avoir :</p>
+
+<ol>
+ <li>Une connaissance basique de l'utilisation d'un ordinateur, et l'utilisation passive du Web (i.e. consulter des sites, consommer le contenu s'y trouvant) ;</li>
+ <li>Un environnement de travail minimal installé, comme indiqué dans la section <a href="/fr/docs/Apprendre/Commencer_avec_le_web/Installation_outils_de_base">installer les logiciels de base</a> et une compréhension de la façon de créer et gérer des fichiers, comme indiqué dans la section <a href="/fr/docs/Apprendre/Commencer_avec_le_web/Gérer_les_fichiers">Gérer les fichiers</a> ;</li>
+ <li>Une familiarité avec HTML, comme discuté dans le module d'<a href="/fr/docs/Apprendre/HTML/Introduction_à_HTML">introduction à HTML</a>.</li>
+</ol>
+
+<div class="note">
+<p><strong>Note </strong>: Si vous travaillez sur un ordinateur / tablette / autre périphérique où vous n'avez pas la possibilité de créer vos propres fichiers, vous pouvez essayer (la plupart) des exemples de code sur des sites de programmation en ligne comme <a href="/fr/docs/">JSBin</a> ou <a href="/fr/docs/">Thimble</a>.</p>
+</div>
+
+<h2 id="Guides">Guides</h2>
+
+<p>Ce module contient les articles suivants, qui vous présenteront les bases théoriques du CSS et vous fourniront des occasions de mettre en pratique vos nouvelles compétences :</p>
+
+<dl>
+ <dt><a href="/fr/docs/Learn/CSS/First_steps/Qu_est_ce_que_CSS">Qu'est-ce que le CSS?</a></dt>
+ <dd><strong>{{Glossary("CSS")}}</strong> (Cascading Style Sheets) permet de créer de superbes pages web, mais comment fonctionne-t-il sous le capot ? Cet article explique ce qu'est le CSS à l'aide d'un exemple de syntaxe simple et couvre également quelques-uns des termes clés du langage.</dd>
+ <dt><a href="/fr/docs/Learn/CSS/First_steps/Getting_started">Démarrer avec CSS</a></dt>
+ <dd>Dans cet article, nous partirons d'un document HTML simple et y appliquerons des CSS, tout en apprenant des choses pratiques sur le langage.</dd>
+ <dt><a href="/fr/docs/Learn/CSS/First_steps/How_CSS_is_structured">Comment est structuré le CSS </a></dt>
+ <dd>Maintenant que vous avez une idée sur ce qu'est le CSS et les bases de son utilisation, il est temps de regarder plus précisement la structure du langage lui-même. Nous avons déjà rencontré de nombreux concepts discutés ici ; vous pouvez vous référer à cette section pour référence si vous rencontrez des difficultés de compréhension des concepts plus avancés.</dd>
+ <dt><a href="/fr/docs/Learn/CSS/First_steps/How_CSS_works">Comment CSS Fonctionne</a></dt>
+ <dd>Nous avons appris les bases de CSS, ce qu'il est et comment écrire des feuilles de style simple. Dans cette leçon, nous étudierons comment un navigateur transforme CSS et HTML en une page web.</dd>
+ <dt><a href="/fr/docs/Learn/CSS/First_steps/Using_your_new_knowledge">Utilisez vos nouvelles compétences</a></dt>
+ <dd>Avec toutes les choses que vous avez apprises dans les dernières leçons, vous devriez être capable de formater des documents textuels simples en utilisant CSS et y ajouter votre propre style. Cet article vous permet d'expérimenter.</dd>
+ <dd></dd>
+</dl>
+
+<h2 id="Voir_aussi">Voir aussi</h2>
+
+<dl>
+ <dt>Literacy<a href="/fr/docs/"> Web intermédiaire 1 : Introduction au CSS</a></dt>
+ <dd><span class="tlid-translation translation" lang="fr"><span title="">Un excellent cours de base de la fondation Mozilla qui explore et teste de nombreuses compétences évoquées dans le module <em>Introduction à CSS</em>.</span> Approfondissements à propos de<span title=""> l'application de styles sur les éléments HTML d'une page Web, les sélecteurs CSS, les attributs et valeurs.P</span></span></dd>
+</dl>
diff --git a/files/fr/learn/css/first_steps/qu_est_ce_que_css/index.html b/files/fr/learn/css/first_steps/qu_est_ce_que_css/index.html
new file mode 100644
index 0000000000..0b4bfefc33
--- /dev/null
+++ b/files/fr/learn/css/first_steps/qu_est_ce_que_css/index.html
@@ -0,0 +1,132 @@
+---
+title: Qu'est ce que CSS ?
+slug: Learn/CSS/First_steps/Qu_est_ce_que_CSS
+tags:
+ - Apprendre
+ - CSS
+ - Débutant
+ - Modules
+ - Specifications
+ - Syntaxe
+translation_of: Learn/CSS/First_steps/What_is_CSS
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{NextMenu("Learn/CSS/First_steps/Getting_started", "Learn/CSS/First_steps")}}</div>
+
+<p class="summary"><strong>{{Glossary("CSS")}}</strong> (<em>Cascading Style Sheets</em>) permet de créer des pages web à l'apparence soignée. Cet article vous propose de lever le voile en expliquant ce qu'est CSS ; un exemple simple en présentera la syntaxe puis quelques termes clé du langage seront introduits.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Prérequis :</th>
+ <td>Notions de base en l'informatique, <a href="/fr/docs/Apprendre/Commencer_avec_le_web/Installation_outils_de_base">logiciels de base installés</a>, <a href="/fr/docs/Apprendre/Commencer_avec_le_web/Gérer_les_fichiers">savoir manipuler des fichiers</a>, connaissance de base de HTML (cf. <a href="/fr/docs/Apprendre/HTML/Introduction_à_HTML">Introduction à HTML</a>.)</td>
+ </tr>
+ <tr>
+ <th scope="row">Objectif :</th>
+ <td>Apprendre ce qu'est CSS.</td>
+ </tr>
+ </tbody>
+</table>
+
+<p>Dans le cours <a href="/fr/docs/Apprendre/HTML/Introduction_à_HTML">Introduction à HTML</a>, nous avons présenté le langage HTML et comment l'utiliser afin de rédiger des documents structurés. Ces documents seront consultables dans un navigateur. Les titres apparaîtront dans une police plus grande que le corps de texte, la rupture entre deux paragraphes sera marquée par un saut de ligne. Les liens seront soulignés et colorés pour les distinguer du reste du texte. L'image ci-dessous montre comment un navigateur affiche un document HTML — la mise en forme par défaut garantit un minimum de lisibilité, même si l'auteur de la page n'a spécifié aucune règle de style.</p>
+
+<p><img alt="La mise en forme par défaut appliquée par un navigateur." src="https://mdn.mozillademos.org/files/17059/basic_styling_fr.png" style="border: 1px solid #cccccc; height: 232px; width: 953px;"></p>
+
+<p>Le Web serait d'un ennui terrible si tous les sites ressemblaient à la page ci-dessus. Grâce à CSS, vous pouvez contrôler exactement l'affichage de chaque élément HTML dans le navigateur et ainsi présenter vos documents avec la mise en forme de votre choix.</p>
+
+<p>Pour plus d'informations sur les styles de navigateur/par défaut, consultez la vidéo suivante :</p>
+
+<p>{{EmbedYouTube("spK_S0HfzFw")}}</p>
+
+<h2 id="À_quoi_sert_CSS">À quoi sert CSS ?</h2>
+
+<p>Comme mentionné plus haut, CSS est un langage de mise en forme des documents. </p>
+
+<p>Les <strong>documents</strong> en question sont des fichiers texte structurés avec un langage de balises — {{Glossary("HTML")}} est le plus connu de ces langages, d'autres exemples sont {{Glossary("SVG")}} ou {{Glossary("XML")}}.</p>
+
+<p><strong>"Présenter</strong> un document à l'utilisateur" signifie convertir ce document dans une forme utilisable par le public visé. Les {{Glossary("browser","navigateurs")}}, tels {{Glossary("Mozilla Firefox","Firefox")}}, {{Glossary("Google Chrome","Chrome")}}, {{Glossary("Safari","Safari")}} ou {{Glossary("Microsoft Edge","Edge")}} sont conçus pour présenter visuellement des documents, que ce soit sur l'écran d'un ordinateur, un vidéo-projecteur ou une imprimante.</p>
+
+<div class="blockIndicator note">
+<p><strong>Note </strong>: Un navigateur est parfois appelé {{Glossary("User agent","agent utilisateur")}}. On entend par là un programme informatique qui agit pour un utilisateur au sein d'un système informatique. Pour CSS, les premiers agents utilisateur qui nous viennent à l'esprit sont les navigateurs. Ce ne sont pourtant pas les seuls. Il existe d'autres "agents utilisateurs" comme les programmes qui convertissent des documents  HTML et CSS en documents PDF imprimables.</p>
+</div>
+
+<p>CSS peut être utilisé pour une mise en forme élémentaire des documents — par exemple changer <a href="/fr/docs/Web/CSS/Type_color">la couleur</a> et <a href="/fr/docs/Web/CSS/font-size">la taille</a> des titres et des liens. Il peut être utilisé pour concevoir une maquette — par exemple transformer <a href="/fr/docs/Web/CSS/Layout_cookbook/Disposition_en_colonnes">un texte affiché sur une colonne</a> en une composition avec un cadre principal et une barre latérale pour les informations reliées. Avec CSS, on peut aussi produire des <a href="/fr/docs/Web/CSS/Animations_CSS">animations</a>. N'hésitez pas à cliquer sur les liens de ce paragraphe pour observer différents exemples.</p>
+
+<h2 id="Syntaxe_de_CSS">Syntaxe de CSS</h2>
+
+<p>CSS est un langage basé sur des règles — on définit des règles de styles destinées à des éléments ou des groupes d'éléments particuliers dans la page.</p>
+
+<p>Par exemple "Je veux que le titre principal de ma page s'affiche en rouge en gros caractères."</p>
+
+<p>Dans le code suivant, une règle CSS élémentaire réalise cette mise en forme :</p>
+
+<pre class="brush: css notranslate">h1 {
+ color: red;
+ font-size: 5em;
+}</pre>
+
+<p>La règle commence par un {{Glossary("CSS Selector", "sélecteur")}}, l'élément HTML mis en forme. Ici le style s'applique aux titres de niveau 1 ({{htmlelement("h1")}}).</p>
+
+<p>Suivent une paire d'accolades <code>{ }</code> à l'intérieur desquelles on trouve une ou plusieurs <strong>déclarations</strong>, sous la forme d'une paire <strong>propriété</strong> : <strong>valeur</strong>. Chaque paire précise une propriété de l'élément sélectionné, suivie de la valeur choisie pour cette propriété ; la propriété et la valeur sont séparées par deux points. Chaque déclaration se termine par un point-virgule. À chaque {{Glossary("property/CSS","propriété")}} définie par CSS correspondent différentes valeurs possibles. Dans l'exemple, la propriété <code>color</code> peut prendre différentes <a href="/fr/docs/Learn/CSS/Building_blocks/Values_and_units#Color">valeurs de type <code>&lt;color&gt;</code></a>. La propriété <code>font-size</code> accepte différentes <a href="/fr/docs/Learn/CSS/Building_blocks/Values_and_units#Numbers_lengths_and_percentages">tailles</a> comme valeurs.</p>
+
+<p>Une feuille de style CSS est constituée d'une succession de telles règles :</p>
+
+<pre class="brush: css notranslate">h1 {
+ color: red;
+ font-size: 5em;
+}
+
+p {
+ color: black;
+}</pre>
+
+<p>On retient facilement certaines valeurs, d'autres sont plus difficiles à mémoriser. Pour s'y retrouver, sur MDN, la page individuelle de chaque propriété donne un aperçu rapide et complet des valeurs applicables.</p>
+
+<div class="blockIndicator note">
+<p><strong>Note :</strong> Sur MDN, dans <a href="/fr/docs/Web/CSS/Reference">la référence CSS</a>, vous trouverez une collection de liens à propos de chaque propriété CSS (ainsi que d'autres aspects de CSS). Par ailleurs, n'hésitez pas à lancer des requêtes "mdn <em>nom-de-propriété-ou-fonctionnalité-css</em>" dans votre moteur de recherche préféré dès qu'un aspect de CSS vous interpelle. Vous pouvez par exemple tester les requêtes "mdn color" et "mdn font-size" !</p>
+</div>
+
+<h2 id="Modules_CSS">Modules CSS</h2>
+
+<p>L'ensemble des fonctionnalités CSS est si important que le langage et ses spécifications ont été découpés en <em>modules</em>. En naviguant dans le site MDN vous croiserez ces modules : quand des pages de documentation sont regroupées, c'est la plupart du temps qu'elles réfèrent à un même module. Par exemple, jetez un œil à la référence MDN pour le module <em><a href="/fr/docs/Web/CSS/CSS_Backgrounds_and_Borders">Backgrounds and Borders</a></em>, vous y trouverez ce pour quoi il a été conçu, les différentes propriétés et fonctionnalités qu'il regroupe. Vous trouverez aussi des liens vers la spécification CSS qui définit cette technologie (voir plus bas).</p>
+
+<p>À ce stade, inutile de se préoccuper de la structure de CSS (même s'il est parfois plus simple de trouver une information quand on a compris qu'une propriété est reliée à une famille d'autres propriétés au sein d'un même module de spécification).</p>
+
+<p>Prenons un exemple précis et revenons au module <em>Backgrounds and Borders</em> — les propriétés <code><a href="/fr/docs/Web/CSS/background-color">background-color</a></code> et <code><a href="/fr/docs/Web/CSS/border-color">border-color</a></code> qui agissent sur l'arrière-plan et les bordures appartiennent toutes les deux à ce module.</p>
+
+<h3 id="Spécifications_CSS">Spécifications CSS</h3>
+
+<p>Chaque technologie standard du Web (HTML, CSS, JavaScript, etc.) est définie dans un grand document appelé spécification (parfois abrégé en "spec"). Les spécifications sont publiées par des organisations de standardisation (telles que le {{glossary("W3C")}}, {{glossary("WHATWG")}}, {{glossary("ECMA")}}, ou {{glossary("Khronos")}}), elles définissent précisément le comportement attendu de ces technologies.</p>
+
+<p>CSS ne déroge pas à la règle — il est développé par un groupe au sein du W3C, nommé le <a href="https://www.w3.org/Style/CSS/"><em>CSS Working Group</em> (ou "groupe de travail CSS" en français)</a>. Ce groupe est constitué de représentants des éditeurs de navigateurs et d'autres sociétés concernées par CSS. On y trouve aussi des <em>experts invités </em>affiliés à aucune des organisations membres qui apporte une voix indépendante à la conception de CSS.</p>
+
+<p>De nouveaux aspects de CSS sont développés ou spécifiés par le groupe de travail CSS, parfois parce qu'un navigateur particulier désire tel comportement, d'autres fois parce que des concepteurs web et des développeurs demandent certaines fonctionnalités et enfin parfois lorsque le <em>CSS Working Group</em> a identifié un besoin. CSS est en développement constant, avec de nouvelles fonctionnalités disponibles au fur et à mesure. Une des caractéristiques cruciale de chaque brique du Web et donc de CSS est la rétro-compatibilité : chaque contributeur s'attache à garantir qu'un site web développé en 2000 avec le CSS disponible à l'époque sera toujours utilisable dans un navigateur actuel ! </p>
+
+<p>Si vous débutez en CSS, la lecture des spécifications peut être déroutante : elles s'adressent avant tout aux ingénieurs qui implémentent la prise en charge dans les navigateurs et pas aux développeurs web qui doivent comprendre les propriétés pour les utiliser dans leurs sites. Dans ce cas, la documentation MDN ou d'autres tutoriels sont recommandés. Il est pourtant important de savoir que les spécifications existent, de comprendre la relation entre celles-ci, le CSS que vous utilisez et la prise en charge des navigateurs (voir ci-dessous).</p>
+
+<h2 id="Prise_en_charge_par_les_navigateurs">Prise en charge par les navigateurs</h2>
+
+<p>Les fonctionnalités CSS définies dans les spécifications peuvent uniquement être utilisées dans une page web si un ou plusieurs navigateurs les implémentent. Autrement dit, il faut bien qu'il y ait un programme qui puisse transformer les règles CSS en éléments affichés à l'écran.</p>
+
+<p>Nous étudierons ce point plus en détail dans l'article sur <a href="/fr/docs/Learn/CSS/First_steps/How_CSS_works">le fonctionnement de CSS</a>. Il est rare que les différents navigateurs implémentent simultanément une nouvelle fonctionnalité CSS. Il est donc fréquent que certains sous-ensembles de CSS soient fonctionnels pour certains navigateurs et pas pour d'autres. Pour cette raison, il est essentiel de vérifier l'état de la compatibilité et des implémentations. Sur chaque page MDN décrivant une propriété, le statut d'implémentation de la propriété est fourni dans un tableau de compatibilité web. Vous saurez ainsi s'il est pertinent de l'utiliser dans votre site web.</p>
+
+<p>Voici par exemple le tableau de compatibilité pour la propriété <code><a href="/fr/docs/Web/CSS/font-family">font-family</a></code>.</p>
+
+<p>{{Compat("css.properties.font-family")}}</p>
+
+<h2 id="Où_continuer">Où continuer</h2>
+
+<p>Maintenant que vous avez compris ce qu'est CSS, vous pourrez commencer à écrire vos premières règles de style dans la leçon <a href="/fr/docs/Learn/CSS/First_steps/Getting_started">Démarrer avec CSS</a>.</p>
+
+<p>{{NextMenu("Learn/CSS/First_steps/Getting_started", "Learn/CSS/First_steps")}}</p>
+
+<h2 id="Dans_ce_cours">Dans ce cours</h2>
+
+<ol>
+ <li><a href="/fr/docs/Learn/CSS/First_steps/Qu_est_ce_que_CSS">Qu'est-ce que CSS ?</a></li>
+ <li><a href="/fr/docs/Learn/CSS/First_steps/Getting_started">Démarrer avec CSS</a></li>
+ <li><a href="/fr/docs/Learn/CSS/First_steps/How_CSS_is_structured">La façon dont CSS est structuré</a></li>
+ <li><a href="/fr/docs/Learn/CSS/First_steps/How_CSS_works">Le fonctionnement de CSS</a></li>
+ <li><a href="/fr/docs/Learn/CSS/First_steps/Using_your_new_knowledge">Mettre en œuvre vos nouvelles connaissances</a></li>
+</ol>
diff --git a/files/fr/learn/css/first_steps/using_your_new_knowledge/index.html b/files/fr/learn/css/first_steps/using_your_new_knowledge/index.html
new file mode 100644
index 0000000000..c49978ebb6
--- /dev/null
+++ b/files/fr/learn/css/first_steps/using_your_new_knowledge/index.html
@@ -0,0 +1,106 @@
+---
+title: Mettre en œuvre vos connaissances
+slug: Learn/CSS/First_steps/Using_your_new_knowledge
+tags:
+ - Apprendre
+ - CSS
+ - Débutant
+ - Playground
+translation_of: Learn/CSS/First_steps/Using_your_new_knowledge
+---
+<p>{{LearnSidebar}}{{PreviousMenu("Learn/CSS/First_steps/How_CSS_works", "Learn/CSS/First_steps")}}</p>
+
+<p class="summary">Le temps est venu d'évaluer tout ce que vous avez appris dans les leçons précécentes : vous savez comment mettre en forme des documents texte simples à l'aide de CSS. </p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Prérequis :</th>
+ <td>Avant de vous soumettre à cette évaluation, vous avez suivi le module sur les bases de CSS ; vous maîtrisez par ailleurs les bases de HTML (cf. <a href="/fr/docs/Apprendre/HTML/Introduction_à_HTML">Introduction à HTML</a>).</td>
+ </tr>
+ <tr>
+ <th scope="row">Objectif :</th>
+ <td>Tester vos connaissances en mettant à l'œuvre CSS.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Point_de_départ">Point de départ</h2>
+
+<p>Vous pouvez travailler dans l'éditeur ci-dessous ou <a href="https://github.com/mdn/css-examples/blob/master/learn/getting-started/biog-download.html/">télécharger le point de départ</a> pour travailler en local sur votre machine, avec votre propre éditeur de code.  Ce point de départ est une page HTML avec le CSS interne écrit dans la section <code>&lt;head&gt;</code>. Sur votre machine, n'hésitez pas à travailler avec une feuille de style externe. Vous pouvez aussi utiliser des éditeurs en ligne comme <a href="https://codepen.io/" rel="noopener">CodePen</a>, <a href="https://jsfiddle.net/" rel="noopener">jsFiddle</a>, ou <a href="https://glitch.com/" rel="noopener">Glitch</a> pour travailler sur les tâches proposées.</p>
+
+<div class="blockIndicator note">
+<p><strong>Note </strong>: ne restez pas coincé, appelez à l'aide — voir la section <a href="#evaluation">Evaluation et comment obtenir de l'aide</a> au bas de cette page.</p>
+</div>
+
+<h2 id="Travailler_avec_CSS">Travailler avec CSS</h2>
+
+<p>L'exemple ci-dessous propose de retravailler la mise en forme d'une biographie stylée avec CSS. Les propriétés utilisées sont les suivantes — chacune renvoie vers sa page MDN pour plus d'exemples d'usages :</p>
+
+<ul>
+ <li>{{cssxref("font-family")}}</li>
+ <li>{{cssxref("color")}}</li>
+ <li>{{cssxref("border-bottom")}}</li>
+ <li>{{cssxref("font-weight")}}</li>
+ <li>{{cssxref("font-size")}}</li>
+ <li>{{cssxref("text-decoration")}}</li>
+</ul>
+
+<p>J'ai utilisé un mélange de sélecteurs, d'éléments HTML comme <code>h1</code> et <code>h2</code> ; j'ai aussi créé une classe <code>job-title</code>.</p>
+
+<p>Utilisez CSS pour changer l'apparence de cette biographie en modifiant les valeurs des propriétés CSS utilisées :</p>
+
+<ol>
+ <li>Affichez le titre de niveau 1 en <code>hotpink</code> ;</li>
+ <li> Donnez au titre un {{cssxref("border-bottom")}} de <code>10px dotted</code> de couleur <code>purple</code> ;</li>
+ <li>Affichez le titre de niveau 2 en italique ;</li>
+ <li>Colorez la <code>ul</code> des détails de contacts en {{cssxref("background-color")}} <code>#eeeeee</code>, avec un {{cssxref("border")}} de <code>5px solid purple</code>. Utilisez la propriété {{cssxref("padding")}} pour éloigner le contenu du bord.</li>
+ <li>Faites que les liens apparaissent en <code>green</code> lors d'un survol du curseur.</li>
+</ol>
+
+<p>Vous devriez obtenir un rendu qui ressemble à cela :</p>
+
+<p><img alt="Screenshot of how the example should look after completing the assessment." src="https://mdn.mozillademos.org/files/17035/learn-css-basics-assessment.png" style="height: 1199px; width: 1104px;"></p>
+
+<p>Une fois cette tâche accomplie, n'hésitez pas à explorer des propriétés rencontrées dans la <a href="/fr/docs/Web/CSS/Reference">référence CSS sur MDN</a> !</p>
+
+<p>À ce stade, il n'y a pas de réponse incorrecte — autorisez vous un peu de fantaisie.</p>
+
+<p>{{EmbedGHLiveSample("css-examples/learn/getting-started/biog.html", '100%', 1600)}} </p>
+
+<h2 id="Evaluation_ou_compléments_dinformation"><a id="evaluation" name="evaluation">Evaluation ou compléments d'information</a></h2>
+
+<p>Si vous voulez une évaluation de votre travail, ou si vous êtes coincé et recherchez de l'aide :</p>
+
+<ol>
+ <li>Publiez votre code dans un éditeur en ligne tel <a href="https://codepen.io/" rel="noopener">CodePen</a>, <a href="https://jsfiddle.net/" rel="noopener">jsFiddle</a>, or <a href="https://glitch.com/" rel="noopener">Glitch</a>.</li>
+ <li>Si vous êtes à l'aise en anglais :
+ <ol>
+ <li>Dans le <a href="https://discourse.mozilla.org/c/mdn" rel="noopener">forum MDN Discourse</a>, écrivez un billet pour évaluation et/ou demande d'aide. Ajouter le tag "learning"  à votre post pour que nous puissions le trouver plus facilement. Votre post devrait contenir :
+ <ul>
+ <li>Un titre parlant comme "Assessment wanted for CSS First Steps".</li>
+ <li>Des détails sur ce que vous voudriez que l'on fasse — par exemple, ce que vous avez déjà essayé si vous êtes coincé et demandez de l'aide.</li>
+ <li>Un lien vers l'exemple dans l'éditeur en ligne, sur lequel vous demandez une évaluation ou de l'aide : voilà une bonne pratique — il n'est pas commode d'aider quelqu'un coincé sur son code quand on ne peut pas voir ce code...</li>
+ <li>Un lien vers cette page d'évaluation afin que nous puissions voir la question sur laquelle vous demandez de l'aide.</li>
+ </ul>
+ </li>
+ </ol>
+ </li>
+ <li>Sinon, n'hésitez pas à contacter @MDNfr sur Twitter.</li>
+</ol>
+
+<h2 id="La_suite">La suite ?</h2>
+
+<p>Bravo, vous avez suivi ce cours jusqu'au bout. Avec votre connaissance de CSS, vous comprenez maintenant le fonctionnement d'une feuille de style. Dans le prochain cours, <a href="/fr/docs/Apprendre/CSS/Building_blocks">construire des blocs CSS</a>, nous approfondirons de nombreux points.</p>
+
+<p>{{PreviousMenu("Learn/CSS/First_steps/How_CSS_works", "Apprendre/CSS/Premiers_pas")}}</p>
+
+<h2 id="Dans_ce_cours">Dans ce cours</h2>
+
+<ol>
+ <li><a href="/fr/docs/Learn/CSS/First_steps/Qu_est_ce_que_CSS">Qu'est-ce que CSS ?</a></li>
+ <li><a href="/fr/docs/Learn/CSS/First_steps/Getting_started">Commencer avec CSS</a></li>
+ <li><a href="/fr/docs/Learn/CSS/First_steps/How_CSS_is_structured">Comment CSS est structuré</a></li>
+ <li><a href="/fr/docs/Learn/CSS/First_steps/How_CSS_works">CSS, comment ça marche ?</a></li>
+ <li><a href="/fr/docs/Learn/CSS/First_steps/Using_your_new_knowledge">Mettez en œuvre vos connaissances</a></li>
+</ol>
diff --git a/files/fr/learn/css/styling_text/index.html b/files/fr/learn/css/styling_text/index.html
new file mode 100644
index 0000000000..57d52b0b06
--- /dev/null
+++ b/files/fr/learn/css/styling_text/index.html
@@ -0,0 +1,50 @@
+---
+title: Introduction au style de texte
+slug: Learn/CSS/Styling_text
+tags:
+ - CSS
+ - Débutant
+ - Liens
+ - Listes
+ - Mise en page
+ - Module
+ - Polices de caractères
+ - Style
+ - Texte
+translation_of: Learn/CSS/Styling_text
+---
+<div> </div>
+
+<p class="summary"><span id="result_box" lang="fr"><span>Une fois acquises les bases du langage CSS, la prochaine étape pour vous est la mise en forme de texte, une des choses les plus commune mais essentielle du CSS.</span></span><span lang="fr"> Nous étudierons ici les principes de base de la mise en forme de texte : choix de polices de caractères, gras ou italique, interlignes et espacement de caractères, ajouter des ombres et autres fonctionnalités. <span>Nous terminerons le module en détaillant l'intégration de polices personnalisées à votre page, ainsi que la mise en forme de listes et de liens.</span></span></p>
+
+<h2 id="Prérequis">Prérequis</h2>
+
+<p>Avant de commencer ce module, vous devez déjà être familiarisé avec les bases de HTML proposées dans <a href="https://developer.mozilla.org/fr/Apprendre/HTML/Introduction_%C3%A0_HTML">Introduction à HTML</a>, et être à l'aise avec les fondamentaux de CSS étudiés dans <a href="https://developer.mozilla.org/fr/Apprendre/CSS/Introduction_%C3%A0_CSS">Introduction à CSS</a>.</p>
+
+<div class="note">
+<p><strong>Note</strong> : Si vous travaillez sur un ordinateur/tablette/autre appereil sur lequel vous ne pouvez pas créer vos propres fichiers, <span id="result_box" lang="fr"><span>vous pouvez essayer (la plupart) des exemples de code dans un programme de codage en ligne tels que</span></span> <a href="http://jsbin.com/">JSBin</a> ou <a href="https://thimble.mozilla.org/">Thimble</a>.</p>
+</div>
+
+<h2 id="Guides">Guides</h2>
+
+<p>Ce module contient les articles suivants, qui vous éclaireront sur les méthodes essentielles de mise en forme de contenu HTML :</p>
+
+<dl>
+ <dt><a href="https://developer.mozilla.org/fr/docs/Learn/CSS/Styling_text/initiation-mise-en-forme-du-texte">Initiation à la mise en forme du texte</a></dt>
+ <dd><span id="result_box" lang="fr"><span>Dans cet article, nous passons en revue toutes les bases du style de texte et de police de caractères, y compris le poids de la police, la famille et le style, les raccourcis, l'alignement du texte et d'autres effets, ainsi que l'espacement des lignes et des lettres.</span></span></dd>
+ <dt><a href="https://developer.mozilla.org/fr/docs/Learn/CSS/Styling_text/Styling_lists">Style de liste</a></dt>
+ <dd><span id="result_box" lang="fr"><span>Les listes se comportent comme la plupart des autres textes, mais il existe des propriétés CSS spécifiques aux listes que vous devez connaître, ainsi que quelques bonnes pratiques à prendre en compte.</span> <span>Cet article explique tout.</span></span></dd>
+ <dt><a href="https://developer.mozilla.org/fr/docs/Learn/CSS/Styling_text/Styling_links">Style de lien</a></dt>
+ <dd><span id="result_box" lang="fr"><span>Pour définir un style de liens, il est important de comprendre comment utiliser les pseudo-classes, pour styliser efficacement les états des liens, et comment créer des liens pour les utiliser dans des fonctionnalités d'interface variées communes telles que les menus de navigation et les onglets.</span> <span>Nous examinerons tous ces sujets dans cet article.</span></span></dd>
+ <dt><a href="https://developer.mozilla.org/fr/docs/Learn/CSS/Styling_text/Web_fonts">Polices de caractères web</a></dt>
+ <dd><span id="result_box" lang="fr"><span>Ici, nous allons explorer les polices web en détail - celles-ci vous permettent de télécharger des polices personnalisées sur votre page web, pour vous donner des styles de texte plus variés et personnalisés.</span></span></dd>
+</dl>
+
+<h2 id="Auto-évaluation">Auto-évaluation</h2>
+
+<p>Les auto-évaluations suivantes testeront votre compréhension des techniques de style de texte abordées dans les guides ci-dessus.</p>
+
+<dl>
+ <dt><a href="https://developer.mozilla.org/fr/docs/Learn/CSS/Styling_text/Typesetting_a_homepage">Composition d'une page d'accueil d'une école communale</a></dt>
+ <dd>Dans cette auto-évaluation, nous testerons votre compréhension du style de texte <span id="result_box" lang="fr"><span>en vous amenant à créer le style du texte de la page d'accueil d'une école communale.</span></span></dd>
+</dl>
diff --git a/files/fr/learn/css/styling_text/initiation-mise-en-forme-du-texte/index.html b/files/fr/learn/css/styling_text/initiation-mise-en-forme-du-texte/index.html
new file mode 100644
index 0000000000..283d1fff00
--- /dev/null
+++ b/files/fr/learn/css/styling_text/initiation-mise-en-forme-du-texte/index.html
@@ -0,0 +1,756 @@
+---
+title: Initiation à la mise en forme du texte
+slug: Learn/CSS/Styling_text/initiation-mise-en-forme-du-texte
+tags:
+ - Alignement
+ - CSS
+ - Débutant
+ - Guide
+ - Polices de caractères
+ - Style
+ - Texte
+translation_of: Learn/CSS/Styling_text/Fundamentals
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{NextMenu("Learn/CSS/Styling_text/Styling_lists", "Learn/CSS/Styling_text")}}</div>
+
+<p class="summary">Dans cet article, nous allons commencer le voyage vers la maîtrise des styles du texte avec {{glossary("CSS")}}. Nous passerons en revue les principes de base de mise en forme du texte, y compris la graisse, la famille et le style de police, les codes d'abréviation, l'alignement du texte et autres effets, ainsi que l'espacement des lignes et des lettres.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Prérequis :</th>
+ <td>Connaissances informatiques de base, les bases HTML (étudiées dans l'<a href="/en-US/docs/Learn/HTML/Introduction_to_HTML">Introduction au HTML</a>), les bases CSS (étudiées dans <a href="/en-US/docs/Learn/CSS/Introduction_to_CSS">Introduction à CSS</a>).</td>
+ </tr>
+ <tr>
+ <th scope="row">Objectif :</th>
+ <td>Apprendre les techniques et propriétés fondamentales nécessaires pour composer du texte sur les pages web.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="En_quoi_consiste_la_mise_en_forme_du_texte_avec_CSS">En quoi consiste la mise en forme du texte avec CSS ?</h2>
+
+<p>Comme vous l'avez déjà vu dans votre apprentissage de HTML et CSS, le texte d'un élément est placé à l'intérieur de la boîte de contenu de cet élément. Il débute en haut à gauche de cette zone (ou en haut à droite, dans le cas des contenus en langues s'écrivant de droite à gauche) et se poursuit vers la fin de la ligne. Arrivé en bout de ligne, il descend à la ligne suivante et continue, puis va à la ligne suivante, jusqu'à ce que tout le contenu ait été placé. Les contenus textuels se comportent comme une suite d'éléments en ligne placés les uns à côté des autres. Aucun saut de ligne n'est créé avant que la fin de la ligne soit atteinte, sauf si vous forcez manuellement le saut de ligne avec l'élément {{htmlelement("br")}}.</p>
+
+<div class="note">
+<p><strong>Note</strong> : si le paragraphe ci‑dessus vous paraît confus,  pas de problème — revenez en arrière et revoyez l'article sur la théorie du <a href="/fr/Apprendre/CSS/Les_bases/Le_modèle_de_boîte">Modèle de boîte</a> avant de poursuivre.</p>
+</div>
+
+<p>Les propriétés CSS utilisées pour le style de texte appartiennent généralement à deux catégories, que nous verrons séparément dans cet article :</p>
+
+<ul>
+ <li><strong>Styles de la police de caractères </strong>: ces propriétés concernent la fonte appliquée au  texte, affectant sa police, sa taille, sa graisse, si elle est italique, etc.</li>
+ <li><strong>Styles de composition du texte </strong>: ces propriétés influent sur les espacements et autres dispositions de mise en page du texte, permettant de modifier, par exemple, l'espacement entre lignes et entre caractères, et la manière de disposer le texte  dans la boîte de contenu.</li>
+</ul>
+
+<div class="note">
+<p><strong>Note </strong>: Gardez à l'esprit que le texte à l'intérieur d'un élément est affecté comme une seule entité. Vous ne pouvez pas sélectionner et mettre en forme des sous-sections de texte, sauf si vous les enveloppez dans un élément approprié (tel que {{htmlelement ("span")}} ou {{htmlelement ("strong")}}, ou utilisez un texte pseudo-élément spécifique comme <a href="https://developer.mozilla.org/fr/docs/Web/CSS/::first-letter">::first-letter</a> (sélectionne la première lettre du texte d'un élément), <a href="https://developer.mozilla.org/fr/docs/Web/CSS/::first-line">::first-line</a> (sélectionne la première ligne du texte d'un élément) ou <a href="https://developer.mozilla.org/fr/docs/Web/CSS/::selection">::selection</a> (sélectionne le texte actuellement mis en surbrillance par le curseur) .</p>
+</div>
+
+<h2 id="Fontes">Fontes</h2>
+
+<p>Passons directement aux propriétés pour le style des polices. Dans cet exemple, nous allons appliquer différentes propriétés CSS au même exemple HTML, qui ressemble à ceci :</p>
+
+<pre class="brush: html">&lt;h1&gt;Tommy le Chat&lt;/h1&gt;
+
+&lt;p&gt;Je m'en souviens comme mon dernier repas...&lt;/p&gt;
+
+&lt;p&gt;Dit Tommy le Chat en jetant la tête en arrière pour dégager
+ce corps étranger qui s'était niché au fond de sa redoutable gueule.
+Beaucoup de rats bien gras trépassèrent dans la ruelle en regardant l'étoile
+brillant au fond du canon de cet extraordinaire rôdeur en quête de proie.
+Un véritable miracle de la nature ce prédateur urbain — Tommy le Chat
+avait beaucoup d'histoires à raconter. Mais il ne le faisait qu'en de rares
+occasions, comme maintenant.&lt;/p&gt;</pre>
+
+<div class="note">
+<p>(NdT : Extrait et traduction <em>approximative</em> de la chanson <em>Tommy the Cat</em> du groupe <a href="https://fr.wikipedia.org/wiki/Primus_(groupe)">Primus)</a></p>
+</div>
+
+<p>Vous pouvez trouver l'<a href="https://mdn.github.io/learning-area/css/styling-text/fundamentals/">exemple (en) fini</a> sur Github (voir aussi <a href="https://github.com/mdn/learning-area/blob/master/css/styling-text/fundamentals/index.html">le code source</a>).</p>
+
+<h3 id="Couleur">Couleur</h3>
+
+<p>La propriété {{cssxref("color")}} définit la couleur du contenu d'avant‑plan des éléments sélectionnés (généralement du texte, mais peut être autre chose, comme un soulignement ou un surlignage créé avec la propriété {{cssxref("text-decoration")}}.</p>
+
+<p><code>color</code> accepte toutes les <a href="https://developer.mozilla.org/fr/Apprendre/CSS/Introduction_%C3%A0_CSS/Values_and_units#Couleurs">unités de couleur des CSS</a>, par exemple :</p>
+
+<pre class="brush: css">p {
+ color: red;
+}</pre>
+
+<p>Les paragraphes seront en rouge, au lieu d'être de couleur noire, couleur par défaut du navigateur standard :</p>
+
+<div class="hidden">
+<pre class="brush: html">&lt;h1&gt;Tommy le Chat&lt;/h1&gt;
+
+&lt;p&gt;Je m'en souviens comme mon dernier repas...&lt;/p&gt;
+
+&lt;p&gt;Dit Tommy le Chat en jetant la tête en arrière pour dégager
+ce corps étranger qui s'était niché au fond de sa redoutable gueule.
+Beaucoup de rats bien gras trépassèrent dans la ruelle en regardant l'étoile
+brillant au fond du canon de cet extraordinaire rôdeur en quête de proie.
+Un véritable miracle de la nature ce prédateur urbain — Tommy le Chat
+avait beaucoup d'histoires à raconter. Mais il ne le faisait qu'en de rares
+occasions, comme maintenant.&lt;/p&gt;</pre>
+</div>
+
+<p>{{ EmbedLiveSample('Couleur', '100%', 220) }}</p>
+
+<h3 id="Familles_de_fontes">Familles de fontes</h3>
+
+<p>Pour définir une police de caractères différente pour le texte, utilisez la propriété {{cssxref("font-family")}} — cela vous permet de spécifier une police (ou une liste de polices) que le navigateur doit appliquer aux éléments sélectionnés. Le navigateur n'appliquera une police de caractères que si elle est disponible sur la machine sur laquelle le site est accessible, sinon, il utilisera une  {{anch("Default fonts", "police par défaut")}} . Un exemple simple pour voir cela :</p>
+
+<pre class="brush: css">p {
+ font-family: arial;
+}</pre>
+
+<p>Cette commande définit la police de caractères arial (qui existe sur tous les ordinateurs) pour tous les paragraphes de la page.</p>
+
+<h4 id="Polices_web_sûres">Polices web sûres</h4>
+
+<p>En parlant de la disponibilité des polices, il y a seulement un certain nombre de polices qui sont généralement disponibles sur tous les systèmes, et peuvent donc être utilisées sans trop de soucis. Ce sont les polices web dites sûres.</p>
+
+<p>La plupart du temps, en tant que développeur web, nous voulons avoir un contrôle précis sur les polices utilisées pour afficher le contenu textuel. Le problème est de trouver un moyen de savoir quelle police est disponible sur l'ordinateur utilisé pour voir nos pages web. Il n'y a aucun moyen systématique de le savoir, mais les polices web sûres sont disponibles sur presque tous les systèmes d'exploitation les plus utilisés (Windows, Mac, les distributions Linux les plus courantes, Android et iOS).</p>
+
+<p>La liste des polices web vraiment sûres changera à mesure que les systèmes d'exploitation évolueront, mais on peut considérer les polices suivantes comme sûres sur le web, du moins pour le moment (beaucoup ont été popularisées grâce aux polices <a href="https://fr.wikipedia.org/wiki/Core_fonts_for_the_Web">Microsoft Core</a> pour le web à la fin des années 90 et début des années 2000) :</p>
+
+<table class="standard-table">
+ <thead>
+ <tr>
+ <th scope="col">Nom</th>
+ <th scope="col" style="white-space: nowrap;">Type générique</th>
+ <th scope="col">Notes</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>Arial</td>
+ <td>sans-serif</td>
+ <td>Il est de bonne pratique d'ajouter Helvetica en tant qu'alternative préférée d'Arial car, bien que leurs apparences soient presque identiques, Helvetica est considérée comme ayant une forme plus agréable, même si Arial est plus courante.</td>
+ </tr>
+ <tr>
+ <td>Courier New</td>
+ <td>monospace</td>
+ <td>Certains systèmes d'exploitation ont une version alternative (peut-être plus ancienne) de la police <em>Courier New</em> appelée <em>Courier</em>. Il est recommandé d'utiliser les deux avec <em>Courier New</em> comme alternative préférée.</td>
+ </tr>
+ <tr>
+ <td style="white-space: nowrap;">Georgia</td>
+ <td>serif</td>
+ <td> </td>
+ </tr>
+ <tr>
+ <td style="white-space: nowrap;">Times New Roman</td>
+ <td>serif</td>
+ <td>Certains systèmes d'exploitation ont une version alternative (peut-être plus ancienne) de la police <em>Times New Roman</em> appelée <em>Times</em>. Il est recommandé d'utiliser les deux avec <em>Times New Roman</em> comme alternative préférée.</td>
+ </tr>
+ <tr>
+ <td>Trebuchet MS</td>
+ <td>sans-serif</td>
+ <td>Vous devriez être prudent avec l'utilisation de cette police - elle n'est pas aussi largement disponible sur les systèmes d'exploitation des mobiles.</td>
+ </tr>
+ <tr>
+ <td>Verdana</td>
+ <td>sans-serif</td>
+ <td> </td>
+ </tr>
+ </tbody>
+</table>
+
+<div class="note">
+<p><strong>Note </strong>: <span id="result_box" lang="fr"><span>Le site <a href="https://www.cssfontstack.com/">cssfontstack.com</a> met à votre disposition, entre autres ressources, une liste de polices web sûres disponibles sur les systèmes d'exploitation Windows et Mac OS. Elle peut faciliter votre prise de décision quant à ce que vous considérerez comme sûr pour votre usage.</span></span></p>
+</div>
+
+<div class="note">
+<p><strong>Note </strong>: Il y a moyen de télécharger une police personnalisée avec une page Web ; cela permet une utilisation personnalisée de la police comme vous le souhaitez : <strong>les polices web</strong>. C'est un peu plus complexe, et nous en discuterons dans un article séparé plus loin dans le module.</p>
+</div>
+
+<h4 id="Polices_par_défaut">Polices par défaut</h4>
+
+<p>CSS définit cinq noms génériques pour les polices : <code>serif</code>, <code>sans-serif</code>, <code>monospace</code>, <code>cursive</code> et <code>fantasy</code>. À cause de leur caractère générique la police de caractères exacte utilisée, lors de l'emploi de ces noms, dépend de chaque navigateur et peut varier pour chaque système d'exploitation sur lequel ils s'exécutent. Dans le pire des cas, le navigateur essaiera de trouver une police appropriée.<code>serif</code>, <code>sans-serif</code> et <code>monospace</code> sont tout à fait prévisibles et devraient donner quelque chose de raisonnable. Par contre, <code>cursive</code> et <code>fantasy</code> sont moins prévisibles et nous vous recommandons de les utiliser avec précaution, en les testant au fur et à mesure.</p>
+
+<p>Les 5 noms sont définis comme suit :</p>
+
+<table class="standard-table">
+ <thead>
+ <tr>
+ <th scope="col">Terme</th>
+ <th scope="col">Définition</th>
+ <th scope="col">Exemple</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td><code>serif</code></td>
+ <td>Les polices qui ont des sérifs (fioritures et autres petits détails que vous voyez en extrémité de trait dans certaines polices)</td>
+ <td><span style="font-family: serif;">Mon grand éléphant rouge</span></td>
+ </tr>
+ <tr>
+ <td><code>sans-serif</code></td>
+ <td>Les polices qui n'ont pas d'empattements</td>
+ <td><span style="font-family: sans-serif;">Mon grand éléphant rouge</span></td>
+ </tr>
+ <tr>
+ <td><code>monospace</code></td>
+ <td>Les polices dans lesquelles chaque caractère a la même largeur, généralement utilisées dans les listes de codes.</td>
+ <td><span style="font-family: monospace;">Mon grand éléphant rouge</span></td>
+ </tr>
+ <tr>
+ <td><code>cursive</code></td>
+ <td>Les polices destinées à émuler l'écriture, avec des traits fluides et connectés.</td>
+ <td><span style="font-family: cursive;">Mon grand éléphant rouge</span></td>
+ </tr>
+ <tr>
+ <td><code>fantasy</code></td>
+ <td>Les polices destinées à être décoratives.</td>
+ <td><span style="font-family: fantasy;">Mon grand éléphant rouge</span></td>
+ </tr>
+ </tbody>
+</table>
+
+<h4 id="Pile_de_polices">Pile de polices</h4>
+
+<p>Comme la disponibilité des polices que vous souhaitez utiliser sur vos pages web n'est pas garantie (même une police web peut échouer pour une raison quelconque), vous pouvez indiquer une pile de polices afin que le navigateur ait à sa disposition plusieurs polices. Il convient simplement d'indiquer pour valeur de <code>font-family</code> plusieurs noms de polices séparés par des virgules, par exemple :</p>
+
+<pre class="brush: css">p {
+ font-family: "Trebuchet MS", Verdana, sans-serif;
+}</pre>
+
+<p>Dans ce cas, le navigateur débute la lecture de la liste et cherche à voir si cette police est disponible sur la machine. <span>Si c'est le cas, il applique cette police aux éléments sélectionnés.</span> <span>Sinon, il passe à la police suivante et ainsi de suite.</span></p>
+
+<p>Indiquer un nom de police générique approprié en fin de liste est une bonne idée : si aucune des polices listées n'est disponible, le navigateur peut au‑moins fournir quelque chose de convenable. Soulignons ce point : les paragraphes seront rendus avec la police serif par défaut du navigateur si aucune autre option n'est disponible — généralement Time New Roman — mais ce ne sera pas un bon substitut à une police sans-serif !</p>
+
+<div class="note">
+<p><strong>Note </strong>: Les noms de police comportant plus d'un mot — comme <code>Trebuchet MS</code> — doivent être entourés de guillemets, par exemple <code>"Trebuchet MS"</code>.</p>
+</div>
+
+<h4 id="Un_exemple_de_font-family">Un exemple de font-family</h4>
+
+<p>Faisons un ajout à notre exemple précédent et donnons aux paragraphes une police sans-serif :</p>
+
+<pre class="brush: css">p {
+ color: red;
+ font-family: Helvetica, Arial, sans-serif;
+}</pre>
+
+<p>Cela donne le résultat suivant :</p>
+
+<div class="hidden">
+<pre class="brush: html">&lt;h1&gt;Tommy le Chat&lt;/h1&gt;
+
+&lt;p&gt;Je m'en souviens comme mon dernier repas...&lt;/p&gt;
+
+&lt;p&gt;Dit Tommy le Chat en jetant la tête en arrière pour dégager
+ce corps étranger qui s'était niché au fond de sa redoutable gueule.
+Beaucoup de rats bien gras trépassèrent dans la ruelle en regardant l'étoile
+brillant au fond du canon de cet extraordinaire rôdeur en quête de proie.
+Un véritable miracle de la nature ce prédateur urbain — Tommy le Chat
+avait beaucoup d'histoires à raconter. Mais il ne le faisait qu'en de rares
+occasions, comme maintenant.&lt;/p&gt;</pre>
+</div>
+
+<p>{{ EmbedLiveSample('Un_exemple_de_font-family', '100%', 220) }}</p>
+
+<h3 id="Taille_de_la_police_de_caractères">Taille de la police de caractères</h3>
+
+<p>Dans l'article <a href="https://developer.mozilla.org/fr/Apprendre/CSS/Introduction_%C3%A0_CSS/Values_and_units">Valeurs et unités CSS</a> de notre prédédent module, nous avons vu les <a href="https://developer.mozilla.org/fr/Apprendre/CSS/Introduction_%C3%A0_CSS/Values_and_units#Longueur_et_taille">unités de longueur et taille</a>. La taille des polices de caractères (définie avec la propriété {{cssxref("font-size")}}) accepte la plupart des unités de valeur (et d'autres comme les <a href="https://developer.mozilla.org/fr/Apprendre/CSS/Introduction_%C3%A0_CSS/Values_and_units#Pourcentages">pourcentages</a>). Toutefois, les unités les plus couramment utilisées pour dimensionner le texte sont :</p>
+
+<ul>
+ <li><code>px</code> (pixels) : le nombre de pixels souhaités pour la hauteur du texte. C'est une unité absolue — il en résulte une même valeur finale calculée de la police sur la page dans à peu près n'importe quelle situation.</li>
+ <li><code>em</code> : 1 em est égal à la taille de la police définie sur l'élément parent de l'élément courant que nous composons (plus précisément, la largeur d'un « M » majuscule de l'élément parent). Cette valeur peut devenir difficile à déterminer si vous avez beaucoup d'imbrications avec diverses tailles de police, mais cela reste faisable, comme vous le verrez ci-dessous. Pourquoi s'embêter ? C'est assez naturel, une fois que vous y êtes habitué ; vous pouvez utiliser <code>em</code> pour tout dimensionner, pas seulement du texte. Vous pouvez avoir un site web entier dimensionné avec des <code>em</code>, la maintenance en sera facilitée.</li>
+ <li><code>rem</code> : il fonctionne comme <code>em</code>, excepté que un <code>rem</code> est égal à la taille de la police sur l'élément racine du document (c'est-à-dire {{htmlelement("html")}}) et non le parent direct). Le calcul des tailles de police en est facilité, mais malheureusement les <code>rem</code> ne sont pas pris en charge dans Internet Explorer 8 et avant. Si vous devez prendre en charge des navigateurs plus anciens dans votre projet, vous devrez vous en tenir aux <code>em</code> ou aux <code>px</code>, soit utiliser une <span class="st">prothèse d'émulation</span> ({{glossary ("polyfill")}}) telle que <a href="https://github.com/chuckcarpenter/REM-unit-polyfill">REM-unit-polyfill</a>.</li>
+</ul>
+
+<p>La propriété <code>font-size</code> d'un élément est héritée de son parent. Tout commence par l'élément racine de l'ensemble du document — {{htmlelement("html")}} — dont la propriété <code>font‑size</code> est normée à 16 px sur les navigateurs. Tout paragraphe (ou tout autre élément dont la taille n'a pas été définie différemment par le navigateur) à l'intérieur de l'élément racine aura une taille finale de 16 px. D'autres éléments peuvent avoir des tailles par défaut différentes, par exemple un élément {{htmlelement ("h1")}} a une taille de 2 <code>em</code> définie par défaut, donc aura une taille finale de 32 px.</p>
+
+<p>Les choses deviennent plus difficiles lorsque vous commencez à modifier la taille de la police des éléments imbriqués. Par exemple, vous avez un élément {{htmlelement ("article")}} dans la page dont la taille de police est 1.5 <code>em</code> (24 px), puis, vous voulez que les paragraphes de l'<code>&lt;article&gt;</code> aient une taille de police calculée de 20 px, quelle valeur de <code>em</code> utiliseriez-vous ?</p>
+
+<pre class="brush: html">&lt;!-- font-size vaut 16px pour la base du document --&gt;
+&lt;article&gt; &lt;!-- Si font-size vaut 1.5em --&gt;
+ &lt;p&gt;Mon paragraphe&lt;/p&gt; &lt;!-- Comment calculer une hauteur de fonte de 20px ? --&gt;
+&lt;/article&gt;</pre>
+
+<p>Vous devrez définir sa valeur <code>em</code> à 20/24 ou 0,83333333 <code>em</code>. Les mathématiques peuvent être compliquées, vous devez donc faire attention à la façon dont vous composez les choses. Il est préférable d'utiliser <code>rem</code> quand vous le pouvez, pour garder les choses simples et éviter d'avoir à définir la taille des polices des éléments du conteneur si possible.</p>
+
+<h4 id="Un_simple_exemple_de_dimensionnement">Un simple exemple de dimensionnement</h4>
+
+<p>Quand vous dimensionnez votre texte, c'est généralement une bonne idée de définir la <code>font‑size</code> de base du document à 10 px, de sorte que les maths sont beaucoup plus faciles à travailler — les valeurs requises (r) em sont alors la taille de la police en pixels divisée par 10, et non par 16. Après cela, vous pouvez facilement dimensionner les différents types de texte dans votre document à votre goût. C'est une bonne idée de lister tous les jeux de règles de <code>font‑size</code> dans une zone désignée de votre feuille de style, afin qu'ils soient faciles à trouver.</p>
+
+<p>Notre nouveau résultat ressemble à :</p>
+
+<div class="hidden">
+<pre class="brush: html">&lt;h1&gt;Tommy le Chat&lt;/h1&gt;
+
+&lt;p&gt;Je m'en souviens comme mon dernier repas...&lt;/p&gt;
+
+&lt;p&gt;Dit Tommy le Chat en jetant la tête en arrière pour dégager
+ce corps étranger qui s'était niché au fond de sa redoutable gueule.
+Beaucoup de rats bien gras trépassèrent dans la ruelle en regardant l'étoile
+brillant au fond du canon de cet extraordinaire rôdeur en quête de proie.
+Un véritable miracle de la nature ce prédateur urbain — Tommy le Chat
+avait beaucoup d'histoires à raconter. Mais il ne le faisait qu'en de rares
+occasions, comme maintenant.&lt;/p&gt;</pre>
+</div>
+
+<pre class="brush: css">html {
+ font-size: 10px;
+}
+
+h1 {
+ font-size: 2.6rem;
+}
+
+p {
+ font-size: 1.4rem;
+ color: red;
+ font-family: Helvetica, Arial, sans-serif;
+}</pre>
+
+<p>{{ EmbedLiveSample('Un_simple_exemple_de_dimensionnement', '100%', 220) }}</p>
+
+<h3 id="Style_de_fonte_graisse_transformation_et_décoration_de_texte">Style de fonte, graisse, transformation et décoration de texte</h3>
+
+<p>CSS fournit quatre propriétés communes pour modifier le poids et l'emphase visuelles du texte :</p>
+
+<ul>
+ <li>{{cssxref("font-style")}} : utilisé pour appliquer ou enlever le style italique. Les valeurs possibles sont les suivantes (vous ne l'utiliserez que rarement, sauf si vous souhaitez désactiver le style italique pour une raison quelconque) :
+ <ul>
+ <li><code>normal</code> : fige le texte en police normale (suppression du style italique existant).</li>
+ <li><code>italic </code>: met le texte en  <em>version italique de la police</em> si elle est disponible ; si elle n'existe pas, le style italique sera émulé avec l'option oblique à la place.</li>
+ <li><code>oblique</code> : force le texte à utiliser une version simulée de fonte italique, créée en <em>inclinant la version normale</em>.</li>
+ </ul>
+ </li>
+ <li>{{cssxref("font-weight")}} : définit la graisse du texte. La propriété peut avoir de nombreuses valeurs s'il y a de nombreuses variantes de polices disponibles (comme <em>-light</em>, <em>-normal</em>, <em>-bold</em>, <em>-extrabold</em>, <em>-black</em>, etc.), mais en réalité, vous les utiliserez rarement en dehors de <code>normal</code> et <code>bold</code> (gras):
+ <ul>
+ <li><code>normal</code>, <code>bold</code> : graisse de la police, normale ou <strong style="font-weight: bold;">bold</strong>.</li>
+ <li><code>lighter</code>, <code>bolder</code> : définit la graisse de l'élément courant de sorte qu'il soit un cran moins gras ou plus gras que son parent.</li>
+ <li><code>100–900</code> : valeurs numériques du taux de graisse ; elles permettent un dosage plus fin que les mots-clés ci-dessus, si nécessaire.</li>
+ </ul>
+ </li>
+ <li>{{cssxref("text-transform")}} : Vous permet de définir les transformations de votre police. Les valeurs comprennent :
+ <ul>
+ <li><code>none</code> : aucune transformation.</li>
+ <li><code>uppercase</code> : met <span style="text-transform: uppercase;">tout le texte en majuscules</span>.</li>
+ <li><code>lowercase</code> : met tout le texte en minuscules.</li>
+ <li><code>capitalize</code> : transforme tous les mots en mettant leur <span style="text-transform: capitalize;">première lettre en majuscule</span>s.</li>
+ <li><code>full-width</code> : force l'écriture de tous les glyphes dans un carré de largeur fixe, similaire à une police à espacement fixe, permettant leur alignement, par ex. caractères latins avec des glyphes de langue asiatique (comme le chinois, le japonais, le coréen.)</li>
+ </ul>
+ </li>
+ <li>{{cssxref("text-decoration")}} : active ou désactive les décorations de texte sur les polices (vous les utiliserez principalement pour désactiver le soulignement par défaut sur les liens lors de leur création). Les valeurs disponibles sont :
+ <ul>
+ <li><code>none</code>: désactive les décorations du texte déjà présentes.</li>
+ <li><code>underline</code>: <u>souligne le texte</u>.</li>
+ <li><code>overline</code>: <span style="text-decoration: overline;">trace une ligne au-dessus du texte</span>.</li>
+ <li><code>line-through</code>: <s style="text-decoration: line-through;">barre le texte</s>.</li>
+ </ul>
+ Vous devez noter que {{cssxref("text-decoration")}} peut accepter plusieurs valeurs à la fois, si vous voulez en ajouter plusieurs simultanément, par exemple <span style="text-decoration: underline overline;"><code>text-decoration: underline overline</code></span>. Notez aussi que {{cssxref("text-decoration")}} est la propriété raccourcie pour {{cssxref("text-decoration-line")}}, {{cssxref("text-decoration-style")}} et {{cssxref("text-decoration-color")}}. Vous pouvez utiliser des combinaisons de ces valeurs de propriété pour créer des effets intéressants, par exemple <span style="text-decoration: line-through red wavy;"><code>text-decoration: line-through red wavy</code>.</span></li>
+</ul>
+
+<p>Regardons l'ajout de quelques-unes de ces propriétés à notre exemple.</p>
+
+<p>Notre nouveau résultat ressemble à :</p>
+
+<div class="hidden">
+<pre class="brush: html">&lt;h1&gt;Tommy le Chat&lt;/h1&gt;
+
+&lt;p&gt;Je m'en souviens comme mon dernier repas...&lt;/p&gt;
+
+&lt;p&gt;Dit Tommy le Chat en jetant la tête en arrière pour dégager
+ce corps étranger qui s'était niché au fond de sa redoutable gueule.
+Beaucoup de rats bien gras trépassèrent dans la ruelle en regardant l'étoile
+brillant au fond du canon de cet extraordinaire rôdeur en quête de proie.
+Un véritable miracle de la nature ce prédateur urbain — Tommy le Chat
+avait beaucoup d'histoires à raconter. Mais il ne le faisait qu'en de rares
+occasions, comme maintenant.&lt;/p&gt;</pre>
+</div>
+
+<pre class="brush: css">html {
+ font-size: 10px;
+}
+
+h1 {
+ font-size: 2.6rem;
+ text-transform: capitalize;
+}
+
+h1 + p {
+ font-weight: bold;
+}
+
+p {
+ font-size: 1.4rem;
+ color: red;
+ font-family: Helvetica, Arial, sans-serif;
+}</pre>
+
+<p>{{ EmbedLiveSample('Style_de_fonte_graisse_transformation_et_décoration_de_texte', '100%', 220) }}</p>
+
+<h3 id="Ombres_du_texte">Ombres du texte</h3>
+
+<p>Vous pouvez ombrer votre texte avec la propriété {{cssxref("text-shadow")}}. Elle prend 4 valeurs, comme vous pouvez le voir dans l'exemple ci-dessous :</p>
+
+<pre class="brush: css">text-shadow: 4px 4px 5px red;</pre>
+
+<p>Les 4 propriétés sont les suivantes :</p>
+
+<ol>
+ <li>Le décalage horizontal de l'ombre par rapport au texte original — cette grandeur acepte la plupart des <a href="https://developer.mozilla.org/en-US/Learn/CSS/Introduction_to_CSS/Values_and_units#Length_and_size">unités de longueur et de taille</a> des CSS disponibles, mais vous utiliserez en règle générale le px. Cette valeur doit être précisée.</li>
+ <li>Le décalage vertical de l'ombre par rapport au texte original — cette grandeur se comporte à la base comme la précédente, sauf que l'ombre est portée vers le haut ou vers le bas, et non vers la gauche ou la droite. Cette valeur doit être précisée.</li>
+ <li>Le rayon de floutage — plus cette valeur est élevée, plus l'ombre est étalée largement. Si cette valeur n'est pas précisée, la valeur par défaut est 0, ce qui signifie pas de flou. Elle accepte toutes les <a href="https://developer.mozilla.org/en-US/Learn/CSS/Introduction_to_CSS/Values_and_units#Length_and_size">unités de longueur et de taille</a> des CSS.</li>
+ <li>La couleur de l'ombre, qui peut prendre toute <a href="https://developer.mozilla.org/en-US/Learn/CSS/Introduction_to_CSS/Values_and_units#Colors">unité de couleur CSS</a>. Si elle n'est pas définie, c'est la couleur noire par défaut.</li>
+</ol>
+
+<div class="note">
+<p><strong>Note</strong> : Les valeurs positives de décalage déplacent l'ombre à droite et en bas, mais vous pouvez aussi utiliser des valeurs négatives pour obtenir une ombre à gauche et en haut, par exemple <code>-1px -1px</code>.</p>
+</div>
+
+<h4 id="Ombres_multiples">Ombres multiples</h4>
+
+<p>Vous pouvez appliquer plusieurs ombres à un même texte, en mettant plusieurs valeurs d'ombrage séparées par une virgule, par exemple :</p>
+
+<pre class="brush: css language-css"><code class="language-css">text-shadow: -1px -1px 1px #aaa,
+ 0px 4px 1px rgba(0,0,0,0.5),
+ 4px 4px 5px rgba(0,0,0,0.7),
+ 0px 0px 7px rgba(0,0,0,0.4);</code></pre>
+
+<p>Si nous l'appliquons à l'élément {{htmlelement ("h1")}} de notre exemple Tommy le Chat, nous nous obtenons :</p>
+
+<div class="hidden">
+<pre class="brush: html">&lt;h1&gt;Tommy le Chat&lt;/h1&gt;
+
+&lt;p&gt;Je m'en souviens comme mon dernier repas...&lt;/p&gt;
+
+&lt;p&gt;Dit Tommy le Chat en jetant la tête en arrière pour dégager
+ce corps étranger qui s'était niché au fond de sa redoutable gueule.
+Beaucoup de rats bien gras trépassèrent dans la ruelle en regardant l'étoile
+brillant au fond du canon de cet extraordinaire rôdeur en quête de proie.
+Un véritable miracle de la nature ce prédateur urbain — Tommy le Chat
+avait beaucoup d'histoires à raconter. Mais il ne le faisait qu'en de rares
+occasions, comme maintenant.&lt;/p&gt;</pre>
+
+<pre class="brush: css line-numbers language-css"><code class="language-css">html {
+ font-size: 10px;
+ }
+
+h1 {
+ font-size:26px;
+ text-transform: capitalize;
+ text-shadow: -1px -1px 1px #aaa,
+ 0px 2px 1px rgba(0,0,0,0.5),
+ 2px 2px 2px rgba(0,0,0,0.7),
+ 0px 0px 3px rgba(0,0,0,0.4);
+ }
+
+h1 + p {
+ font-weight: bold;
+ }
+
+p {
+ font-size:14px;
+ color: red;
+ font-family: Helvetica, Arial, sans-serif;
+ }
+</code>
+</pre>
+</div>
+
+<p>{{ EmbedLiveSample('Ombres_du_texte', '100%', 220) }}</p>
+
+<div class="note">
+<p><strong>Note </strong>: Vous pouvez voir plus d'exemples intéressants de <code>text-shadow</code> dans l'article de Sitepoint <a href="http://www.sitepoint.com/moonlighting-css-text-shadow/">Moonlighting with CSS text-shadow</a> (Clair de lune avec text-shadow).</p>
+</div>
+
+<h2 id="Mise_en_page_du_texte"><small lang="en">Mise en page du texte</small></h2>
+
+<p><span id="result_box" lang="fr"><span>Après les propriétés de base des polices, examinons maintenant celles permettant de modifier la disposition des textes.</span></span></p>
+
+<h3 id="Alignement_du_texte">Alignement du texte</h3>
+
+<p>La propriété {{cssxref("text-align")}} s'utilise pour contrôler la disposition du texte dans la zone de contenu. Les valeurs acceptées sont les suivantes. Elles <span id="result_box" lang="fr"><span>fonctionnent à peu près de la même manière que dans un traitement de texte</span></span> :</p>
+
+<ul>
+ <li><code>left</code>: le texte est aligné à gauche.</li>
+ <li><code>right</code>: le texte est aligné à droite.</li>
+ <li><code>center</code>: le texte est centré.</li>
+ <li><code>justify</code>: <span id="result_box" lang="fr"><span>étale le texte, en faisant varier les espaces entre les mots afin de donner la même largeur à toutes les lignes du texte.</span> <span>Vous devez l'utiliser avec discernement </span></span> — <span lang="fr"><span> il peut sembler parfait, surtout lorsqu'il est appliqué à un paragraphe avec beaucoup de longs mots.</span> <span>Si vous voulez l'utiliser, vous devriez aussi penser à utiliser quelque chose d'autre, comme {{cssxref ("hyphens")}}, pour couper certains des mots les plus longs entre les lignes.</span></span></li>
+</ul>
+
+<p>Si nous appliquons <code>text-align: center;</code> à l'élément {{htmlelement("h1")}} de notre exemple, nous aurons :</p>
+
+<div class="hidden">
+<pre class="brush: html">&lt;h1&gt;Tommy le Chat&lt;/h1&gt;
+
+&lt;p&gt;Je m'en souviens comme mon dernier repas...&lt;/p&gt;
+
+&lt;p&gt;Dit Tommy le Chat en jetant la tête en arrière pour dégager
+ce corps étranger qui s'était niché au fond de sa redoutable gueule.
+Beaucoup de rats bien gras trépassèrent dans la ruelle en regardant l'étoile
+brillant au fond du canon de cet extraordinaire rôdeur en quête de proie.
+Un véritable miracle de la nature ce prédateur urbain — Tommy le Chat
+avait beaucoup d'histoires à raconter. Mais il ne le faisait qu'en de rares
+occasions, comme maintenant.&lt;/p&gt;</pre>
+
+<pre class="brush: css">html {
+ font-size: 10px;
+}
+
+h1 {
+ font-size: 2.6rem;
+ text-transform: capitalize;
+ text-shadow: -1px -1px 1px #aaa,
+ 0px 2px 1px rgba(0,0,0,0.5),
+ 2px 2px 2px rgba(0,0,0,0.7),
+ 0px 0px 3px rgba(0,0,0,0.4);
+ text-align: center;
+}
+
+h1 + p {
+ font-weight: bold;
+}
+
+p {
+ font-size: 1.4rem;
+ color: red;
+ font-family: Helvetica, Arial, sans-serif;
+}</pre>
+</div>
+
+<p>{{ EmbedLiveSample('Alignement_du_texte', '100%', 220) }}</p>
+
+<h3 id="Hauteur_de_ligne">Hauteur de ligne</h3>
+
+<p>La propriété {{cssxref ("line-height")}} définit la hauteur de chaque ligne de texte — elle peut prendre la plupart des <a href="/fr/Apprendre/CSS/Introduction_à_CSS/Values_and_units#Length_and_size">unités de longueur et de taille</a>, mais elle peut également prendre une valeur sans unité, qui agit comme un multiplicateur et est considérée habituellement comme la meilleure option — la valeur de {{cssxref ("font-size")}} est multipliée par ce facteur pour obtenir la valeur de <code>line-height</code>. Le corps de texte semble généralement plus agréable et est plus facile à lire lorsque les lignes sont espacées ; la hauteur de ligne recommandée est d'environ 1,5-2 (double interligne). Donc, pour définir une hauteur de ligne de texte égale à 1,5 fois la hauteur de la police, vous utiliserez ceci :</p>
+
+<pre class="brush: css">line-height: 1.5;</pre>
+
+<p>En appliquant cette règle à l'élément {{htmlelement("p")}}  de l'exemple, nous obtenons :</p>
+
+<div class="hidden">
+<pre class="brush: html">&lt;h1&gt;Tommy le Chat&lt;/h1&gt;
+
+&lt;p&gt;Je m'en souviens comme mon dernier repas...&lt;/p&gt;
+
+&lt;p&gt;Dit Tommy le Chat en jetant la tête en arrière pour dégager
+ce corps étranger qui s'était niché au fond de sa redoutable gueule.
+Beaucoup de rats bien gras trépassèrent dans la ruelle en regardant l'étoile
+brillant au fond du canon de cet extraordinaire rôdeur en quête de proie.
+Un véritable miracle de la nature ce prédateur urbain — Tommy le Chat
+avait beaucoup d'histoires à raconter. Mais il ne le faisait qu'en de rares
+occasions, comme maintenant.&lt;/p&gt;</pre>
+
+<pre class="brush: css">html {
+ font-size: 10px;
+}
+
+h1 {
+ font-size: 2.6rem;
+ text-transform: capitalize;
+ text-shadow: -1px -1px 1px #aaa,
+ 0px 2px 1px rgba(0,0,0,0.5),
+ 2px 2px 2px rgba(0,0,0,0.7),
+ 0px 0px 3px rgba(0,0,0,0.4);
+ text-align: center;
+}
+
+h1 + p {
+ font-weight: bold;
+}
+
+p {
+ font-size: 1.4rem;
+ color: red;
+ font-family: Helvetica, Arial, sans-serif;
+}</pre>
+</div>
+
+<p>{{ EmbedLiveSample('Hauteur_de_ligne', '100%', 250) }}</p>
+
+<h3 id="Espacement_entre_les_lettres_et_les_mots">Espacement entre les lettres et les mots</h3>
+
+<p>Les propriétés {{cssxref ("letter-spacing")}} et {{cssxref ("word-spacing")}} permettent de définir l'espacement entre les lettres et les mots de votre texte. Vous ne les utiliserez pas très souvent, mais vous pourriez les utiliser pour obtenir une certaine apparence ou pour améliorer la lisibilité d'une police particulièrement dense. Ils peuvent prendre la plupart des <a href="https://developer.mozilla.org/en-US/Learn/CSS/Introduction_to_CSS/Values_and_units#Length_and_size">unités de longueur et de taille</a>.</p>
+
+<p>Si nous appliquons les paramètres suivants à la première ligne des éléments {{htmlelement("p")}} dans notre exemple :</p>
+
+<pre class="brush: css">p::first-line {
+ letter-spacing: 2px;
+ word-spacing: 4px;
+}</pre>
+
+<p>Nous obtiendrons :</p>
+
+<div class="hidden">
+<pre class="brush: html">&lt;h1&gt;Tommy le Chat&lt;/h1&gt;
+
+&lt;p&gt;Je m'en souviens comme mon dernier repas...&lt;/p&gt;
+
+&lt;p&gt;Dit Tommy le Chat en jetant la tête en arrière pour dégager
+ce corps étranger qui s'était niché au fond de sa redoutable gueule.
+Beaucoup de rats bien gras trépassèrent dans la ruelle en regardant l'étoile
+brillant au fond du canon de cet extraordinaire rôdeur en quête de proie.
+Un véritable miracle de la nature ce prédateur urbain — Tommy le Chat
+avait beaucoup d'histoires à raconter. Mais il ne le faisait qu'en de rares
+occasions, comme maintenant.&lt;/p&gt;</pre>
+
+<pre class="brush: css">html {
+ font-size: 10px;
+}
+
+h1 {
+ font-size: 2.6rem;
+ text-transform: capitalize;
+ text-shadow: -1px -1px 1px #aaa,
+ 0px 2px 1px rgba(0,0,0,0.5),
+ 2px 2px 2px rgba(0,0,0,0.7),
+ 0px 0px 3px rgba(0,0,0,0.4);
+ text-align: center;
+}
+
+h1 + p {
+ font-weight: bold;
+}
+
+p::first-line {
+ letter-spacing: 2px;
+ word-spacing: 4px;
+}
+
+p {
+ font-size: 1.4rem;
+ color: red;
+ font-family: Helvetica, Arial, sans-serif;
+ line-height: 1.5;
+}</pre>
+</div>
+
+<p>{{ EmbedLiveSample('Espacement_entre_les_lettres_et_les_mots', '100%', 250) }}</p>
+
+<h3 id="D'autres_propriétés_intéressantes">D'autres propriétés intéressantes</h3>
+
+<p>Les propriétés ci-dessus donnent un début d'idée de la manière de composer un style pour un texte de page web, mais beaucoup d'autres propriétés peuvent être utilisées. Nous n'avons juste évoqué que les plus importantes. Une fois que vous serez un familier de l'utilisation de ce qui précède, explorez donc ce qui suit :</p>
+
+<p>Styles de police de caractères :</p>
+
+<ul>
+ <li>{{cssxref("font-variant")}} : bascule entre petites majuscules et police normale, et réciproquement.</li>
+ <li>{{cssxref("font-kerning")}} : active et désactive les options de crénage des polices.</li>
+ <li>{{cssxref("font-feature-settings")}} : active et désactive les fonctionnalités des polices de caractères <a href="https://en.wikipedia.org/wiki/OpenType">OpenType</a>.</li>
+ <li>{{cssxref("font-variant-alternates")}} : contrôle l'utilisation de glyphes alternatifs pour une apparence de police donnée.</li>
+ <li>{{cssxref("font-variant-caps")}}: contrôle l'utilisation de glyphes alternatifs en capitales.</li>
+ <li>{{cssxref("font-variant-east-asian")}} : contrôle l'utilisation de glyphes alternatifs pour les écritures des pays de l'est de l'Asie, comme le japonais ou le chinois.</li>
+ <li>{{cssxref("font-variant-ligatures")}} : contrôle les ligatures et formes contextuelles utilisées dans le texte.</li>
+ <li>{{cssxref("font-variant-numeric")}} : contrôle l'utilisation de glyphes alternatifs pour les nombres, les fractions et les marqueurs ordinaux.</li>
+ <li>{{cssxref("font-variant-position")}} : contrôle l'utilisation de glyphes alternatifs de plus petites tailles positionnés en exposant ou en indice.</li>
+ <li>{{cssxref("font-size-adjust")}} : ajuste la taille visuelle de la police indépendamment de sa taille réelle.</li>
+ <li>{{cssxref("font-stretch")}} : bascule entre les versions étirées alternatives possibles d'une police donnée.</li>
+ <li>{{cssxref("text-underline-position")}} : définit la position du soulignement avec la valeur <code>underline</code> pour la propriété <code>text-decoration-line</code>.</li>
+ <li>{{cssxref("text-rendering")}} : essaye d'effectuer une optimisation du rendu du texte.</li>
+</ul>
+
+<p>styles de mise en page du texte</p>
+
+<ul>
+ <li>{{cssxref("text-indent")}} : indique le nombre d'espaces à ménager horizontalement avant le début de la première ligne de texte du contenu.</li>
+ <li>{{cssxref("text-overflow")}} : définit la façon de signaler aux utilisateurs le contenu en débordement (et donc non affiché).</li>
+ <li>{{cssxref("white-space")}} : définit comment les espaces blancs et les sauts de ligne associés dans l'élément sont gérés.</li>
+ <li>{{cssxref("word-break")}} : spécifie s'il y a césure dans les mots.</li>
+ <li>{{cssxref("direction")}} : définit la direction du texte (cela dépend de la langue et généralement, il vaut mieux laisser HTML la gérer car elle est liée au contenu du texte.)</li>
+ <li>{{cssxref("hyphens")}} : active et désactive la césure pour les langues prises en charge.</li>
+ <li>{{cssxref("line-break")}} : détend ou renforce la rupture de ligne pour les langues asiatiques.</li>
+ <li>{{cssxref("text-align-last")}} : définit comment la dernière ligne d'un bloc ou d'une ligne, juste avant un saut de ligne forcé, est alignée.</li>
+ <li>{{cssxref("text-orientation")}} : définit l'orientation du texte dans une ligne.</li>
+ <li>{{cssxref("word-wrap")}} : indique si le navigateur peut replier une ligne en conservant l'ordre des mots pour empêcher un débordement.</li>
+ <li>{{cssxref("writing-mode")}} : définit si les lignes de texte sont disposées horizontalement ou verticalement et la direction des lignes suivantes.</li>
+</ul>
+
+<h2 id="Abréviations_pour_propriétés_de_fontes">Abréviations pour propriétés de fontes</h2>
+
+<p>De nombreuses propriétés des fontes peuvent être déclarées de manière abrégée avec {{cssxref("font")}}. Elles sont écrites dans l'ordre suivant : {{cssxref("font-style")}}, {{cssxref("font-variant")}}, {{cssxref("font-weight")}}, {{cssxref("font-stretch")}}, {{cssxref("font-size")}}, {{cssxref("line-height")}} et {{cssxref("font-family")}}.</p>
+
+<p>Parmi toutes ces propriétés, seules <code>font-size</code> et <code>font-family</code> sont requises lorsque la propriété abrégée <code>font</code> est utilisée.</p>
+
+<p>Une barre oblique doit être placée entre les propriétés {{cssxref("font-size")}} et {{cssxref("line-height")}}.</p>
+
+<p>Un exemple complet ressemblerait à ceci :</p>
+
+<pre class="brush: css">font: italic normal bold normal 3em/1.5 Helvetica, Arial, sans-serif;</pre>
+
+<h2 id="Apprentissage_actif_jouer_avec_les_styles_du_texte">Apprentissage actif : jouer avec les styles du texte</h2>
+
+<p>Dans cette session d'apprentissage actif, nous n'avons pas d'exercice spécifique à vous proposer : nous voulons juste vous permettre de jouer avec certaines propriétés de police ou mise en page de texte et de voir ce que vous pouvez produire ! Vous pouvez le faire en utilisant des fichiers HTML / CSS hors ligne ou en entrant votre code dans l'exemple modifiable en direct ci-dessous.</p>
+
+<p>Si vous faites une erreur, vous pouvez toujours <em>Réinitialiser</em> avec le bouton de même nom.</p>
+
+<div class="hidden">
+<h6 id="Playable_code">Playable code</h6>
+
+<pre class="brush: html">&lt;div class="body-wrapper" style="font-family: 'Open Sans Light',Helvetica,Arial,sans-serif;"&gt;
+ &lt;h2&gt;Zone de saisie du HTML&lt;/h2&gt;
+ &lt;textarea id="code" class="html-input" style="width: 90%;height: 10em;padding: 10px;border: 1px solid #0095dd;"&gt;
+ &lt;p&gt;Un peu de texte pour vous délecter !&lt;/p&gt;&lt;/textarea&gt;
+
+ &lt;h2&gt;Zone de saisie de la CSS&lt;/h2&gt;
+ &lt;textarea id="code" class="css-input" style="width: 90%;height: 10em;padding: 10px;border: 1px solid #0095dd;"&gt;p {
+
+ }&lt;/textarea&gt;
+
+ &lt;h2&gt;Zone de rendu&lt;/h2&gt;
+ &lt;div class="output" style="width: 90%;height: 10em;padding: 10px;border: 1px solid #0095dd;"&gt;&lt;/div&gt;
+ &lt;div class="controls"&gt;
+ &lt;input id="reset" type="button" value="Réinitialiser" style="margin: 10px 10px 0 0;"&gt;
+ &lt;/div&gt;
+&lt;/div&gt;
+</pre>
+
+<pre class="brush: js">var htmlInput = document.querySelector(".html-input");
+var cssInput = document.querySelector(".css-input");
+var reset = document.getElementById("reset");
+var htmlCode = htmlInput.value;
+var cssCode = cssInput.value;
+var output = document.querySelector(".output");
+
+var styleElem = document.createElement('style');
+var headElem = document.querySelector('head');
+headElem.appendChild(styleElem);
+
+function drawOutput() {
+ output.innerHTML = htmlInput.value;
+ styleElem.textContent = cssInput.value;
+}
+
+reset.addEventListener("click", function() {
+ htmlInput.value = htmlCode;
+ cssInput.value = cssCode;
+ drawOutput();
+});
+
+htmlInput.addEventListener("input", drawOutput);
+cssInput.addEventListener("input", drawOutput);
+window.addEventListener("load", drawOutput);
+</pre>
+</div>
+
+<p>{{ EmbedLiveSample('Playable_code', 700, 800) }}</p>
+
+<h2 id="Résumé">Résumé</h2>
+
+<p>Nous espérons que vous avez aimé jouer avec le texte dans cet article ! Le prochain article vous donnera tout ce que vous devez savoir sur le style des listes HTML.</p>
+
+<p>{{NextMenu("Learn/CSS/Styling_text/Styling_lists", "Learn/CSS/Styling_text")}}</p>
+
+<h2 id="Dans_ce_module">Dans ce module</h2>
+
+<p> </p>
+
+<ul>
+ <li><a href="/fr/docs/Learn/CSS/Styling_text/initiation-mise-en-forme-du-texte">Initiation à la mise en forme du texte</a></li>
+ <li><a href="/fr/docs/Learn/CSS/Styling_text/Styling_lists">Style de listes</a></li>
+ <li><a href="/fr/docs/Learn/CSS/Styling_text/Mise_en_forme_des_liens">Mise en forme des liens</a></li>
+ <li><a class="new" href="https://developer.mozilla.org/fr/docs/Learn/CSS/Styling_text/Web_fonts" rel="nofollow">Polices de caractères web</a></li>
+ <li><a class="new" href="https://developer.mozilla.org/fr/docs/Learn/CSS/Styling_text/Typesetting_a_homepage" rel="nofollow">Composition d'une page d'accueil d'une école communale</a></li>
+</ul>
+
+<p> </p>
+
+<p> </p>
diff --git a/files/fr/learn/css/styling_text/mise_en_forme_des_liens/index.html b/files/fr/learn/css/styling_text/mise_en_forme_des_liens/index.html
new file mode 100644
index 0000000000..f216d54186
--- /dev/null
+++ b/files/fr/learn/css/styling_text/mise_en_forme_des_liens/index.html
@@ -0,0 +1,448 @@
+---
+title: Mise en forme des liens
+slug: Learn/CSS/Styling_text/Mise_en_forme_des_liens
+tags:
+ - Article
+ - Beginner
+ - CSS
+ - Focus
+ - Guide
+ - Learn
+ - Links
+ - Pseudo-class
+ - hover
+ - hyperlinks
+ - menus
+ - tabs
+translation_of: Learn/CSS/Styling_text/Styling_links
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/CSS/Styling_text/Styling_lists", "Learn/CSS/Styling_text/Web_fonts", "Learn/CSS/Styling_text")}}</div>
+
+<p class="summary">Lors de la mise en forme de <a href="/fr/Apprendre/HTML/Introduction_%C3%A0_HTML/Creating_hyperlinks">liens</a>, il est important de comprendre comment utiliser les pseudo-classes pour mettre en forme efficacement les états des liens, et comment créer des liens pour les utiliser dans diverses fonctionnalités d'interface courantes, telles que les menus de navigation et les onglets. Nous allons examiner tous ces sujets dans cet article.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Prérequis :</th>
+ <td>notions de base en informatique, notions de base en HTML (étudier l'<a href="/fr/Apprendre/HTML/Introduction_%C3%A0_HTML">Introduction au HTML)</a>, notions de base en CSS (étudier l'<a href="/fr/Apprendre/CSS/Introduction_%C3%A0_CSS">Introduction à CSS</a>), <a href="/fr/docs/Learn/CSS/Styling_text/initiation-mise-en-forme-du-texte">initiation à la mise en forme de texte</a>.</td>
+ </tr>
+ <tr>
+ <th scope="row">Objectif :</th>
+ <td>apprendre à mettre en forme les états des liens, et comment utiliser efficacement les liens dans les fonctionnalités courantes de l'IU, comme les menus de navigation.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Un_coup_dœil_à_quelques_liens">Un coup d'œil à quelques liens</h2>
+
+<p>Nous avons regardé comment les liens sont implémentés dans votre HTML selon les meilleures pratiques dans <a href="/fr/Apprendre/HTML/Introduction_%C3%A0_HTML/Creating_hyperlinks">Création d'hyperliens</a>. Dans cet article, nous allons développer ces connaissances en vous montrant les meilleures pratiques pour la mise en forme de liens.</p>
+
+<h3 id="État_des_liens">État des liens</h3>
+
+<p>La première chose à comprendre est le concept d'états des liens : les différents états dans lesquels les liens peuvent exister, qui peuvent être mis en forme en utilisant différentes <a href="/fr/Apprendre/CSS/Introduction_%C3%A0_CSS/Les_s%C3%A9lecteurs">pseudo-classes</a> :</p>
+
+<ul>
+ <li><strong>link (non visité)</strong> : l'état par défaut dans lequel se trouve un lien, lorsqu'il n'est dans aucun autre état ; cela peut être spécifiquement mis en forme en utilisant la pseudo classe {{cssxref(":link")}} ;</li>
+ <li><strong>visited :</strong> un lien qui a déjà été visité (qui existe dans l'historique du navigateur), mis en forme en utilisant la pseudo-classe {{cssxref(":visited")}} ;</li>
+ <li><strong>hover :</strong> un lien qui est survolé par le pointeur de la souris de l'utilisateur, mis en forme en utilisant la pseudo classe {{cssxref(":hover")}} ;</li>
+ <li><strong>focus :</strong> un lien qui a reçu la focalisation (par exemple, quand l'utilisateur du clavier s'est déplacé en utilisant la touche <kbd>Tab</kbd> ou similaire, ou qui a reçu la focalisation par programmation par utilisation de {{domxref("HTMLElement.focus()")}}) ; ceci est mis en forme en utilisant la pseudo-classe {{cssxref(":focus")}} ;</li>
+ <li><strong>active :</strong> un lien en cours d'activation (par exemple, lorsqu'on clique dessus), mis en forme en utilisant la pseudo classe {{cssxref (":active")}}.</li>
+</ul>
+
+<h3 id="Styles_par_défaut">Styles par défaut</h3>
+
+<p>L'exemple suivant illustre le comportement d'un lien par défaut (le CSS simplement agrandit et centre le texte pour le rendre plus visible).</p>
+
+<pre class="brush: html notranslate">&lt;p&gt;&lt;a href="#"&gt;Un simple lien&lt;/a&gt;&lt;/p&gt;
+</pre>
+
+<pre class="brush: css notranslate">p {
+ font-size: 2rem;
+ text-align: center;
+}</pre>
+
+<p>{{ EmbedLiveSample('Styles_par_défaut', '100%', 120) }}</p>
+
+<div class="note">
+<p><strong>Note </strong>: tous les liens dans les exemples de cette page sont de faux liens : un # (hash, ou signe dièse) est mis à la place de l'URL réelle. En effet, si des liens réels étaient inclus, un simple clic sur ceux-ci cassererait les exemples (vous vous retrouveriez avec une erreur, ou une page chargée dans l'exemple intégré de laquelle vous ne pourriez pas revenir) ; # ne redirige que vers la page actuelle.</p>
+</div>
+
+<p>Vous remarquerez quelques petites choses en explorant les styles par défaut :</p>
+
+<ul>
+ <li>les liens sont soulignés ;</li>
+ <li>les liens non visités sont bleus ;</li>
+ <li>les liens visités sont en violet ;</li>
+ <li>le survol d'un lien fait se changer en petite icône de main le pointeur de la souris ;</li>
+ <li>les liens ayant reçus la focalisation ont un contour autour d'eux : vous devriez pouvoir vous focaliser sur les liens de cette page avec le clavier en appuyant sur la touche <kbd>Tab</kbd> (sur Mac, il se peut que vous ayez besoin d'activer l'option <em>Accès clavier complet : Toutes les commandes</em> en appuyant sur <kbd>Ctrl</kbd> + <kbd>F7</kbd> pour que cela fonctionne) ;</li>
+ <li>les liens actifs sont rouges (essayez de maintenir le bouton de la souris enfoncé sur le lien lorsque vous cliquez dessus).</li>
+</ul>
+
+<p>De façon assez intéressante, ces styles par défaut sont pratiquement les mêmes que ce qu'ils étaient aux premiers temps des navigateurs, au milieu des années 1990. C'est parce que les utilisateurs connaissent - et s'attendent à - ce comportement ; si les liens étaient mis en forme différemment, cela créerait beaucoup de confusion. Cela ne signifie pas que vous ne deviez pas du tout mettre en forme les liens, mais simplement que vous ne devriez pas vous éloigner trop du comportement attendu. Vous devriez au moins :</p>
+
+<ul>
+ <li>utiliser le soulignement pour les liens, mais pas pour d'autres choses ; si vous ne voulez pas souligner les liens, au moins les mettre en évidence d'une autre manière ;</li>
+ <li>les faire réagir d'une manière ou d'une autre lorsqu'ils sont survolés ou lorsqu'ils ont reçu la focalisation, et d'une manière légèrement différente lorsqu'ils sont activés.</li>
+</ul>
+
+<p>Les styles par défaut peuvent être désactivés/modifiés en utilisant les propriétés CSS suivantes :</p>
+
+<ul>
+ <li>{{cssxref ("color")}} pour la couleur du texte ;</li>
+ <li>{{cssxref ("cursor")}} pour le style du pointeur de la souris - vous ne devriez pas le désactiver, à moins d'avoir une très bonne raison ;</li>
+ <li>{{cssxref ("outline")}} pour le contour du texte (un contour est similaire à une bordure, la seule différence étant que la bordure occupe de l'espace dans la boîte et non un contour, elle se trouve juste au-dessus du Contexte) ; le contour est une aide utile à l'accessibilité, alors réfléchissez bien avant de la désactiver ; vous devriez au moins dupliquer aussi les styles affectés à l'état link hover sur l'état de focalisation.</li>
+</ul>
+
+<div class="note">
+<p><strong>Note </strong>: vous n'êtes pas limité aux propriétés ci-dessus pour mettre en forme vos liens ; vous êtes libre d'utiliser les propriétés que vous aimez. Essayez seulement de ne pas devenir trop fou !</p>
+</div>
+
+<h3 id="Mise_en_forme_de_quelques_liens">Mise en forme de quelques liens</h3>
+
+<p>Maintenant que nous avons examiné les états par défaut en détail, regardons un ensemble typique de mises en forme de liens.</p>
+
+<p>Pour commencer, nous écrirons notre jeu de règles vides :</p>
+
+<pre class="brush: css notranslate">a {
+
+}
+
+
+a:link {
+
+}
+
+a:visited {
+
+}
+
+a:focus {
+
+}
+
+a:hover {
+
+}
+
+a:active {
+
+}</pre>
+
+<p>Cet ordre est important parce que les styles de liens se construisent les uns par dessus les autres ; par exemple, les styles de la première règle s'appliqueront à toutes les suivantes, et lorsqu'un lien est activé, il est également survolé. Si vous les mettez dans le mauvais ordre, les choses ne fonctionneront pas correctement. Pour se souvenir de l'ordre, vous pouvez essayer d'utiliser un moyen mnémotechnique comme La Vie Fuit la HAine (LoVe Fears HAte).</p>
+
+<p>Maintenant, ajoutons quelques informations supplémentaires pour mettre en forme cela correctement :</p>
+
+<pre class="brush: css notranslate">body {
+ width: 300px;
+ margin: 0 auto;
+ font-size: 1.2rem;
+ font-family: sans-serif;
+}
+
+p {
+ line-height: 1.4;
+}
+
+a {
+ outline: none;
+ text-decoration: none;
+ padding: 2px 1px 0;
+}
+
+a:link {
+ color: #265301;
+}
+
+a:visited {
+ color: #437A16;
+}
+
+a:focus {
+ border-bottom: 1px solid;
+ background: #BAE498;
+}
+
+a:hover {
+ border-bottom: 1px solid;
+ background: #CDFEAA;
+}
+
+a:active {
+ background: #265301;
+ color: #CDFEAA;
+}</pre>
+
+<p>Nous allons aussi fournir un extrait d'HTML auquel appliquer le CSS :</p>
+
+<pre class="brush: html notranslate">&lt;p&gt;Il y a plusieurs navigateurs disponibles, tels que &lt;a href="#"&gt;Mozilla
+Firefox&lt;/a&gt;, &lt;a href="#"&gt;Google Chrome&lt;/a&gt;, et
+&lt;a href="#"&gt;Microsoft Edge&lt;/a&gt;.&lt;/p&gt;</pre>
+
+<p>En mettant les deux ensemble, nous obtenons ce résultat :</p>
+
+<p>{{EmbedLiveSample('Mise_en_forme_de_quelques_liens', '100%', 150)}}</p>
+
+<p>Alors qu'avons-nous fait ici ? Cela semble certainement différent de la mise en forme par défaut, mais cela donne toujours une expérience suffisamment familière pour que les utilisateurs sachent ce qui se passe :</p>
+
+<ul>
+ <li>les deux premières règles ne sont pas très intéressantes pour cette discussion ;</li>
+ <li>la troisième règle utilise le sélecteur <code>a</code> pour se débarasser du soulignement de texte par défaut et du contour de focalisation (qui varie d'un navigateur à l'autre), et elle ajoute une petite quantité de remplissage à chaque lien ; tout ceci deviendra clair plus tard ;</li>
+ <li>ensuite, nous utilisons les sélecteurs <code>a:link</code> et <code>a:visited</code> pour définir deux variations de couleur sur les liens non visités et visités, afin qu'ils soient distincts ;</li>
+ <li>les deux règles suivantes utilisent <code>a:focus</code> et <code>a:hover</code> pour faire que les liens centrés et survolés aient des couleurs d'arrière-plan différentes, plus un soulignement afin que le lien se démarque encore davantage ; deux points à noter ici :
+ <ul>
+ <li>le soulignement a été créé en utilisant {{cssxref("border-bottom")}}, pas {{cssxref("text-decoration")}} ; certaines personnes préfèrent cela parce que le premier a de meilleures options de mise en forme que le second, et qu'il est tracé un peu plus bas, de sorte qu'il ne coupe pas les jambages du mot souligné (par exemple, les jambes du g et du y) ;</li>
+ <li>la valeur {{cssxref("border-bottom")}} a été définie comme <code>1px solid</code>, sans couleur indiquée ; cela fait que la bordure adopte la même couleur que le texte de l'élément, ce qui est utile dans des cas comme celui-ci, où le texte a une couleur différente dans chaque cas ;</li>
+ </ul>
+ </li>
+ <li>enfin, <code>a:active</code> est utilisé pour donner aux liens un schéma de couleurs inversé pendant qu'ils sont activés, afin de faire comprendre que quelque chose d'important est en train de se passer !</li>
+</ul>
+
+<h3 id="Apprentissage_actif_mettez_en_forme_vos_propres_liens">Apprentissage actif : mettez en forme vos propres liens</h3>
+
+<p>Dans cette session d'apprentissage actif, nous aimerions que vous utilisiez notre ensemble de règles vide, et que vous ajoutiez vos propres déclarations pour que les liens soient vraiment cools. Utilisez votre imagination, soyez fou. Nous sommes sûrs que vous pourrez trouver quelque chose d'encore plus cool et tout aussi fonctionnel que notre exemple ci-dessus.</p>
+
+<p>Si vous faites une erreur, vous pouvez toujours l'annuler en utilisant le bouton <em>Réinitialiser</em>. Si vous êtes vraiment bloqué, appuyez sur le bouton <em>Afficher la solution</em> pour insérer l'exemple que nous avons montré ci-dessus.</p>
+
+<div class="hidden">
+<h5 id="Playable_code">Playable code</h5>
+
+<pre class="brush: html notranslate">&lt;div class="body-wrapper" style="font-family: 'Open Sans Light',Helvetica,Arial,sans-serif;"&gt;
+ &lt;h2&gt;Zone de saisie HTML&lt;/h2&gt;
+ &lt;textarea id="code" class="html-input" style="width: 90%;height: 10em;padding: 10px;border: 1px solid #0095dd;"&gt;&lt;p&gt;Il y a plusieurs navigateurs disponibles, tels que &lt;a href="#"&gt;Mozilla
+ Firefox&lt;/a&gt;, &lt;a href="#"&gt;Google Chrome&lt;/a&gt;, et
+&lt;a href="#"&gt;Microsoft Edge&lt;/a&gt;.&lt;/p&gt;&lt;/textarea&gt;
+
+ &lt;h2&gt;Zone de saisie de la CSS&lt;/h2&gt;
+ &lt;textarea id="code" class="css-input" style="width: 90%;height: 10em;padding: 10px;border: 1px solid #0095dd;"&gt;a {
+
+}
+
+a:link {
+
+}
+
+a:visited {
+
+}
+
+a:focus {
+
+}
+
+a:hover {
+
+}
+
+a:active {
+
+}&lt;/textarea&gt;
+
+ &lt;h2&gt;Zone de rendu&lt;/h2&gt;
+ &lt;div class="output" style="width: 90%;height: 10em;padding: 10px;border: 1px solid #0095dd;"&gt;&lt;/div&gt;
+ &lt;div class="controls"&gt;
+  &lt;input id="reset" type="button" value="Réinitialiser" style="margin: 10px 10px 0 0;"&gt;
+ &lt;input id="solution" type="button" value="Voir la solution" style="margin: 10px 0 0 10px;"&gt;
+ &lt;/div&gt;
+&lt;/div&gt;
+</pre>
+
+<pre class="brush: js notranslate">var htmlInput = document.querySelector(".html-input");
+var cssInput = document.querySelector(".css-input");
+var reset = document.getElementById("reset");
+var htmlCode = htmlInput.value;
+var cssCode = cssInput.value;
+var output = document.querySelector(".output");
+var solution = document.getElementById("solution");
+
+var styleElem = document.createElement('style');
+var headElem = document.querySelector('head');
+headElem.appendChild(styleElem);
+
+function drawOutput() {
+ output.innerHTML = htmlInput.value;
+ styleElem.textContent = cssInput.value;
+}
+
+reset.addEventListener("click", function() {
+  htmlInput.value = htmlCode;
+  cssInput.value = cssCode;
+  drawOutput();
+});
+
+solution.addEventListener("click", function() {
+ htmlInput.value = htmlCode;
+ cssInput.value = 'p {\n font-size: 1.2rem;\n font-family: sans-serif;\n line-height: 1.4;\n}\n\na {\n outline: none;\n text-decoration: none;\n padding: 2px 1px 0;\n}\n\na:link {\n color: #265301;\n}\n\na:visited {\n color: #437A16;\n}\n\na:focus {\n border-bottom: 1px solid;\n background: #BAE498;\n}\n\na:hover {\n border-bottom: 1px solid;\n background: #CDFEAA;\n}\n\na:active {\n background: #265301;\n color: #CDFEAA;\n}';
+ drawOutput();
+});
+
+htmlInput.addEventListener("input", drawOutput);
+cssInput.addEventListener("input", drawOutput);
+window.addEventListener("load", drawOutput);
+</pre>
+</div>
+
+<p>{{ EmbedLiveSample('Playable_code', 700, 800) }}</p>
+
+<h2 id="Inclusion_dicônes_dans_des_liens">Inclusion d'icônes dans des liens</h2>
+
+<p>Une pratique courante consiste à inclure des icônes dans des liens pour fournir plus d'un indicateur concernant le type de contenu vers lequel le lien pointe. Regardons un exemple très simple qui ajoute une icône à des liens externes (les liens qui mènent à d'autres sites). Une telle icône ressemble généralement à une petite flèche pointant hors d'une boîte ; pour cet exemple, nous allons utiliser cet excellent exemple de icons8.com.</p>
+
+<p>Regardons un peu d'HTML et de CSS qui nous donneront l'effet que nous voulons. Tout d'abord, un peu d'HTML simple à mettre en forme :</p>
+
+<pre class="brush: html notranslate">&lt;p&gt;Pour davantage d'information sur la météo, visitez notre &lt;a href="http://#"&gt;page météo&lt;/a&gt;,
+jetez un œil sur &lt;a href="http://#"&gt;météo sur Wikipedia&lt;/a&gt;, ou regardez la &lt;a href="http://#"&gt;météo sur Science Extrême &lt;/a&gt;.&lt;/p&gt;</pre>
+
+<p>Ensuite, le CSS:</p>
+
+<pre class="brush: css notranslate">body {
+ width: 300px;
+ margin: 0 auto;
+ font-family: sans-serif;
+}
+
+p {
+ line-height: 1.4;
+}
+
+a {
+ outline: none;
+ text-decoration: none;
+ padding: 2px 1px 0;
+}
+
+a:link {
+ color: blue;
+}
+
+a:visited {
+ color: purple;
+}
+
+a:focus, a:hover {
+ border-bottom: 1px solid;
+}
+
+a:active {
+ color: red;
+}
+
+a[href*="http"] {
+ background: url('https://mdn.mozillademos.org/files/12982/external-link-52.png') no-repeat 100% 0;
+ background-size: 16px 16px;
+ padding-right: 19px;
+}</pre>
+
+<p>{{ EmbedLiveSample("Inclusion_d'icônes_dans_des_liens", '100%', 150) }}</p>
+
+<p>Alors, qu'est-ce qui se passe ici ? Nous allons sauter le gros du CSS, du fait que c'est seulement la même information que celle que vous avez déjà regardée. La dernière règle est cependant intéressante : ici, nous insérons une image d'arrière-plan personnalisée sur les liens externes d'une manière similaire à celle dont nous avons traité les puces personnalisées sur les éléments de liste dans le dernier article ; cette fois, nous utilisons le raccourci {{cssxref("background")}} au lieu des propriétés individuelles. Nous définissons le chemin vers l'image que nous voulons insérer, nous spécifions <code>no-repeat</code> de façon à obtenir l'insertion d'une seule une copie, puis nous indiquons la position comme étant 100% de la distance à droite du contenu du texte, et 0 pixels à partir du haut.</p>
+
+<p>Nous utilisons également {{cssxref("background-size")}} pour indiquer à quelle taille nous voulons afficher l'image d'arrière-plan - il est utile d'avoir une icône plus grande et de la redimensionner comme nécessaire dans un but de conception web adaptative. Cela ne fonctionne cependant qu'avec IE 9 et ultérieur, donc si vous avez besoin de prendre en charge ces navigateurs plus anciens, il vous suffira de redimensionner l'image et de l'insérer telle quelle.</p>
+
+<p>Enfin, nous avons mis un peu de {{cssxref("padding-right")}} sur les liens pour faire de la place afin que l'image d'arrière-plan se place à l'intérieur, de sorte que nous ne la faisions chevaucher le texte.</p>
+
+<p>Un dernier mot : comment avons-nous sélectionné uniquement les liens externes ? Eh bien, si vous écrivez vos liens HTML correctement, vous ne devriez utiliser des URL absolues que pour les liens externes : il est plus efficace d'utiliser des liens relatifs pour la redirection vers d'autres parties de votre propre site. Le texte "http" ne devrait donc apparaître que dans les liens externes, et nous pouvons le sélectionner avec un <a href="/fr/Apprendre/CSS/Introduction_%C3%A0_CSS/Les_s%C3%A9lecteurs">sélecteur d'attribut</a> : <code>a[href*="http]</code> sélectionne les éléments {{htmlelement("a")}}, mais seulement s'ils ont un attribut {{htmlattrxref ("href","a")}} ayant une valeur contenant "http" quelque part à l'intérieur.</p>
+
+<p>Alors voilà, essayez de revoir la section d'apprentissage actif ci-dessus et d'explorer cette nouvelle technique !</p>
+
+<div class="note">
+<p><strong>Note </strong>: ne vous inquiétez pas si vous n'êtes pas encore familier avec les <a href="/fr/Apprendre/CSS/styliser_boites">arrières-plans</a> et le <a href="/fr/Apps/app_layout/responsive_design_building_blocks">responsive web design</a> ; ceux-ci sont expliqués par ailleurs.</p>
+</div>
+
+<h2 id="Mise_en_forme_de_liens_comme_des_boutons">Mise en forme de liens comme des boutons</h2>
+
+<p>Les outils que vous avez explorés jusqu'à présent dans cet article peuvent également être utilisés d'autres façons. Par exemple, des états tels que hover peuvent être utilisés pour mettre en forme de nombreux éléments différents, pas seulement des liens : vous pouvez définir l'état de survol des paragraphes, des éléments de liste ou d'autres choses.</p>
+
+<p>En outre, les liens sont très couramment mis en forme de façon à ressembler et à se comporter comme des boutons dans certaines circonstances : un menu de navigation de site Web est généralement balisé comme une liste contenant des liens, et cela peut facilement être mis en forme pour ressembler à un ensemble de boutons de contrôle ou d'onglets qui fournissent à l'utilisateur un accès à d'autres parties du site. Voyons comment.</p>
+
+<p>D'abord, un peu d'HTML :</p>
+
+<pre class="brush: html notranslate">&lt;ul&gt;
+ &lt;li&gt;&lt;a href="#"&gt;Accueil&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#"&gt;Pizza&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#"&gt;Musique&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#"&gt;Wombats&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="#"&gt;Finland&lt;e/a&gt;&lt;/li&gt;
+&lt;/ul&gt;</pre>
+
+<p>Et maintenant, notre CSS :</p>
+
+<pre class="brush: css notranslate">body,html {
+ margin: 0;
+ font-family: sans-serif;
+}
+
+ul {
+ padding: 0;
+ width: 100%;
+}
+
+li {
+ display: inline;
+}
+
+a {
+  outline: none;
+ text-decoration: none;
+  display: inline-block;
+  width: 19.5%;
+  margin-right: 0.625%;
+  text-align: center;
+  line-height: 3;
+  color: black;
+}
+
+li:last-child a {
+  margin-right: 0;
+}
+
+a:link, a:visited, a:focus {
+ background: yellow;
+}
+
+a:hover {
+ background: orange;
+}
+
+a:active {
+ background: red;
+ color: white;
+}</pre>
+
+<p>Cela nous donne le résultat suivant :</p>
+
+<p>{{ EmbedLiveSample('Mise_en_forme_de_liens_comme_des_boutons', '100%', 100) }}</p>
+
+<p>Expliquons ce qui se passe ici, en nous concentrant sur les parties les plus intéressantes :</p>
+
+<ul>
+ <li>notre deuxième règle supprime le {{cssxref("padding")}} par défaut de l'élément {{htmlelement ("ul")}}, et définit sa largeur de façon à couvrir 100% du conteneur externe (le {{htmlelement("body")}} dans ce cas) ;</li>
+ <li>par défaut, les éléments {{htmlelement("li")}} se présentent normalement sous forme de blocs (voir les types de boîtes CSS pour rappel), ce qui signifie qu'ils vont se trouver sur leurs propres lignes ; dans ce cas, nous créons une liste horizontale de liens ; pour cela, dans la troisième règle, nous mettons la propriété {{cssxref("display")}} à inline, ce qui fait que les éléments de la liste se trouvent tous sur la même ligne : ils se comportent maintenant comme des éléments inline ;</li>
+ <li>la quatrième règle, qui met en forme l'élément {{htmlelement("a")}}, est la plus compliquée ici ; passons-la en revue étape par étape :
+ <ul>
+ <li>comme dans les exemples précédents, nous commençons par désactiver la valeur par défaut {{cssxref("text-decoration")}} et {{cssxref("outline")}} : nous ne voulons pas que ceux-ci gâchent notre présentation ;</li>
+ <li>ensuite, nous mettons le {{cssxref ("display")}} à <code>inline-block</code> : les éléments {{htmlelement ("a")}} sont inline par défaut et, bien que nous ne voulions pas qu'ils s'étalent sur leurs propres lignes comme une valeur de <code>block</code> le ferait, nous voulons néanmoins être en mesure de les dimensionner : <code>inline-block</code> nous permet de le réaliser ;</li>
+ <li>maintenant, passons au dimensionnement ; nous voulons remplir toute la largeur de l'{{htmlelement("ul")}}, laisser une petite marge entre chaque bouton (mais sans espace sur le bord droit), et nous avons 5 boutons pour accueillir tout cela, qui doit avoir la même taille ; pour ce faire, nous définissons la {{cssxref ("width")}} à 19,5%, et la {{cssxref ("margin-right")}} à 0,625% ; vous remarquerez que toute cette largeur s'élève à 100,625%, ce qui ferait que le dernier bouton déborde sur l'<code>&lt;ul&gt;</code> et passe à la ligne suivante ; cependant, nous le ramenons à 100%, en utilisant la règle suivante, qui sélectionne seulement le dernier <code>&lt;a&gt;</code> dans la liste, et en supprime la marge ; terminé !</li>
+ <li>les trois dernières déclarations sont assez simples et ne sont principalement présentes qu'à des fins esthétiques ; nous centrons le texte à l'intérieur de chaque lien, nous définissons {{cssxref("line-height")}} à 3 pour donner un peu de hauteur aux boutons (ce qui a aussi l'avantage de centrer le texte verticalement) et nous définissons la couleur du texte à noir.</li>
+ </ul>
+ </li>
+</ul>
+
+<div class="note">
+<p><strong>Note</strong> : vous avez peut-être remarqué que les éléments de la liste dans le HTML sont tous placés sur la même ligne ; cela est dû au fait que les espaces/sauts de ligne entre les éléments inline block créent des espaces sur la page, tout comme des espaces entre les mots, et que de tels espaces casseraient la disposition de notre menu de navigation horizontale ; nous avons donc supprimé les espaces ; vous pouvez trouver plus d'informations (et de solutions) à propos de ce problème sur <a href="https://css-tricks.com/fighting-the-space-between-inline-block-elements/">Fighting the space between inline block elements</a>.</p>
+</div>
+
+<h2 id="Résumé">Résumé</h2>
+
+<p>Nous espérons que cet article vous a fourni tout ce que vous aviez besoin de savoir sur les liens - pour l'instant ! L'article final de notre module de Mise en forme de texte détaille comment utiliser des polices personnalisées (ou polices web, comme elles sont mieux connues) sur vos sites web.</p>
+
+<p>{{PreviousMenuNext("Learn/CSS/Styling_text/Styling_lists", "Learn/CSS/Styling_text/Web_fonts", "Learn/CSS/Styling_text")}}</p>
+
+<h2 id="Dans_ce_module">Dans ce module</h2>
+
+
+
+<ul>
+ <li><a href="/fr/docs/Learn/CSS/Styling_text/initiation-mise-en-forme-du-texte">Initiation à la mise en forme du texte</a></li>
+ <li><a href="/fr/docs/Learn/CSS/Styling_text/Styling_lists">Style de listes</a></li>
+ <li><a href="/fr/docs/Learn/CSS/Styling_text/Mise_en_forme_des_liens">Mise en forme des liens</a></li>
+ <li><a class="new" href="https://developer.mozilla.org/fr/docs/Learn/CSS/Styling_text/Web_fonts" rel="nofollow">Polices de caractères web</a></li>
+ <li><a class="new" href="https://developer.mozilla.org/fr/docs/Learn/CSS/Styling_text/Typesetting_a_homepage" rel="nofollow">Composition d'une page d'accueil d'une école communale</a></li>
+</ul>
diff --git a/files/fr/learn/css/styling_text/styling_lists/index.html b/files/fr/learn/css/styling_text/styling_lists/index.html
new file mode 100644
index 0000000000..fbbaa1fd87
--- /dev/null
+++ b/files/fr/learn/css/styling_text/styling_lists/index.html
@@ -0,0 +1,396 @@
+---
+title: Style de listes
+slug: Learn/CSS/Styling_text/Styling_lists
+tags:
+ - CSS
+ - Débutant
+ - Guide
+ - Listes
+ - Numeros
+ - Puces
+ - Styles
+ - Texte
+translation_of: Learn/CSS/Styling_text/Styling_lists
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/CSS/Styling_text/Fundamentals", "Learn/CSS/Styling_text/Styling_links", "Learn/CSS/Styling_text")}}</div>
+
+<p class="summary"><span id="result_box" lang="fr"><span>Les <a href="/fr/Apprendre/HTML/Introduction_à_HTML/HTML_text_fundamentals#Listes">listes</a> se comportent comme la plupart des autres textes, mais il existe des propriétés CSS propres aux listes que vous devez connaître, et quelques bonnes pratiques à prendre en compte.</span> <span>Cet article explique tout.</span></span></p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Prérequis :</th>
+ <td>Connaissances de base informatiques, bases HTML (étudiées dans <a href="https://developer.mozilla.org/fr/Apprendre/HTML/Introduction_%C3%A0_HTML">Introduction à HTML</a>), bases CSS (étudiées dans <a href="https://developer.mozilla.org/fr/Apprendre/CSS/Introduction_%C3%A0_CSS">Introduction à CSS</a>), <a href="https://developer.mozilla.org/fr/docs/Learn/CSS/Styling_text/initiation-mise-en-forme-du-texte">la mise en forme du texte</a>.</td>
+ </tr>
+ <tr>
+ <th scope="row">Objectif :</th>
+ <td><span id="result_box" lang="fr"><span>Se familiariser avec les meilleures pratiques et propriétés liées aux styles de liste.</span></span></td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Un_exemple_de_liste_simple">Un exemple de liste simple</h2>
+
+<p>Pour commencer, regardons un exemple de liste simple. Au long de cet article nous verrons les listes non ordonnées, ordonnées et des listes descriptives — tous les styles ont des fonctionnalités similaires, mais il existe quelques particularités en fonction du type de liste. Un exemple sans style est <a href="http://mdn.github.io/learning-area/css/styling-text/styling-lists/unstyled-list.html">disponible sur Github</a> (voyez aussi le <a href="https://github.com/mdn/learning-area/blob/master/css/styling-text/styling-lists/unstyled-list.html">code source</a>).</p>
+
+<p><span id="result_box" lang="fr"><span>Le code HTML pour nos exemples de liste ressemble à ceci :</span></span></p>
+
+<pre class="brush: html">&lt;h2&gt;Liste de courses (non ordonnée)&lt;/h2&gt;
+
+&lt;p&gt;Paragraphe de référence, paragraphe de référence, paragraphe de référence,
+paragraphe de référence, paragraphe de référence, paragraphe de référence.&lt;/p&gt;
+
+&lt;ul&gt;
+ &lt;li&gt;Houmous&lt;/li&gt;
+ &lt;li&gt;Pain blanc&lt;/li&gt;
+ &lt;li&gt;Salade verte&lt;/li&gt;
+ &lt;li&gt;Fromage halloumi&lt;/li&gt;
+&lt;/ul&gt;
+
+&lt;h2&gt;Liste de recette (ordonnée)&lt;/h2&gt;
+
+&lt;p&gt;paragraphe de référence, paragraphe de référence, paragraphe de référence,
+paragraphe de référence, paragraphe de référence, paragraphe de référence.&lt;/p&gt;
+
+&lt;ol&gt;
+ &lt;li&gt;Faire griller le pain pitta, laisser refroidir, puis le trancher sur le côté.&lt;/li&gt;
+ &lt;li&gt;Frire l'halloumi dans une poêle plate antiadhésive, jusqu'à ce qu'il soit doré des deux côtés.&lt;/li&gt;
+ &lt;li&gt;Laver et hacher la salade.&lt;/li&gt;
+ &lt;li&gt;Mettre la salade, l'houmous et l'halloumi frit entre les tranches de pain.&lt;/li&gt;
+&lt;/ol&gt;
+
+&lt;h2&gt;Liste descriptive des ingrédients&lt;/h2&gt;
+
+&lt;p&gt;paragraphe de référence, paragraphe de référence, paragraphe de référence,
+paragraphe de référence, paragraphe de référence, paragraphe de référence.&lt;/p&gt;
+
+&lt;dl&gt;
+ &lt;dt&gt;Houmous&lt;/dt&gt;
+ &lt;dd&gt;Une purée ou sauce épaisse généralement faite de pois chiches mélangés avec du tahini, du jus de citron, du sel, de l'ail et d'autres aromates.&lt;/dd&gt;
+ &lt;dt&gt;Pain pitta&lt;/dt&gt;
+ &lt;dd&gt;Un pain plat moelleux, légèrement levé.&lt;/dd&gt;
+ &lt;dt&gt;Halloumi&lt;/dt&gt;
+ &lt;dd&gt;Fromage à pâte mi-dure, non affiné, saumuré, à point de fusion plus élevé que d'habitude, généralement fabriqué à partir de lait de chèvre et de brebis.&lt;/dd&gt;
+ &lt;dt&gt;Salade verte&lt;/dt&gt;
+ &lt;dd&gt;Ces feuilles vertes et saines que beaucoup d'entre nous n'utilisent que pour garnir les kebabs.&lt;/dd&gt;
+&lt;/dl&gt;</pre>
+
+<p>Si vous allez à l'exemple réel maintenant, et examinez les éléments de la liste en utilisant <a href="/en-US/docs/Learn/Common_questions/What_are_browser_developer_tools">les outils de développement du navigateur</a>, vous noterez quelques valeurs de style par défaut :</p>
+
+<ul>
+ <li>Les éléments {{htmlelement("ul")}} et {{htmlelement("ol")}} ont une propriété {{cssxref("margin")}} de <code>16 px</code> (<code>1 em</code>) en haut et en bas et une propriété {{cssxref("padding-left")}} de <code>40 px</code> (<code>2.5 em</code>.)</li>
+ <li>Les éléments de la liste ({{htmlelement("li")}}) <span id="result_box" lang="fr"><span>n'ont aucun paramètre d'espacement par défaut</span></span><span lang="fr"><span>.</span></span></li>
+ <li>L'élément {{htmlelement("dl")}} a des propriétés {{cssxref("margin")}} de<code>16 px</code> (<code>1 em</code>) en haut et en bas , mais pas de définition du remplissage.</li>
+ <li>Les éléments {{htmlelement("dd")}} ont une propriété {{cssxref("margin-left")}} de <code>40 px</code> (<code>2.5 em</code>.)</li>
+ <li>Les éléments {{htmlelement("p")}}, inclus pour référence, ont des propriétés {{cssxref("margin")}} de <code>16 px</code> (<code>1 em</code>) en haut et en bas, identiques à ceux des différents types de listes.</li>
+</ul>
+
+<h2 id="Gestion_d'espacement_des_listes">Gestion d'espacement des listes</h2>
+
+<p>Si vous modifiez le style des listes, vous devez ajuster l'espacement vertical et horizontal de manière à le rendre identique à celui des éléments environnants (tels que paragraphes ou images : ce principe est parfois appelé « rythme vertical » — vous pouvez voir l'<a href="http://mdn.github.io/learning-area/css/styling-text/styling-lists/">exemple de style terminé</a> sur Github et trouver<a href="https://github.com/mdn/learning-area/blob/master/css/styling-text/styling-lists/index.html"> le code source</a> aussi.)</p>
+
+<p>Le CSS utilisé pour le style et l'espacement du texte est le suivant :</p>
+
+<pre>/* Style général */
+
+html {
+ font-family: Helvetica, Arial, sans-serif;
+ font-size: 10px;
+}
+
+h2 {
+ font-size: 2rem;
+}
+
+ul,ol,dl,p {
+ font-size: 1.5rem;
+}
+
+li, p {
+ line-height: 1.5;
+}
+
+/* Styles des listes descriptives */
+
+
+dd, dt {
+ line-height: 1.5;
+}
+
+dt {
+ font-weight: bold;
+}
+
+dd {
+ margin-bottom: 1.5rem;
+}</pre>
+
+<ul>
+ <li>La première règle définit une police de caractères pour l'ensemble du site avec une taille de base de 10 px. Elles sont héritées par tous les éléments de la page.</li>
+ <li>Les règles 2 et 3 définissent des tailles relatives de la police pour les titres, les différents types de liste (les enfants des éléments de liste en héritent) et les paragraphes. Cela signifie que les paragraphes et listes auront la même taille de police et les mêmes espacements entre le haut et le bas, ce qui aidera à garder un rythme vertical cohérent.</li>
+ <li>La règle 4 définit la même propriété {{cssxref("line-height")}} pour les paragraphes et éléments de listes — ainsi les paragraphes et chaque élément de liste individuellement auront le même espacement entre les lignes. Cela aidera également à garder un rythme vertical cohérent.</li>
+ <li>Les règles 5 et 6 s'appliquent à la liste descriptive — nous définissons la même valeur pour la propriété <code>line-height</code> pour les termes à décrire et les descriptions, valeur utilisée pour les paragraphes et les éléments de liste. Encore une fois, la cohérence est bonne ! Nous écrivons aussi les termes à décrire avec une police en gras, pour les distinguer visuellement plus facilement.</li>
+</ul>
+
+<h2 id="Style_propre_à_une_liste">Style propre à une liste</h2>
+
+<p>Maintenant que nous avons examiné l'espacement général des listes, explorons quelques propriétés propres à une liste. Il y a trois propriétés à connaître pour commencer ; elles s'appliquent aux éléments {{htmlelement("ul")}} ou {{htmlelement("ol")}} :</p>
+
+<ul>
+ <li>{{cssxref("list-style-type")}} : définit le type de puces à utiliser pour la liste, par exemple des puces carrées ou rondes pour une liste non ordonnée ou bien des nombres, des lettres ou des chiffres romains pour une liste ordonnée.</li>
+ <li>{{cssxref("list-style-position")}} : définit si les puces seront disposées à l'intérieur ou à l'extérieur du début de l'élément liste.</li>
+ <li>{{cssxref("list-style-image")}} : permet d'utiliser une image personnalisée pour la puce, plutôt qu'un simple carré ou rond.</li>
+</ul>
+
+<h3 id="Styles_de_puces">Styles de puces</h3>
+
+<p>Comme mentionné ci-dessus, la propriété {{cssxref("list-style-type")}} vous permet de définir le type de puce à utiliser. Dans notre exemple, nous avons défini une liste ordonnée utilisant les chiffres romains en majuscules avec :</p>
+
+<pre class="brush: css">ol {
+ list-style-type: upper-roman;
+}</pre>
+
+<p>Cela donne l'apparence suivante :</p>
+
+<p><img alt="une liste ordonnée avec les puces placées à l'extérieur du texte de l'élément de la liste." src="https://mdn.mozillademos.org/files/16069/ex_1.png" style="border-style: solid; border-width: 1px; display: block; height: 94px; margin: 0px auto; width: 406px;"></p>
+
+<p>Vous pouvez trouver beaucoup plus d'options en consultant la page de référence {{cssxref("list-style-type")}}.</p>
+
+<h3 id="Position_des_puces">Position des puces</h3>
+
+<p>La propriété {{cssxref("list-style-position")}} définit si les puces apparaissent à l'extérieur ou à l'intérieur de la liste devant chaque élément. Par défaut, la valeur est <code>outside</code> et les puces apparaîssent comme ci-dessus.</p>
+
+<p>Si vous choisissez la valeur <code>inside</code>, les puces seront disposées dans la ligne :</p>
+
+<pre class="brush: css">ol {
+ list-style-type: upper-roman;
+ list-style-position: inside;
+}</pre>
+
+<p><img alt="une liste ordonnée avec les puces intégrées au texte des éléments de la liste." src="https://mdn.mozillademos.org/files/16070/ex_2.png" style="border-style: solid; border-width: 1px; display: block; height: 147px; margin: 0px auto; width: 406px;"></p>
+
+<h3 id="Utilisation_d'une_puce_image_personnalisée">Utilisation d'une puce image personnalisée</h3>
+
+<p>La propriété {{cssxref("list-style-image")}} vous permet d'utiliser une image pour personnaliser vos puces. La syntaxe est assez simple :</p>
+
+<pre class="brush: css">ul {
+ list-style-image: url(star.svg);
+}</pre>
+
+<p>Cependant, cette propriété est un peu limitée en terme de contrôle de la position, de la taille, etc. des puces. Il vaut mieux utiliser la famille de propriétés de {{cssxref ("background")}}, dont vous apprendrez beaucoup plus dans le module <a href="https://developer.mozilla.org/fr/Apprendre/CSS/styliser_boites"> Styliser les boîtes</a>. Pour l'instant, voici un avant-goût !</p>
+
+<p>Dans notre exemple achevé, nous avons appliqué un style à la liste non ordonnée (en plus de ce que vous avez déjà vu ci-dessus) comme ceci :</p>
+
+<pre class="brush: css">ul {
+ padding-left: 2rem;
+ list-style-type: none;
+}
+
+ul li {
+ padding-left: 2rem;
+ background-image: url(star.svg);
+ background-position: 0 0;
+ background-size: 1.6rem 1.6rem;
+ background-repeat: no-repeat;
+}</pre>
+
+<p>Voici ce que nous avons fait :</p>
+
+<ul>
+ <li>abaissé la valeur de la propriété {{cssxref ("padding-left")}} de l'élément {{htmlelement ("ul")}} de <code>40px</code> par défaut à <code>20px</code>, puis défini la même valeur pour les éléments de la liste. Ainsi,  l'ensemble des éléments d'une liste non ordonnée seront toujours alignés avec les éléments d'une liste ordonnée et les descriptions d'une liste descriptive; tout en disposant d'un remplissage où les images d'arrière-plan seront placées. Si nous ne le faisions pas, les images d'arrière-plan et le texte de l'élément de liste se superposeraient, ce qui ferait brouillon.</li>
+ <li>défini la propriété {{cssxref("list-style-type")}} à <code>none</code>, ainsi aucune puce par défaut n'apparaît. Nous allons utiliser les propriétés de {{cssxref("background")}} pour gérer les puces.</li>
+ <li>inséré une puce pour chaque élément de la liste désordonnée. Les propriétés pertinentes sont les suivantes :
+ <ul>
+ <li>{{cssxref("background-image")}} : référence du chemin d'accès au fichier image utilisé comme puce.</li>
+ <li>{{cssxref("background-position")}} : emplacement de l'image dans l'arrière-plan de l'élément sélectionné — dans ce cas, nous disons <code>0 0</code> : la puce apparaîtra dans le coin supérieur gauche de chaque élément de la liste.</li>
+ <li>{{cssxref("background-size")}} : taille de l'image d'arrière-plan. L'idéal est que les puces soient de même taille que les éléments de la liste (ou légèrement plus petites ou plus grandes). Nous utilisons une taille de <code>1.6rem</code> (<code>16px</code>), qui correspond bien au remplissage de <code>20px</code> dans lequel la puce est placée — 16 px plus 4 px d'espace entre la puce et le texte de l'élément de liste fonctionne bien.</li>
+ <li>{{cssxref("background-repeat")}} : par défaut, les images d'arrière-plan se répètent jusqu'à avoir rempli l'espace d'arrière-plan disponible. Nous voulons l'insertion d'une seule copie de l'image sans répétition, donc nous choisissons la valeur <code>no-repeat</code>.</li>
+ </ul>
+ </li>
+</ul>
+
+<p>Ceci nous donne le résultat suivant :</p>
+
+<p><img alt="une liste non ordonnée avec les puces définies comme de petites images d'étoiles." src="https://mdn.mozillademos.org/files/16071/ex_3.png" style="border-style: solid; border-width: 1px; display: block; height: 115px; margin: 0px auto; width: 194px;"></p>
+
+<h3 id="Raccourci_de_style_de_liste">Raccourci de style de liste</h3>
+
+<p>Les 3 propriétés mentionnées ci-dessus peuvent toutes être définies en utilisant la propriété abrégée {{cssxref("list-style")}}. Par exemple, le CSS suivant :</p>
+
+<pre class="brush: css">ul {
+ list-style-type: square;
+ list-style-image: url(example.png);
+ list-style-position: inside;
+}</pre>
+
+<p>peut être remplacé par cela :</p>
+
+<pre>ul {
+ list-style: square url(example.png) inside;
+}</pre>
+
+<p>Les valeurs peuvent être listées dans n'importe quel ordre et vous pouvez en mentionner une, deux ou les trois (les valeurs par défaut utilisées pour les propriétés non-citées sont <code>disc</code>, <code>none</code> et <code>outside</code>. Si un <code>type</code> et une <code>image</code> sont donnés, le type sera affiché en solution de repli dans le cas où l'image ne peut pas être chargée pour une raison quelconque.</p>
+
+<h2 id="Contrôle_du_numérotage_des_listes">Contrôle du numérotage des listes</h2>
+
+<p>Parfois, vous pouvez vouloir numéroter différemment une liste ordonnée — par ex., à partir d'un nombre autre que 1 ou en comptant à rebours ou en comptant par pas supérieur à 1. HTML et CSS ont quelques outils pour vous le permettre.</p>
+
+<h3 id="Numéro_de_départ">Numéro de départ</h3>
+
+<p>L'attribut {{htmlattrxref("start","ol")}} vous permet de commencer le numérotage de la liste à partir d'un nombreautre que 1. L'exemple suivant :</p>
+
+<pre class="brush: html">&lt;ol start="4"&gt;
+ &lt;li&gt;Faire griller le pain pitta, laisser refroidir, puis le trancher sur le côté.&lt;/li&gt;
+ &lt;li&gt;Frire l'halloumi dans une poêle plate antiadhésive, jusqu'à ce qu'il soit doré des deux côtés.&lt;/li&gt;
+ &lt;li&gt;Laver et hacher la salade.&lt;/li&gt;
+ &lt;li&gt;Mettre la salade, l'houmous et l'halloumi frit entre les tranches de pain.&lt;/li&gt;
+&lt;/ol&gt;</pre>
+
+<p>vous donne cette sortie :</p>
+
+<p>{{ EmbedLiveSample('Numéro_de_départ', '100%', 150) }}</p>
+
+<h3 id="Numérotation_inversée">Numérotation inversée</h3>
+
+<p>L'attribut {{htmlattrxref("reversed","ol")}} inverse la numérotation de la liste. L'exemple suivant :</p>
+
+<pre class="brush: html">&lt;ol start="4" reversed&gt;
+ &lt;li&gt;Faire griller le pain pitta, le laisser refroidir, puis le trancher sur le côté.&lt;/li&gt;
+ &lt;li&gt;Frire l'halloumi dans une poêle plate antiadhésive, jusqu'à ce qu'il soit doré des deux côtés.&lt;/li&gt;
+ &lt;li&gt;Laver et hacher la salade.&lt;/li&gt;
+ &lt;li&gt;Mettre la salade, l'houmous et l'halloumi frit entre les tranches de pain.&lt;/li&gt;
+&lt;/ol&gt;</pre>
+
+<p>donne cette sortie :</p>
+
+<p>{{ EmbedLiveSample('Numérotation_inversée', '100%', 150) }}</p>
+
+<h3 id="Valeurs_individualisées">Valeurs individualisées</h3>
+
+<p>L'attribut {{htmlattrxref("value","ol")}} vous permet <span id="result_box" lang="fr"><span>de numéroter les éléments de liste avec des valeurs numériques de votre choix</span></span> . L'exemple suivant :</p>
+
+<pre class="brush: html">&lt;ol&gt;
+ &lt;li value="2"&gt;Faire griller le pain pitta, laisser refroidir, puis le trancher sur le côté.&lt;/li&gt;
+ &lt;li value="4"&gt;Frire l'halloumi dans une poêle plate antiadhésive, jusqu'à ce qu'il soit doré des deux côtés.&lt;/li&gt;
+ &lt;li value="6"&gt;Laver et hacher la salade.&lt;/li&gt;
+ &lt;li value="8"&gt;Mettre la salade, l'houmous et l'halloumi frit entre les tranches de pain.&lt;/li&gt;
+&lt;/ol&gt;</pre>
+
+<p>vous donne cette sortie :</p>
+
+<p>{{ EmbedLiveSample('Valeurs_individualisées', '100%', 150) }}</p>
+
+<div class="note">
+<p><strong>Note</strong> : Même si vous utilisez une propriété {{cssxref ("type-style-list")}}  avec des caractères non‑numériques, vous devez toujours utiliser les valeurs numériques équivalentes avec l'attribut <code>value</code>.</p>
+</div>
+
+<h2 id="Apprentissage_actif_définir_le_style_d'une_liste_imbriquée">Apprentissage actif : définir le style d'une liste imbriquée</h2>
+
+<p>Dans cette session d'apprentissage actif, vous devez utiliser ce que vous avez appris ci-dessus en donnant un certain style à une liste imbriquée. Avec le code HTML fourni, nous vous demandons de :</p>
+
+<ol>
+ <li>mettre une puce carrée devant les éléments de la liste non ordonnée,</li>
+ <li>donner aux éléments des listes, ordonnées ou non, une hauteur de ligne de 1.5 fois la taille de la police de caractères.</li>
+ <li>donner à la liste ordonnée une puce alphabétique en minuscules.</li>
+ <li>ne pas hésiter à jouer avec l'exemple de liste autant que vous le souhaitez, en expérimentant les types de puces, l'espacement ou tout ce que vous pouvez trouver.</li>
+</ol>
+
+<p>Si vous faites une erreur, vous pourrez toujours tout remettre à zéro avec le bouton <em>Réinitialiser</em>. Si vous êtes vraiment bloqué, pressez le bouton <em>Voir la solution</em> pour voir une réponse possible.</p>
+
+<div class="hidden">
+<h6 id="Playable_code">Playable code</h6>
+
+<pre class="brush: html">&lt;div class="body-wrapper" style="font-family: 'Open Sans Light',Helvetica,Arial,sans-serif;"&gt;
+ &lt;h2&gt;Zone de saisie du HTML&lt;/h2&gt;
+ &lt;textarea id="code" class="html-input" style="width: 90%;height: 10em;padding: 10px;border: 1px solid #0095dd;"&gt;&lt;ul&gt;
+ &lt;li&gt;D'abord, allumez la chandelle.&lt;/li&gt;
+ &lt;li&gt;Ensuite, ouvrez la boîte.&lt;/li&gt;
+ &lt;li&gt;Puis, mettez les trois objets magiques dans la
+ boîte, dans cet ordre exactement, pour terminer
+ le charme :
+ &lt;ol&gt;
+ &lt;li&gt;le livre de sorts,&lt;/li&gt;
+ &lt;li&gt;la baguette brillante,&lt;/li&gt;
+ &lt;li&gt;la statue du lutin.&lt;/li&gt;
+ &lt;/ol&gt;
+ &lt;/li&gt;
+&lt;/ul&gt;&lt;/textarea&gt;
+
+ &lt;h2&gt;Zone de saisie de la CSS&lt;/h2&gt;
+ &lt;textarea id="code" class="css-input" style="width: 90%;height: 10em;padding: 10px;border: 1px solid #0095dd;"&gt;&lt;/textarea&gt;
+
+ &lt;h2&gt;Zone de rendu&lt;/h2&gt;
+ &lt;div class="output" style="width: 90%;height: 12em;padding: 10px;border: 1px solid #0095dd;overflow: auto;"&gt;&lt;/div&gt;
+ &lt;div class="controls"&gt;
+ &lt;input id="reset" type="button" value="Réinitialiser" style="margin: 10px 10px 0 0;"&gt;
+ &lt;input id="solution" type="button" value="Voir la solution" style="margin: 10px 0 0 10px;"&gt;
+ &lt;/div&gt;
+&lt;/div&gt;
+</pre>
+
+<pre class="brush: js">var htmlInput = document.querySelector(".html-input");
+var cssInput = document.querySelector(".css-input");
+var reset = document.getElementById("reset");
+var htmlCode = htmlInput.value;
+var cssCode = cssInput.value;
+var output = document.querySelector(".output");
+var solution = document.getElementById("solution");
+
+var styleElem = document.createElement('style');
+var headElem = document.querySelector('head');
+headElem.appendChild(styleElem);
+
+function drawOutput() {
+ output.innerHTML = htmlInput.value;
+ styleElem.textContent = cssInput.value;
+}
+
+reset.addEventListener("click", function() {
+ htmlInput.value = htmlCode;
+ cssInput.value = cssCode;
+ drawOutput();
+});
+
+solution.addEventListener("click", function() {
+ htmlInput.value = htmlCode;
+ cssInput.value = 'ul {\n list-style-type: square;\n}\n\nul li, ol li {\n line-height: 1.5;\n}\n\nol {\n list-style-type: lower-alpha\n}';
+ drawOutput();
+});
+
+htmlInput.addEventListener("input", drawOutput);
+cssInput.addEventListener("input", drawOutput);
+window.addEventListener("load", drawOutput);
+</pre>
+</div>
+
+<p>{{ EmbedLiveSample('Playable_code', 700, 800) }}</p>
+
+<h2 id="Voir_aussi">Voir aussi</h2>
+
+<p>Les compteurs CSS fournissent des outils avancés pour personnaliser le comptage et le style des listes, mais ils sont assez complexes. Nous vous recommandons de les examiner si vous voulez vous étendre sur le sujet. Voir :</p>
+
+<ul>
+ <li>{{cssxref("@counter-style")}}</li>
+ <li>{{cssxref("counter-increment")}}</li>
+ <li>{{cssxref("counter-reset")}}</li>
+</ul>
+
+<h2 id="Résumé">Résumé</h2>
+
+<p>Les listes sont relativement faciles à saisir lorsque vous connaissez les quelques principes de base associés et les propriétés spécifiques. Dans le prochain article, nous allons évoquer des techniques de style des liens.</p>
+
+<p>{{PreviousMenuNext("Learn/CSS/Styling_text/Fundamentals", "Learn/CSS/Styling_text/Styling_links", "Learn/CSS/Styling_text")}}</p>
+
+<h2 id="Dans_ce_module">Dans ce module</h2>
+
+<p> </p>
+
+<ul>
+ <li><a href="/fr/docs/Learn/CSS/Styling_text/initiation-mise-en-forme-du-texte">Initiation à la mise en forme du texte</a></li>
+ <li><a href="/fr/docs/Learn/CSS/Styling_text/Styling_lists">Style de listes</a></li>
+ <li><a href="/fr/docs/Learn/CSS/Styling_text/Mise_en_forme_des_liens">Mise en forme des liens</a></li>
+ <li><a class="new" href="https://developer.mozilla.org/fr/docs/Learn/CSS/Styling_text/Web_fonts" rel="nofollow">Polices de caractères web</a></li>
+ <li><a class="new" href="https://developer.mozilla.org/fr/docs/Learn/CSS/Styling_text/Typesetting_a_homepage" rel="nofollow">Composition d'une page d'accueil d'une école communale</a></li>
+</ul>
diff --git a/files/fr/learn/css/styling_text/typesetting_a_homepage/index.html b/files/fr/learn/css/styling_text/typesetting_a_homepage/index.html
new file mode 100644
index 0000000000..9cc49e8056
--- /dev/null
+++ b/files/fr/learn/css/styling_text/typesetting_a_homepage/index.html
@@ -0,0 +1,126 @@
+---
+title: Composition de la page d'accueil d'une école de communauté
+slug: Learn/CSS/Styling_text/Typesetting_a_homepage
+tags:
+ - CSS
+ - Codage
+ - Composer du texte
+ - Débutant
+ - Evaluation
+ - Fontes
+ - Fontes web
+ - Liens
+ - Listes
+translation_of: Learn/CSS/Styling_text/Typesetting_a_homepage
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenu("Learn/CSS/Styling_text/Web_fonts", "Learn/CSS/Styling_text")}}</div>
+
+<p class="summary">Dans cette évaluation, nous testerons votre compréhension de toutes les techniques pour la composition de textes à l'écran présentées au cours de ce module : elle consiste à créer la page d'accueil du site d'une école communale. Vous ne devriez avoir que du plaisir tout au long de ce parcours.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Prérequis :</th>
+ <td>Avant de tenter cette évaluation, il faut que vous ayez déjà travaillé tous les articles de ce module.</td>
+ </tr>
+ <tr>
+ <th scope="row">Objectif :</th>
+ <td>Tester la compréhension de la composition de textes à l'écran avec les techniques des CSS.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Point_de_départ">Point de départ</h2>
+
+<p>Pour débuter cette évaluation, vous devez :</p>
+
+<ul>
+ <li>récupérer les fichiers <a href="https://github.com/mdn/learning-area/blob/master/css/styling-text/typesetting-a-homepage-start/index.html">HTML</a> et <a href="https://github.com/mdn/learning-area/blob/master/css/styling-text/typesetting-a-homepage-start/style.css">CSS</a> de l'exercice ainsi que <a href="https://github.com/mdn/learning-area/blob/master/css/styling-text/typesetting-a-homepage-start/external-link-52.png">le lien externe sur l'icône</a>.</li>
+ <li>en faire une copie sur votre ordinateur.</li>
+</ul>
+
+<div class="note">
+<p><strong>Note</strong> : Autrement, il reste possible d'utiliser un site comme <a class="external external-icon" href="http://jsbin.com/">JSBin</a> ou <a class="external external-icon" href="https://thimble.mozilla.org/">Thimble</a> pour faire votre évaluation. Collez le HTML et remplissez la CSS dans l'un de ces éditeurs en ligne ; utilisez <a href="http://mdn.github.io/learning-area/css/styling-text/typesetting-a-homepage-start/external-link-52.png">cet URL</a> pour pointer sur l'image de fond. Si l'éditeur en ligne que vous utilisez n'a pas de panneau CSS séparé, vous pouvez l'intégrer dans un élément <code>&lt;style&gt;</code> de l'élément <code>head</code> du document.</p>
+</div>
+
+<h2 id="Énoncé_de_l'exercice">Énoncé de l'exercice</h2>
+
+<p>Nous mettons à votre disposition un HTML pour la page d'accueil du site internet d'un collège de communauté imaginaire, plus certains éléments de la CSS composant la page sur deux colonnes et fournissant d'autres rudiments de composition. Vous devez écrire des compléments à la CSS sous le commentaire au bas du fichier de façon à pouvoir marquer aisément vos ajouts. Ne vous tracassez pas si certains sélecteurs sont répétés : nous laisserons ce point de côté dans cet exemeple.</p>
+
+<p>Fontes :</p>
+
+<ul>
+ <li>Primo, téléchargez quelques polices gratuites.  Comme il s'agit d'un collège, les polices choisies doivent donner à la page une impression de sérieux, de formalisme et de confiance — une police sérif ample pour le corps du texte général, associée une police sans sérif ou bloc sérif pour les en-têtes serait pas mal.</li>
+ <li>Ensuite, utilisez le service ad-hoc pour créer le « bulletproof <code>@font-face</code> code » pour ces deux fontes.</li>
+ <li>Appliquez la police pour le corps à toute la page et celle pour les titres aux en‑têtes.</li>
+</ul>
+
+<p>Style général du texte :</p>
+
+<ul>
+ <li>Donnez à la page une propriété <code>font-size</code> de <code>10px</code> sur tout le site.</li>
+ <li>Donnez aux titres et autres types d'éléments des tailles de polices appropriées définie avec une unité relative adéquate.</li>
+ <li>Donnez au corps du texte une propriété <code>line-height</code> appropriée.</li>
+ <li>Centrez le titre d'en-tête sue la page.</li>
+ <li>Augmentez légérement la valeur de la propriété <code>letter-spacing</code> des titres pour qu'ils ne paraissent pas trop écrasés en donnant un peu d'air aux lettres.</li>
+ <li>Donnez au corps du texte une valeur de propriété <code>letter-spacing</code> et <code>word-spacing</code> appropriée.</li>
+ <li>Donnez au premier paragraphe après chaque titre dans <code>&lt;section&gt;</code> une légère indentation, disons 20px.</li>
+</ul>
+
+<p>Liens :</p>
+
+<ul>
+ <li>Donnez aux liens, visités, ciblés et survolés des couleurs en accord avec celles des barres horizontales en haut et en bas de la page.</li>
+ <li>Faites en sorte que les liens soient soulignés par défaut, mais que le soulignement disparaisse lorsqu'ils sont ciblés ou survolés.</li>
+ <li>Supprimez le soulignement du focus par défaut de TOUS les liens de la page.</li>
+ <li>Donnez à l'état actif un style sensiblement différent pour qu'il se démarque bien, mais faites en sorte qu'il s'intègre à la conception globale de la page.</li>
+ <li>Faites en sorte que l'icône de lien externe soit insérée à côté des liens externes.</li>
+</ul>
+
+<p>Listes :</p>
+
+<ul>
+ <li>Assurez-vous que l'espacement des listes et éléments de liste s'accorde bien avec le style d'ensemble de la page. Chaque élément de liste doit avoir la même valeur de propriété <code>line-height</code> qu'une ligne de paragraphe et chaque liste doit avoir le même espacement en haut et en bas que celui entre les paragraphes.</li>
+ <li>Mettez une belle puce, appropriée à la conception de la page, devant les éléments de la liste. À vous de décider si vous choisissez une image personnalisée ou autre chose.</li>
+</ul>
+
+<p>Menu de navigation :</p>
+
+<ul>
+ <li>Donnez à votre menu de navigation un style tel que son aspect soit en accord avec l'apparence et la convivialité de la page.</li>
+</ul>
+
+<h2 id="Conseils_et_astuces">Conseils et astuces</h2>
+
+<ul>
+ <li>Il n'y a pas besoin de modifier le HTML en quoi que ce soit pour cet exercice.</li>
+ <li>Le menu de navigation n'est pas forcément à représenter sous forme de boutons, mais il doit être un peu plus grand pour ne pas avoir l'air riquiqui sur le côté de la page ; n'oubliez pas non plus que sa disposition doit être verticale.</li>
+</ul>
+
+<h2 id="Exemple">Exemple</h2>
+
+<p>La capture d'écran ci-après montre un exemple possible du design terminé :</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/12994/example2.png" style="display: block; height: 1106px; margin: 0px auto; width: 1533px;"></p>
+
+<h2 id="Évaluation">Évaluation</h2>
+
+<p>Si vous faites cet exercice dans le cadre d'un cours organisé, vous devez pouvoir donner votre travail à votre professeur pour notation. Si vous faites de l'auto-formation, vous pouvez obtenir le guide de notation très facilement en le demandant sur  <a class="external external-icon" href="https://discourse.mozilla.org/t/fundamental-css-comprehension-assessment/24682" rel="noopener">le fil de discussion à propos de cet exercice</a> ou par l'intermédiaire du canal IRC <a href="irc://irc.mozilla.org/mdn">#mdn</a> sur <a class="external external-icon" href="https://wiki.mozilla.org/IRC" rel="noopener">Mozilla IRC</a>. Faites l'exercice d'abors, il n'y rien à gagner en trichant !</p>
+
+<p>{{PreviousMenu("Learn/CSS/Styling_text/Web_fonts", "Learn/CSS/Styling_text")}}</p>
+
+<p> </p>
+
+<h2 id="Dans_ce_module">Dans ce module</h2>
+
+<p> </p>
+
+<ul>
+ <li><a href="/fr/docs/Learn/CSS/Styling_text/initiation-mise-en-forme-du-texte">Initiation à la mise en forme du texte</a></li>
+ <li><a href="/fr/docs/Learn/CSS/Styling_text/Styling_lists">Style de listes</a></li>
+ <li><a href="/fr/docs/Learn/CSS/Styling_text/Mise_en_forme_des_liens">Mise en forme des liens</a></li>
+ <li><a class="new" href="https://developer.mozilla.org/fr/docs/Learn/CSS/Styling_text/Web_fonts" rel="nofollow">Polices de caractères web</a></li>
+ <li>Composition d'une page d'accueil d'une école de communauté</li>
+</ul>
diff --git a/files/fr/learn/css/styling_text/web_fonts/index.html b/files/fr/learn/css/styling_text/web_fonts/index.html
new file mode 100644
index 0000000000..64724b25db
--- /dev/null
+++ b/files/fr/learn/css/styling_text/web_fonts/index.html
@@ -0,0 +1,203 @@
+---
+title: Fontes Web
+slug: Learn/CSS/Styling_text/Web_fonts
+translation_of: Learn/CSS/Styling_text/Web_fonts
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/CSS/Styling_text/Styling_links", "Learn/CSS/Styling_text/Typesetting_a_homepage", "Learn/CSS/Styling_text")}}</div>
+
+<p class="summary">Dans le premier article du module, nous avons exploré les fonctions CSS de base disponibles pour composer du texte. Dans cet article, nous allons plus loin et explorons les polices web en détail : comment télécharger des polices personnalisées en même temps que la page Web, pour donner un style plus varié et personnalisé au texte.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Prérequis :</th>
+ <td>Connaissances informatiques de base, les bases HTML (étudiées dans l'<a href="https://developer.mozilla.org/en-US/docs/Learn/HTML/Introduction_to_HTML">Introduction au HTML</a>), les bases CSS (étudiées dans <a href="https://developer.mozilla.org/en-US/docs/Learn/CSS/Introduction_to_CSS">Introduction à CSS</a>).</td>
+ </tr>
+ <tr>
+ <th scope="row">Objectif :</th>
+ <td>Apprendre comment appliquer des fontes web à une page web, soit avec un service tierce partie, soit en écrivant vous-même le code.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Rappel_familles_de_fontes">Rappel : familles de fontes</h2>
+
+<p>Comme nous l'avons vu dans <a href="/fr/docs/Learn/CSS/Styling_text/initiation-mise-en-forme-du-texte">Initiation à la mise en forme du texte</a>, les fontes appliquées aux HTML sont contrôlées par la propriété {{cssxref("font-family")}}. Elle accepte un ou plusieurs noms de familles de fontes et le navigateur parcourt la liste jusqu'à trouver la fonte disponible sur le système sur lequel il tourne :</p>
+
+<pre class="brush: css">p {
+ font-family: Helvetica, "Trebuchet MS", Verdana, sans-serif;
+}</pre>
+
+<p>Ce système fonctionne bien, mais généralement, le choix des développeurs Web en matière de polices sont limités. Il n'y en a qu'une poignée dont la disponibilité soit garantie sur tous les systèmes courants — les polices dites <a href="/fr/docs/Learn/CSS/Styling_text/initiation-mise-en-forme-du-texte#Polices_web_sûres">Web-safe</a>. La pile de polices vous permet de préciser la police préférable, puis la police alternative sûre pour le Web, puis la police par défaut du système, mais cela induit du travail supplémentaire de tests pour s'assurer que le désign reste correct avec chaque police, etc.</p>
+
+<h2 id="Fontes_Web">Fontes Web</h2>
+
+<p>Mais il y a autre chose qui fonctionne très bien, depuis la version 6 d'IE. La fonctionnalité CSS des polices Web permet de définir les fichiers de polices à télécharger avec le site Web au fur et à mesure de sa consultation ; autrement dit, tout navigateur prenant en charge les polices Web aura exactement la police précisée à sa disposition. Incroyable ! La syntaxe requise ressemble à ce qui suit.</p>
+
+<p>Primo, un bloc {{cssxref("@font-face")}} est placé au début de la CSS ; il précise le ou les fichiers de fontes à télécharger :</p>
+
+<pre class="brush: css">@font-face {
+ font-family: "myFont";
+ src: url("myFont.ttf");
+}</pre>
+
+<p>Sous cette déclaration, vous pouvez utiliser le nom de la famille de polices précisé dans @font-face pour appliquer la police personnalisée où vous le voulez, normalement :</p>
+
+<pre class="brush: css">html {
+ font-family: "myFont", "Bitstream Vera Serif", serif;
+}</pre>
+
+<p>La syntaxe peut devenir un peu plus complexe que cela, nous reviendrons sur le sujet plus bas.</p>
+
+<p>Deux points important sont à garder présents à l'esprit à ce propos :</p>
+
+<p>L'utilisation des polices n'est généralement pas gratuite. Vous devez payer pour les utiliser et/ou respecter d'autres conditions de licence telles que citer le créateur de la police dans le code (ou sur le site). Ne vous appropriez pas les polices et ne les utilisez pas sans donner le crédit voulu.</p>
+
+<ol>
+ <li>Les navigateurs prennent en charge divers formats de polices ; donc, vous aurez besoin de plusieurs formats de polices pour une prise en charge croisée correcte des navigateurs. Par ex., la plupart des navigateurs modernes prennent en charge les formats WOFF/WOFF2 (Web Open Font Format versions 1 et 2), le plus efficace, mais les vieilles versions d'IE n'acceptent que les polices EOT (Embedded Open Type) et, même, vous pourriez avoir besoin d'inclure une version SVG de la police pour être pris en charge par les anciennes versions de l'iPhone et des navigateurs Android. Nous vous montrerons ci-dessous comment générer le code voulu.</li>
+ <li>Fonts generally aren't free to use. You have to pay for them, and/or follow other license conditions such as crediting the font creator in the code (or on your site.) You shouldn't steal fonts and use them without giving proper credit.</li>
+</ol>
+
+<div class="note">
+<p><strong>Note </strong>: La technique des polices Web est prise en charge dans Internet Explorer depuis sa version 4 !</p>
+</div>
+
+<h2 id="Apprentissage_actif_un_exemple_de_fonte_web">Apprentissage actif : un exemple de fonte web</h2>
+
+<p>En gardant en tête ce qui précède, construisons un exemple de police web de base à partir des premiers principes. Il est difficile de le montrer à l'aide d'un exemple direct intégré : nous aimerions donc que vous suiviez les étapes détaillées dans les paragraphes ci‑après afin d'avoir une idée du processus.</p>
+
+<p>Utilisez les fichiers <a href="https://github.com/mdn/learning-area/blob/master/css/styling-text/web-fonts/web-font-start.html">web-font-start.html</a> et <a href="https://github.com/mdn/learning-area/blob/master/css/styling-text/web-fonts/web-font-start.css">web-font-start.css</a> comme point de départ pour ajouter votre code (voir l'<a href="http://mdn.github.io/learning-area/css/styling-text/web-fonts/web-font-start.html">exemple en direct</a> aussi.) Faites une copie de ces fichiers dans un nouveau répertoire sur votre ordinateur. Dans le fichier <code>web-font-start.css</code>, vous trouverez un CSS minimal pour traiter la mise en page et la composition de base de l'exemple.</p>
+
+<h3 id="Recherche_des_polices">Recherche des polices</h3>
+
+<p> </p>
+
+<p>Dans cet exemple, nous utilisons deux polices web, une pour les en-têtes et une pour le corps du texte. Pour commencer, nous devons trouver les fichiers de ces polices. Les fontes des polices sont stockées en différents formats de fichiers. Il y a généralement trois types de sites où obtenir des fontes :</p>
+
+<ul>
+ <li>un distributeur de fontes gratuites : c'est un site de téléchargement de polices gratuites (la licence peut exiger certaines conditions, comme citer le créateur de la fonte). C'est le cas de <a href="https://www.fontsquirrel.com/">Font Squirrel</a>, <a href="http://www.dafont.com/">dafont</a> et <a href="https://everythingfonts.com/">Everything Fonts</a>.</li>
+ <li>un distributeur de fontes payantes : c'est un site qui met à disposition des fontes contre paiement, comme <a href="http://www.fonts.com/">fonts.com</a> ou <a href="http://www.myfonts.com/">myfonts.com</a>. Vous pouvez aussi acheter directement auprès du fondeur, par exemple <a href="https://www.linotype.com/">Linotype</a>, <a href="http://www.monotype.com">Monotype</a> ou <a href="http://www.exljbris.com/">Exljbris</a>.</li>
+ <li>un service de fontes en ligne : c'est un site qui stocke et téléverse les polices à votre intention, facilitant ainsi l'ensemble du processus. Voir la section {{anch("Utiliser un service de polices en ligne")}} pour plus de détails.</li>
+</ul>
+
+<p>Cherchons des polices de caractères ! Allez dans <a href="https://www.fontsquirrel.com/">Font Squirrel</a> et choisissez deux polices — une police adaptée aux en-têtes (peut-être une belle police d'affichage de blocs avec sérifs) et une police un peu moins criarde et plus lisible pour les paragraphes. Après avoir trouvé chaque police, appuyez sur le bouton de téléchargement et enregistrez le fichier dans le même répertoire que les fichiers HTML et CSS précéemment enregistrés. Peu importe qu'il s'agisse de TTF (True Type Fonts) ou OTF (Open Type Fonts).</p>
+
+<p>Dans chaque cas, décompressez le paquet de la fonte (les fontes Web sont généralement distribuées dans des fichiers ZIP contenant les fichiers de police et l'information de licence). Vous pouvez trouver plusieurs fichiers de polices dans le paquet — certaines fontes sont distribuées sous forme de familles avec plusieurs variantes disponibles, par exemple fine, moyenne, grasse, italique, italique fine, etc. Pour cet exemple, ne vous interessez qu'à un seul fichier pour chacun des deux cas.</p>
+
+<div class="note">
+<p><strong>Note </strong>: Dans la partie « Find fonts » dans la colonne de droite, vous pouvez cliquer sur les diverses marques et classification pour filtrer les chois à afficher.</p>
+</div>
+
+<h3 id="Créer_le_code_requis">Créer le code requis</h3>
+
+<p>Maintenant, créez le code requis (et les formats de police). Pour chaque police, suivez ces étapes :</p>
+
+<ol>
+ <li>Assurez-vous d'avoir satisfait aux exigences de la licence, si vous l'utilisez dans un projet commercial et/ou Web.</li>
+ <li>Allez sur le <a href="https://www.fontsquirrel.com/tools/webfont-generator">Webfont Generator</a> de Fontsquirrel.</li>
+ <li>Téléversez les deux fichiers de fontes avec le bouton <em>Upload Fonts</em>.</li>
+ <li>Cochez la case nommée « Yes, the fonts I'm uploading are legally eligible for web embedding » (<em>Oui, les fontes téléversées sont légalement éligibles à une intégration web</em>).</li>
+ <li>Cliquez sur « <em>Download your kit</em> » (<em>Télécharger le kit</em>) .</li>
+</ol>
+
+<p>Après que le générateur a terminé le traitement, vous obtenez un fichier ZIP à télécharger — enregistrez‑le dans le même répertoire que les fichiers HTML et CSS.</p>
+
+<h3 id="Mise_en_œuvre_du_code_dans_la_démo">Mise en œuvre du code dans la démo</h3>
+
+<p>Maintenant, faites l'extraction de l'ensemble des polices web crées. Dans le répertoire d'extraction, trois éléments utiles :</p>
+
+<ul>
+ <li>Plusieurs versions de chaque police : (par ex., <code>.ttf</code>, <code>.woff</code>, <code>.woff2</code>, etc. ; les polices exactement fournies sont mises à jour au fur et à mesure des modifications des exigences de prise en charge des navigateurs). Comme mentionné ci‑dessus, plusieurs polices sont nécessaires pour une prise en charge croisée entre navigateurs — c'est le moyen choisi par Fontsquirrel pour s'assurer que vous avez bien ce qui est nécessaire.</li>
+ <li>Un fichier HTML de démo pour chaque police — chargez‑les dans votre navigateur pour voir ce à quoi elles ressemblent dans divers contextes d'emploi.</li>
+ <li>Un fichier <code>stylesheet.css</code>, qui contient le code @font-face dont vous avez besoin.</li>
+</ul>
+
+<p>Pour mettre en œuvre ces polices dans la démo, suivez ces étapes :</p>
+
+<ol>
+ <li>Renommez le répertoire d'extraction avec quelque chose de simple, comme <code>fonts</code>.</li>
+ <li>Ouvrez le fichier <code>stylesheet.css</code> et copiez y les deux blocs <code>@font-face</code> contenus dans le  fichier <code>web-font-start.css</code> — il faut les mettre tout en haut, avant tout élement du CSS, car les polices doivent être importées avant de pouvoir les utiliser sur votre site.</li>
+ <li>Chaque fonction <code>url()</code> pointe sur un fichier de police à importer dans la CSS — assurez‑vous que les chemins vers les fichiers soient corrects, donc ajoutez  <code>fonts/</code> au début de chaque chemin (si nécessaire).</li>
+ <li>Maintenant, vous pouvez vous servir de ces polices dans vos piles de fontes, tout à fait comme les polices système ou une police « web safe ». Par exemple :
+ <pre class="brush: css">font-family: 'zantrokeregular', serif;</pre>
+ </li>
+</ol>
+
+<p>Vous devriez obtenir une page de démonstration avec les belles polices implémentées ci‑dessus. Comme les diverses polices sont créées en différentes tailles, il se peut que vous deviez ajuster la taille, l'espacement, etc. pour parfaire l'aspect.</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/12984/web-font-example.png" style="border-style: solid; border-width: 1px; display: block; margin: 0px auto;"></p>
+
+<div class="note">
+<p><strong>Note</strong> : Si vous avez des problèmes pour faire fonctionner votre travail, n'hésitez pas à comparer votre version à nos fichiers finis — voyez <a href="https://github.com/mdn/learning-area/blob/master/css/styling-text/web-fonts/web-font-finished.html">web-font-finished.html</a> et <a href="https://github.com/mdn/learning-area/blob/master/css/styling-text/web-fonts/web-font-finished.css">web-font-finished.css</a> (lancez l'<a href="http://mdn.github.io/learning-area/css/styling-text/web-fonts/web-font-finished.html">exemple terminé directement</a>).</p>
+</div>
+
+<h2 id="Utiliser_un_service_de_polices_en_ligne">Utiliser un service de polices en ligne</h2>
+
+<p>Les services de polices en ligne stockent et servent généralement des polices pour vous afin que vous n'ayez pas à vous soucier d'écrire le code <code>@font-face</code>, et en général, il suffit d'insérer une simple ligne ou deux de code dans votre site pour que tout fonctionne. Les exemples incluent <a href="https://typekit.com/">Typekit</a> and <a href="http://www.typography.com/cloud/welcome/">Cloud.typography</a>. La plupart de ces services sont fondés sur l'abonnement, à l'exception notable de <a href="https://www.google.com/fonts">Google Fonts</a>, un service gratuit utile, en particulier pour les tests rapides et la rédaction de démos.</p>
+
+<p> </p>
+
+<p>La plupart de ces services sont faciles à utiliser, donc nous n'en parlerons pas dans le détail. Regardons rapidement les polices de Google, pour que vous puissiez vous faire une idée. Encore une fois, utilisez des copies de <code>web-font-start.html</code> et <code>web-font-start.css</code> comme point de départ.</p>
+
+<ol>
+ <li>Allez sur <a href="https://www.google.com/fonts">Google Fonts</a>.</li>
+ <li>Utilisez les filtres sur la droite pour afficher les types de polices à choisir et retenez une paire de fontes qui vous plaisent.</li>
+ <li>Pour sélectionner une famille de fontes, pressez le bouton ⊕ sur le côté.</li>
+ <li>Après avoir choisi les familles de fontes, pressez la barre avec  <em>[Nombre] Families Selected</em> en bas de la page.</li>
+ <li>Dans l'écran résultant, copiez d'abord la ligne de code HTML affichée et collez‑la dans l'en-tête de votre fichier HTML. Mettez-la au-dessus de l'élément {{htmlelement("link")}} existant, de sorte que la police soit importée avant que le navigateur essaye de l'utiliser dans la CSS.</li>
+ <li>Copiez ensuite les déclarations CSS listées dans la CSS comme il convient pour appliquer la fonte personnalisée à votre HTML.</li>
+</ol>
+
+<div class="note">
+<p><strong>Note</strong> : Vous pourrez trouver une version complétée sur <a href="https://github.com/mdn/learning-area/blob/master/css/styling-text/web-fonts/google-font.html">google-font.html</a> et <a href="https://github.com/mdn/learning-area/blob/master/css/styling-text/web-fonts/google-font.css">google-font.css</a>, si vous avez besoin de vérifier votre travail par rapport au nôtre (<a href="http://mdn.github.io/learning-area/css/styling-text/web-fonts/google-font.html">voir en direct</a>).</p>
+</div>
+
+<h2 id="font-face_plus_en_détail">@font-face plus en détail</h2>
+
+<p>Examinons la syntaxe générée par fontsquirrel pour <code>@font-face</code>. C'est un bloc de ce type :</p>
+
+<pre class="brush: css">@font-face {
+ font-family: 'ciclefina';
+ src: url('fonts/cicle_fina-webfont.eot');
+ src: url('fonts/cicle_fina-webfont.eot?#iefix') format('embedded-opentype'),
+ url('fonts/cicle_fina-webfont.woff2') format('woff2'),
+ url('fonts/cicle_fina-webfont.woff') format('woff'),
+ url('fonts/cicle_fina-webfont.ttf') format('truetype'),
+ url('fonts/cicle_fina-webfont.svg#ciclefina') format('svg');
+ font-weight: normal;
+ font-style: normal;
+}</pre>
+
+<p>Elle est désignée sous le vocable « bulletproof @font-face syntax » (<em>syntaxe @font-face à puces garanties</em>), d'après un post de Paul Irish lors des débuts des succès de <code>@font-face</code> (<a href="http://www.paulirish.com/2009/bulletproof-font-face-implementation-syntax/">Bulletproof @font-face Syntax</a>). Voyons les actions :</p>
+
+<ul>
+ <li><code>font-family</code> : cette ligne précise la référence à la police. Vous pouvez mettre cette assertion comme bon vous semble, pour autant que ce soit utilisé de manière cohérent dans la CSS.</li>
+ <li><code>src</code> : ces lignes indiquent les chemins vers les fichiers de fontes à importer dans la CSS (la partie <code>url</code>) et le format de chaque fichier de fonte (la partie <code>format</code>). Cette dernière partie est dans chaque cas optionnelle, mais il est utile de la déclarer car elle permet aux navigateurs de trouver la police à utiliser plus rapidement. Plusieurs déclarations peuvent être mises dans la liste, séparées par des virgules — le navigateur cherchera parmi celles-ci et utilisera la première trouvée qu'il comprend — toutefois il est préférable de mettre en tête les formats nouveaux comme WOFF2 et le plus anciens comme TTF en fin de liste. Les fontes EOT font exception — elles seront placées en tête pour corriger une paire de bogues dans les anciennes versions de IE, car IE essayera d'utiliser la première trouvée même s'il est en fait incapable de l'utiliser.</li>
+ <li>{{cssxref("font-weight")}}/{{cssxref("font-style")}} : ces lignes définissent la graisse de la police, si elle est italique ou pas. Si vous importez plusieurs graisses d'une même police, vous pouvez indiquer quelles sont ses caractéristiques et utiliser diverses valeurs de {{cssxref("font-weight")}}/{{cssxref("font-style")}} pour faire votre choix au lieu d'appeler de noms différents les membres de la même famille. <a href="http://www.456bereastreet.com/archive/201012/font-face_tip_define_font-weight_and_font-style_to_keep_your_css_simple/">@font-face tip: define font-weight and font-style to keep your CSS simple</a> (<em>en anglais — Astuces pour @font-face : définir la graisse et le style des fontes pour avoir des CSS simples</em>) par Roger Johansson montre que faire plus en détail.</li>
+</ul>
+
+<div class="note">
+<p><strong>Note </strong>: Vous pouvez aussi définir des valeurs particulières de {{cssxref("font-variant")}} et {{cssxref("font-stretch")}} pour vos polices. Dans les navigateurs les plus récents, vous pouvez également indiquer une valeur pour {{cssxref("unicode-range")}} : c'est la plage des codes caractères dont l'utilisation est prévue — dans les navigateurs prenant en charge cette propriété, seuls les caractères indiqués seront téléchargés, ce qui réduit les volumes téléchargés non nécessaires. <a href="https://24ways.org/2011/creating-custom-font-stacks-with-unicode-range/">Creating Custom Font Stacks with Unicode-Range</a> (<em>Création de piles de fontes personnalisées en définissant des plages unicode</em>) de Drew McLellan donne quelques indications utiles pour l'utilisation de cette propriété.</p>
+</div>
+
+<h2 id="Résumé">Résumé</h2>
+
+<p>Maintenant que vous avez travaillé nos articles sur les principes fondamentaux pour composer du texte, il est temps de tester votre compréhension de la chose avec notre évaluation pour le module : composition d'une page d'accueil d'une école communale.</p>
+
+<p>{{PreviousMenuNext("Learn/CSS/Styling_text/Styling_links", "Learn/CSS/Styling_text/Typesetting_a_homepage", "Learn/CSS/Styling_text")}}</p>
+
+<p> </p>
+
+<h2 id="Dans_ce_module">Dans ce module</h2>
+
+<p> </p>
+
+<ul>
+ <li><a href="/fr/docs/Learn/CSS/Styling_text/initiation-mise-en-forme-du-texte">Initiation à la mise en forme du texte</a></li>
+ <li><a href="/fr/docs/Learn/CSS/Styling_text/Styling_lists">Style de listes</a></li>
+ <li><a href="/fr/docs/Learn/CSS/Styling_text/Mise_en_forme_des_liens">Mise en forme des liens</a></li>
+ <li>Polices de caractères web</li>
+ <li><a class="new" href="/fr/docs/Learn/CSS/Styling_text/Typesetting_a_homepage" rel="nofollow">Composition d'une page d'accueil d'une école de communauté</a></li>
+</ul>
diff --git a/files/fr/learn/javascript/first_steps/a_first_splash/index.html b/files/fr/learn/javascript/first_steps/a_first_splash/index.html
new file mode 100644
index 0000000000..674bcefd33
--- /dev/null
+++ b/files/fr/learn/javascript/first_steps/a_first_splash/index.html
@@ -0,0 +1,708 @@
+---
+title: Notre premier code JavaScript
+slug: Learn/JavaScript/First_steps/A_first_splash
+tags:
+ - Apprendre
+ - Article
+ - CodingScripting
+ - Débutant
+ - Fonctions
+ - JavaScript
+ - Objets
+ - Opérateurs
+ - Variables
+ - structures conditionnelles
+translation_of: Learn/JavaScript/First_steps/A_first_splash
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/JavaScript/First_steps/What_is_JavaScript", "Learn/JavaScript/First_steps/What_went_wrong", "Learn/JavaScript/First_steps")}}</div>
+
+<p class="summary">Maintenant que vous avez appris quelques éléments théoriques sur le JavaScript, et ce que vous pouvez faire avec, nous allons vous donner un cours intensif sur les fonctionnalités basiques du JavaScript avec un tutoriel entièrement pratique. Vous allez construire un jeu simple, étape par étape. Il s'agit de faire deviner un nombre, notre jeu s'appelle « Guess the number ».</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Prérequis :</th>
+ <td>Une culture informatique basique, et des notions de HTML et CSS.</td>
+ </tr>
+ <tr>
+ <th scope="row">Objectif :</th>
+ <td>Avoir une première expérience d'écriture de JavaScript et comprendre les implications de l'écriture d'un programme en JavaScript.</td>
+ </tr>
+ </tbody>
+</table>
+
+<p>Ne vous attendez pas à comprendre tout le code en détail immédiatement — nous voulons simplement vous présenter les grands concepts pour le moment, et vous donner une idée de la façon dont JavaScript (et d'autres langages de programmation) fonctionne. Dans les articles suivants, vous reviendrez plus en détails sur toutes ces fonctionnalités !</p>
+
+<div class="note">
+<p>Note : De nombreuses fonctionnalités que vous allez voir en JavaScript sont identiques à celles d'autres langages de programmation — fonctions, boucles, etc. La syntaxe du code est différente mais les concepts sont globalement identiques.</p>
+</div>
+
+<h2 id="Penser_comme_un_programmeur">Penser comme un programmeur</h2>
+
+<p>Une des choses les plus difficiles à apprendre en programmation n'est pas la syntaxe, mais comment l'appliquer afin de résoudre un problème réel. Vous devez commencer à penser comme un programmeur — ce qui implique généralement d'examiner les tâches que votre programme doit effectuer, de déterminer les fonctionnalités du code nécessaires à leurs réalisations et comment les faire fonctionner ensemble.</p>
+
+<p>Cela requiert un mélange de travail acharné, d'expérience avec la syntaxe de programmation (de manière générale) et surtout de la pratique — ainsi qu'un peu de créativité. Plus vous allez coder, plus vous aller vous améliorer. On ne peut pas garantir que vous aurez un « cerveau de développeur » en 5 minutes, mais nous allons vous donner plein d'occasions pour pratiquer cette façon de penser, tout au long du cours.</p>
+
+<p>Maintenant que vous avez cela en tête, regardons l'exemple que nous allons construire dans cet article et comment le découper en plusieurs tâches qui ont du sens.</p>
+
+<h2 id="Exemple_—_Jeu_Guess_the_number">Exemple — Jeu : Guess the number</h2>
+
+<p><span id="result_box" lang="fr"><span>Dans cet article, nous allons vous montrer comment construire le jeu simple que vous pouvez voir ci-dessous :</span></span></p>
+
+<div class="hidden">
+<h6 id="Top_hidden_code">Top hidden code</h6>
+
+<pre class="brush: html">&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+
+&lt;head&gt;
+ &lt;meta charset="utf-8"&gt;
+ &lt;title&gt;Number guessing game&lt;/title&gt;
+ &lt;style&gt;
+ html {
+ font-family: sans-serif;
+ }
+
+ body {
+ width: 50%;
+ max-width: 800px;
+ min-width: 480px;
+ margin: 0 auto;
+ }
+
+ .lastResult {
+ color: white;
+ padding: 3px;
+ }
+ &lt;/style&gt;
+&lt;/head&gt;
+
+&lt;body&gt;
+ &lt;h1&gt;Deviner un nombre&lt;/h1&gt;
+ &lt;p&gt;Nous avons généré un nombre aléatoire entre 1 et 100, tentez de le deviner en 10 tours maximum. Pour chaque tentative, nous vous dirons si votre estimation est trop ou pas assez élevée.&lt;/p&gt;
+ &lt;div class="form"&gt; &lt;label for="guessField"&gt;Entrez votre proposition : &lt;/label&gt;&lt;input type="text" id="guessField" class="guessField"&gt; &lt;input type="submit" value="Valider" class="guessSubmit"&gt; &lt;/div&gt;
+ &lt;div class="resultParas"&gt;
+ &lt;p class="guesses"&gt;&lt;/p&gt;
+ &lt;p class="lastResult"&gt;&lt;/p&gt;
+ &lt;p class="lowOrHi"&gt;&lt;/p&gt;
+ &lt;/div&gt;
+&lt;/body&gt;
+&lt;script&gt;
+ // Le JavaScript se place ici
+ let randomNumber = Math.floor(Math.random() * 100) + 1;
+ let guesses = document.querySelector('.guesses');
+ let lastResult = document.querySelector('.lastResult');
+ let lowOrHi = document.querySelector('.lowOrHi');
+ let guessSubmit = document.querySelector('.guessSubmit');
+ let guessField = document.querySelector('.guessField');
+ let guessCount = 1;
+ let resetButton;
+
+ function checkGuess() {
+ let userGuess = Number(guessField.value);
+ if (guessCount === 1) {
+ guesses.textContent = 'Propositions précédentes : ';
+ }
+
+ guesses.textContent += userGuess + ' ';
+
+ if (userGuess === randomNumber) {
+ lastResult.textContent = 'Bravo, vous avez trouvé le nombre !';
+ lastResult.style.backgroundColor = 'green';
+ lowOrHi.textContent = '';
+ setGameOver();
+ } else if (guessCount === 10) {
+ lastResult.textContent = '!!! PERDU !!!';
+ lowOrHi.textContent = '';
+ setGameOver();
+ } else {
+ lastResult.textContent = 'Faux!';
+ lastResult.style.backgroundColor = 'red';
+ if (userGuess &lt; randomNumber) {
+ lowOrHi.textContent='Le nombre saisi est trop petit !' ;
+ } else if(userGuess &gt; randomNumber) {
+ lowOrHi.textContent = 'Le nombre saisi est trop grand!';
+ }
+ }
+
+ guessCount++;
+ guessField.value = '';
+ }
+
+ guessSubmit.addEventListener('click', checkGuess);
+
+ function setGameOver() {
+ guessField.disabled = true;
+ guessSubmit.disabled = true;
+ resetButton = document.createElement('button');
+ resetButton.textContent = 'Rejouer';
+ document.body.appendChild(resetButton);
+ resetButton.addEventListener('click', resetGame);
+ }
+
+ function resetGame() {
+ guessCount = 1;
+ let resetParas = document.querySelectorAll('.resultParas p');
+ for (let i = 0 ; i &lt; resetParas.length ; i++) {
+ resetParas[i].textContent='';
+ }
+
+ resetButton.parentNode.removeChild(resetButton);
+ guessField.disabled = false;
+ guessSubmit.disabled = false;
+ guessField.value='';
+ guessField.focus();
+ lastResult.style.backgroundColor='white';
+ randomNumber=Math.floor(Math.random() * 100) + 1;
+ }
+&lt;/script&gt;
+
+&lt;/html&gt;</pre>
+</div>
+
+<p>{{ EmbedLiveSample('Top_hidden_code', '100%', 320, "", "", "hide-codepen-jsfiddle") }}</p>
+
+<p><span id="result_box" lang="fr"><span>Essayez de jouer et familiarisez-vous avec ce jeu avant de continuer.</span><br>
+ <br>
+ <span>Imaginons que votre patron vous ait donné le résumé suivant pour créer ce jeu :</span></span></p>
+
+<blockquote>
+<p><span id="result_box" lang="fr"><span>Je vous demande de créer un jeu simple de devinette de </span><span>nombre. Le jeu choisit aléatoirement un nombre entre 1 et 100, puis il met le joueur au défi de le deviner en 10 tentatives maxi.</span> <span>À chaque tour, le joueur doit être informé s'il a deviné ou non le bon nombre — si ce n'est pas le cas, le jeu lui indique si son estimation est trop basse ou trop élevée.</span> Le jeu<span> doit également rappeler au joueur les nombres déjà proposés.</span> <span>Le jeu se termine quand le joueur a deviné le nombre mystère, ou s'il a épuisé ses 10 chances.</span> </span>À<span lang="fr"><span> la fin du jeu, le joueur a la possibilité de débuter une nouvelle partie.</span></span></p>
+</blockquote>
+
+<p>La première chose à faire en regardant ce résumé, c'est de le décomposer en tâches simples et codables comme le ferait un programmeur :</p>
+
+<ol>
+ <li>Générer un nombre aléatoire entre 1 et 100.</li>
+ <li>Stocker le nombre de tours déjà joués. Commencer par 1.</li>
+ <li>Fournir au joueur le moyen de saisir un nombre.</li>
+ <li>Stocker l'ensemble des propositions de nombres pour que le joueur puisse les consulter.</li>
+ <li>Vérifier si le nombre saisi par le joueur est correct.</li>
+ <li>S'il est correct :
+ <ol>
+ <li>Afficher un message de félicitations.</li>
+ <li>Empêcher que le joueur saisisse de nouveau un nombre.</li>
+ <li>Afficher un contrôle pour que le joueur puisse rejouer.</li>
+ </ol>
+ </li>
+ <li>S'il est faux et que le joueur a encore des tours à jouer :
+ <ol>
+ <li>Informer le joueur que sa proposition de nombre est fausse.</li>
+ <li>Lui permettre d'entrer une nouvelle proposition de nombre.</li>
+ <li>Incrémenter le nombre de tours de 1.</li>
+ </ol>
+ </li>
+ <li>S'il est faux et que le joueur n'a plus de tours à jouer :
+ <ol>
+ <li>Informer le joueur qu'il a perdu et que la partie est finie.</li>
+ <li>Empêcher que le joueur saisisse de nouveau un nombre.</li>
+ <li>Afficher un contrôle pour que le joueur puisse rejouer.</li>
+ </ol>
+ </li>
+ <li><span id="result_box" lang="fr"><span title="Once the game restarts, make sure the game logic and UI are completely reset, then go back to step 1.
+
+">Une fois le jeu redémarré, s'assurer que la logique du jeu et l'interface utilisateur sont complètement réinitialisées, puis revenir à l'étape 1.</span></span></li>
+</ol>
+
+<p><span id="result_box" lang="fr"><span title="Let's now move forward, looking at how we can turn these steps into code, building up the example, and exploring JavaScript features as we go.">Voyons maintenant comment nous pouvons transformer ces étapes en code. Nous allons développer cet exemple et explorer les fonctionnalités JavaScript </span></span><span lang="fr"><span title="Let's now move forward, looking at how we can turn these steps into code, building up the example, and exploring JavaScript features as we go.">au fur et à mesure.</span></span></p>
+
+<h3 id="Configuration_initiale">Configuration initiale</h3>
+
+<p>Pour commencer ce didacticiel, faites une copie locale du fichier <a href="https://github.com/mdn/learning-area/blob/master/javascript/introduction-to-js-1/first-splash/number-guessing-game-start.html">number-guessing-game-start.html</a>  (à voir <a href="http://mdn.github.io/learning-area/javascript/introduction-to-js-1/first-splash/number-guessing-game-start.html">directement ici</a>). Ouvrez-le dans votre éditeur de code et votre navigateur web. Pour l'instant, vous ne verrez qu'un titre, un paragraphe d'instructions et un formulaire pour entrer une estimation, mais le formulaire est pour l'instant inactif.</p>
+
+<p>L'endroit où nous allons ajouter tout notre code se trouve dans l'élément {{htmlelement ("script")}} au bas du code HTML :</p>
+
+<pre class="brush: html">&lt;script&gt;
+
+ // Votre code JavaScript se place ici
+
+&lt;/script&gt;
+</pre>
+
+<h3 id="Ajouter_des_variables_pour_stocker_les_données">Ajouter des variables pour stocker les données</h3>
+
+<p>Commençons. Tout d'abord, ajoutez les lignes suivantes dans l'élément {{htmlelement ("script")}} :</p>
+
+<pre class="brush: js">let randomNumber = Math.floor(Math.random() * 100) + 1;
+
+let guesses = document.querySelector('.guesses');
+let lastResult = document.querySelector('.lastResult');
+let lowOrHi = document.querySelector('.lowOrHi');
+
+let guessSubmit = document.querySelector('.guessSubmit');
+let guessField = document.querySelector('.guessField');
+
+let guessCount = 1;
+let resetButton;</pre>
+
+<p>Cette partie de code définit les variables nécessaires au stockage des données que notre programme utilisera. Les variables sont essentiellement des conteneurs de valeurs (tels que des nombres ou des chaînes de texte). Une variable se crée avec le mot-clé <code>let</code> suivi du nom de la variable. Vous pouvez ensuite attribuer une valeur à la variable avec le signe égal (<code>=</code>) suivi de la valeur que vous voulez lui donner.</p>
+
+<p>Dans notre exemple :</p>
+
+<ul>
+ <li>La première variable — <code>randomNumber</code> — reçoit le nombre aléatoire entre 1 et 100, calculé en utilisant un algorithme mathématique.</li>
+ <li>Les trois variables suivantes sont chacune faite pour stocker une référence aux paragraphes de résultats dans le HTML ; elles sont utilisées pour insérer des valeurs dans les paragraphes plus tard dans le code :
+ <pre class="brush: html">&lt;p class="guesses"&gt;&lt;/p&gt;
+&lt;p class="lastResult"&gt;&lt;/p&gt;
+&lt;p class="lowOrHi"&gt;&lt;/p&gt;</pre>
+ </li>
+ <li>Les deux variables suivantes stockent des références au champ de saisie du formulaire et au bouton de soumission ; elles sont utilisées pour écouter l'envoi de la supposition (guess) plus tard.
+ <pre class="brush: html">&lt;label for="guessField"&gt;Enter a guess: &lt;/label&gt;&lt;input type="text" id="guessField" class="guessField"&gt;
+&lt;input type="submit" value="Submit guess" class="guessSubmit"&gt;</pre>
+ </li>
+ <li>Nos deux dernières variables stockent un nombre de suppositions qui vaut initialement 1 (utilisées pour garder une trace du nombre de suppositions que le joueur a faite) et une référence à un bouton de réinitialisation qui n'existe pas encore.</li>
+</ul>
+
+<div class="note">
+<p><strong>Note </strong>: Vous en apprendrez beaucoup plus sur les variables plus tard dans le cours, en commençant par le <a href="/fr/docs/Learn/JavaScript/First_steps/Variables">prochain article</a>.</p>
+</div>
+
+<h3 id="Fonctions">Fonctions</h3>
+
+<p>Ajoutez maintenant ce qui suit dans votre code JavaScript :</p>
+
+<pre class="brush: js">function checkGuess() {
+ alert('Je suis un espace réservé');
+}</pre>
+
+<p>Les fonctions sont des blocs de code réutilisables que vous pouvez écrire une fois et exécuter encore et encore, pour éviter de réécrire le même code tout le temps. C'est vraiment utile. Il y a plusieurs façons de définir les fonctions, mais pour l'instant nous allons nous concentrer sur un type simple. Ici, nous avons défini une fonction en utilisant le mot-clé <code>function</code> accompagné de son nom suivi de parenthèses. Ensuite, nous avons mis deux accolades (<code>{ }</code>). Dans ces accolades est placé tout le code à exécuter à chaque appel de la fonction.</p>
+
+<p>Quand nous voulons exécuter le code, nous saisissons le nom de la fonction suivi des parenthèses.</p>
+
+<p>Essayez. Enregistrez le code et actualisez la page du navigateur. Puis, allez dans les<a href="/fr/Apprendre/D%C3%A9couvrir_outils_d%C3%A9veloppement_navigateurs"> outils de développement et la console JavaScript </a>et entrez la ligne suivante :</p>
+
+<pre class="brush: js">checkGuess();</pre>
+
+<p>Après avoir pressé <kbd>Entrée</kbd> ou <kbd>Retour</kbd>, vous devriez voir apparaître une alerte « Je suis un espace réservé » ; nous avons défini une fonction dans notre code créant une alerte chaque fois que nous l'appelons.</p>
+
+<div class="note">
+<p><strong>Note</strong> : Vous allez en apprendre beaucoup plus sur les fonctions plus tard dans ce cours.</p>
+</div>
+
+<h3 id="Opérateurs">Opérateurs</h3>
+
+<p>Les opérateurs en JavaScript nous permettent d'effectuer des tests, de faire des calculs, de joindre des chaînes ensemble et d'autres choses de ce genre.</p>
+
+<p>Si vous ne l'avez pas déjà fait, sauvegardez ce code, actualisez la page affichée dans le navigateur et ouvrez les<a href="/fr/Apprendre/D%C3%A9couvrir_outils_d%C3%A9veloppement_navigateurs"> outils de développement et la console Javascript</a>. Ensuite, vous pouvez saisir les exemples ci‑dessous — saisissez chacun dans les colonnes « Exemple » exactement comme indiqué, en appuyant sur la touche <kbd>Entrée</kbd> du clavier après chacun et regardez le résultat renvoyé. Si vous n'avez pas facilement accès aux outils de développement du navigateur, vous pouvez toujours utiliser la console intégrée ci-dessous :</p>
+
+<div class="hidden">
+<h6 id="Hidden_code">Hidden code</h6>
+
+<pre class="brush: html">&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+ &lt;head&gt;
+ &lt;meta charset="utf-8"&gt;
+ &lt;title&gt;Console JavaScript&lt;/title&gt;
+ &lt;style&gt;
+ * {
+ box-sizing: border-box;
+ }
+
+ html {
+ background-color: #0C323D;
+ color: #809089;
+ font-family: monospace;
+ }
+
+ body {
+ max-width: 700px;
+ }
+
+ p {
+ margin: 0;
+ width: 1%;
+ padding: 0 1%;
+ font-size: 16px;
+ line-height: 1.5;
+ float: left;
+ }
+
+ .input p {
+ margin-right: 1%;
+ }
+
+ .output p {
+ width: 100%;
+ }
+
+ .input input {
+ width: 96%;
+ float: left;
+ border: none;
+ font-size: 16px;
+ line-height: 1.5;
+ font-family: monospace;
+ padding: 0;
+ background: #0C323D;
+ color: #809089;
+ }
+
+ div {
+ clear: both;
+ }
+
+ &lt;/style&gt;
+ &lt;/head&gt;
+ &lt;body&gt;
+
+
+ &lt;/body&gt;
+
+ &lt;script&gt;
+ let geval = eval;
+
+ function createInput() {
+ let inputDiv = document.createElement('div');
+ let inputPara = document.createElement('p');
+ let inputForm = document.createElement('input');
+
+ inputDiv.setAttribute('class','input');
+ inputPara.textContent = '&gt;';
+ inputDiv.appendChild(inputPara);
+ inputDiv.appendChild(inputForm);
+ document.body.appendChild(inputDiv);
+ inputDiv.focus();
+
+ if (document.querySelectorAll('div').length &gt; 1) {
+        inputForm.focus();
+      }
+
+ inputForm.addEventListener('change', executeCode);
+ }
+
+ function executeCode(e) {
+ try {
+ let result = geval(e.target.value);
+ } catch(e) {
+ let result = 'error — ' + e.message;
+ }
+
+ let outputDiv = document.createElement('div');
+ let outputPara = document.createElement('p');
+
+ outputDiv.setAttribute('class','output');
+ outputPara.textContent = 'Résultat : ' + result;
+ outputDiv.appendChild(outputPara);
+ document.body.appendChild(outputDiv);
+
+ e.target.disabled = true;
+ e.target.parentNode.style.opacity = '0.5';
+
+ createInput()
+ }
+
+ createInput();
+
+ &lt;/script&gt;
+&lt;/html&gt;</pre>
+</div>
+
+<p>{{ EmbedLiveSample('Hidden_code', '100%', 300,"", "", "hide-codepen-jsfiddle") }}</p>
+
+<p>Regardons d'abord les opérateurs arithmétiques, par exemple :</p>
+
+<table class="standard-table">
+ <thead>
+ <tr>
+ <th scope="col">Operator</th>
+ <th scope="col">Name</th>
+ <th scope="col">Example</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td><code>+</code></td>
+ <td>Addition</td>
+ <td><code>6 + 9</code></td>
+ </tr>
+ <tr>
+ <td><code>-</code></td>
+ <td>Soustraction</td>
+ <td><code>20 - 15</code></td>
+ </tr>
+ <tr>
+ <td><code>*</code></td>
+ <td>Multiplication</td>
+ <td><code>3 * 7</code></td>
+ </tr>
+ <tr>
+ <td><code>/</code></td>
+ <td>Division</td>
+ <td><code>10 / 5</code></td>
+ </tr>
+ </tbody>
+</table>
+
+<p>L'opérateur <code>+</code> peut aussi s'utiliser pour unir des chaînes de caractères (en informatique, on dit <em>concaténer</em>). Entrez les lignes suivantes, une par une :</p>
+
+<pre class="brush: js">let name = 'Bingo';
+name;
+let hello = ' dit bonjour !';
+hello;
+let greeting = name + hello;
+greeting;</pre>
+
+<p>Des raccourcis d'opérateurs sont également disponibles, appelés <a href="https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Opérateurs/Opérateurs_d_affectation">opérateurs d'assignation</a> augmentés. Par exemple, si vous voulez simplement ajouter une nouvelle chaîne de texte à une chaîne existante et renvoyer le résultat, vous pouvez faire :</p>
+
+<pre class="brush: js">name += ' dit bonjour !';</pre>
+
+<p>Cela équivaut à :</p>
+
+<pre class="brush: js">name = name + ' dit bonjour !';</pre>
+
+<p>Lorsque nous exécutons des tests vrai/faux (par exemple, dans des conditions — voir {{anch ("Structures conditionnelles", "ci-dessous")}}, nous utilisons des <a href="/fr/docs/Web/JavaScript/Reference/Operators/Comparison_Operators">opérateurs de comparaison</a>, par exemple :</p>
+
+<table class="standard-table">
+ <thead>
+ <tr>
+ <th scope="col">Operator</th>
+ <th scope="col">Name</th>
+ <th scope="col">Example</th>
+ </tr>
+ <tr>
+ <td><code>===</code></td>
+ <td>Égalité stricte (est-ce exactement identique ?)</td>
+ <td><code>5 === 2 + 4</code></td>
+ </tr>
+ <tr>
+ <td><code>!==</code></td>
+ <td>Non égalité (est-ce différent ?)</td>
+ <td><code>'Chris' !== 'Ch' + 'ris'</code></td>
+ </tr>
+ <tr>
+ <td><code>&lt;</code></td>
+ <td>Inférieur à</td>
+ <td><code>10 &lt; 6</code></td>
+ </tr>
+ <tr>
+ <td><code>&gt;</code></td>
+ <td>Supérieur à</td>
+ <td><code>10 &gt; 20</code></td>
+ </tr>
+ </thead>
+</table>
+
+<h3 id="Structures_conditionnelles">Structures conditionnelles</h3>
+
+<p>Revenons à la fonction <code style="font-size: 16px !important; line-height: 24px !important;">checkGuess()</code>. Nous pouvons assurément dire que nous ne souhaitons pas qu'elle renvoie un message d'emplacement réservé. Nous voulons qu'elle vérifie si la supposition du joueur est correcte ou non et qu'elle renvoie une réponse appropriée.</p>
+
+<p>Donc, remplacez l'actuelle fonction <code style="font-size: 16px !important; line-height: 24px !important;">checkGuess()</code> par celle-ci :</p>
+
+<pre class="brush: js line-numbers language-js"><code class="language-js">function checkGuess(){
+ let userGuess = Number(guessField.value);
+ if (guessCount === 1) {
+ guesses.textContent = 'Propositions précédentes : ';
+ }
+ guesses.textContent += userGuess + ' ';
+
+ if (userGuess === randomNumber) {
+ lastResult.textContent = 'Bravo, vous avez trouvé le nombre !';
+ lastResult.style.backgroundColor = 'green';
+ lowOrHi.textContent = '';
+ setGameOver();
+ } else if (guessCount === 10) {
+ lastResult.textContent = '!!! PERDU !!!';
+ setGameOver();
+ } else {
+ lastResult.textContent = 'Faux !';
+ lastResult.style.backgroundColor = 'red';
+ if (userGuess &lt; randomNumber) {
+ lowOrHi.textContent = 'Le nombre saisi est trop petit !';
+ } else if (userGuess &gt; randomNumber) {
+ lowOrHi.textContent = 'Le nombre saisi est trop grand !';
+ }
+ }
+
+ guessCount++;
+ guessField.value = '';
+ guessField.focus();
+}
+</code></pre>
+
+<p>Pas mal de code — ouf ! Passons en revue chaque section et expliquons ce qu'elle fait.</p>
+
+<ul>
+ <li>La première ligne de la fonction (ligne 2) déclare une variable nommée <code>userGuess</code> et définit sa valeur par celle qui vient d'être saisie dans le champ de texte. Nous faisons passer aussi cette valeur par la méthode  <code style="font-size: 16px !important; line-height: 24px !important;">Number()</code> , juste pour nous assurer que la valeur stockée dans <code>userGuess</code> est bien un nombre.</li>
+ <li>Ensuite, nous rencontrons notre premier bloc de code conditionnel (lignes 3-5). Il permet d'exécuter des instructions de manière sélective, selon certaines conditions qui sont vraies ou non. Cela ressemble un peu à une fonction, mais ce n'est pas le cas. La forme la plus simple du bloc conditionnel commence par le mot clé <code>if</code>, puis parenthèses, puis des accolades <code>{ }</code>.<br>
+ A l'intérieur de ces parenthèses, nous mettons le test. S'il renvoie <code>true</code> , nous exécutons le code à l'intérieur des accolades. Sinon, nous ne le faisons pas, et passons au morceau de code suivant. Dans ce cas, le test vérifie si la variable <code>guessCount</code> est égale à <code>1</code> (c'est-à-dire s'il s'agit de la première supposition du joueur) :
+ <pre class="brush: js">guessCount === 1</pre>
+ Si c'est le cas, nous faisons en sorte que le texte affiché soit « Propositions précédentes : ». Sinon, nous ne le faisons pas.</li>
+ <li>La ligne 6 ajoute la valeur courante <code>userGuess</code> à la fin du paragraphe <code>guesses</code> , plus un espace vide de sorte qu'il y aura un espace entre chaque supposition faite.</li>
+ <li>Le bloc suivant (lignes 8-24) effectue quelques vérifications :
+ <ul>
+ <li>Le premier <code>if(){ }</code> vérifie si la supposition de l'utilisateur est égale au nombre aléatoire <code>randomNumber</code> situé en haut de notre code JavaScript. Si c'est le cas, le joueur a deviné correctement et a gagné le jeu, nous affichons donc un message de félicitations d'une belle couleur verte au joueur, effaçons le contenu de la boîte d'information sur la position de l'estimation et exécutons une fonction appelée <code>setGameOver()</code>, dont nous reparlerons plus tard.</li>
+ <li>Ensuite, nous chaînons un autre test à la fin du précédent avec une structure <code>else if(){ }</code>. Cette structure vérifie si l'utilisateur a épuisé toutes ses tentatives. Si c'est le cas, le programme fait la même chose que dans le bloc précédent, mais avec un message de fin de partie au lieu d'un message de félicitations.</li>
+ <li>Le dernier bloc chaîné à la fin de ce code (<code>else { }</code>) contient du code qui n'est exécuté que si aucun des deux autres tests n'a renvoyé <em>vrai</em> (c'est-à-dire que le joueur n'a pas deviné juste, mais qu'il lui reste des possibilité de supposition). Dans ce cas, nous lui disons que sa supposition est mauvaise, puis nous effectuons un autre test conditionnel pour vérifier si elle est supérieure ou inférieure à la valeur exacte et affichons un autre message approprié pour indiquer si sa supposition est trop forte ou trop faible.</li>
+ </ul>
+ </li>
+</ul>
+
+<ul>
+ <li>Les trois dernières lignes de la fonction (ligne 26-28) préparent à une nouvelle proposition. Nous ajoutons 1 à la variable <code>guessCount</code> qui décompte les tours (<code>++</code> est une opération d'incrémentation — ajout de 1), puis effaçons le champ texte du formulaire et lui redonnons le focus, pour être prêt pour la saisie suivante.</li>
+</ul>
+
+<h3 id="Evénements">Evénements</h3>
+
+<p>À ce stade, nous avons bien implémentée la fonction <code>checkGuess()</code>, mais elle ne s'éxecutera pas parce que nous ne l'avons pas encore appelé.<br>
+ Idéalement, nous voulons l'appeler lorsque le bouton <kbd>Soumettre</kbd> est cliqué, et pour ce faire, nous devons utiliser un événement. Les événements sont des actions qui se produisent dans le navigateur, comme le clic sur un bouton, le chargement d'une page ou la lecture d'une vidéo, en réponse à quoi nous pouvons exécuter des blocs de code. Les constructions qui écoutent l'événement en cours s'appellent des <strong>écouteurs d'événements</strong>, et les blocs de code exécutés en réponse à l'événement déclencheur sont appelés des <strong>gestionnaires d'évenements</strong>.<br>
+ <br>
+ Ajoutez la ligne suivante sous l'accolade de fermeture de votre fonction <code>checkGuess()</code> :</p>
+
+<pre class="brush: js">guessSubmit.addEventListener('click', checkGuess);</pre>
+
+<p>Ici, nous ajoutons un écouteur d'événement au bouton <code>guessSubmit</code> . C'est une méthode qui prend deux valeurs d'entrée (appelées arguments) - le type d'événement que nous écoutons (dans ce cas, <code>click</code>) qui est une chaîne de caractères, et le code que nous voulons exécuter quand l'événement se produit (dans ce cas, la fonction <code>checkGuess()</code>  — notez que nous n'avons pas besoin de spécifier les parenthèses lors de l'écriture dans {{domxref("EventTarget.addEventListener", "addEventListener()")}}).</p>
+
+<p>Essayez d'enregistrer et d'actualiser votre code, votre exemple devrait désormais fonctionner, jusqu'à un certain point. Maintenant, le seul problème est que si vous devinez la bonne réponse ou si vous n'avez plus de tours à jouer, le jeu "va se casser" parce que nous n'avons pas encore implémenté la fonction <code>setGameOver()</code> dont le rôle est de terminer proprement le jeu. Ajoutons maintenant le code manquant pour compléter notre exemple.</p>
+
+<h3 id="Finir_les_fonctionnalités_du_jeu">Finir les fonctionnalités du jeu</h3>
+
+<p>Pour définir la fonction <code>setGameOver()</code> à la fin de notre programme, ajoutez le code ci-dessous tout en bas :</p>
+
+<pre class="brush: js">function setGameOver() {
+ guessField.disabled = true;
+ guessSubmit.disabled = true;
+ resetButton = document.createElement('button');
+ resetButton.textContent = 'Start new game';
+ document.body.appendChild(resetButton);
+ resetButton.addEventListener('click', resetGame);
+}</pre>
+
+<ul>
+ <li>Les deux premières lignes désactivent l'entrée de texte et le bouton en définissant leurs propriétés désactivées à <code>true</code>.  Ceci est nécessaire, car si nous ne le faisons pas, l'utilisateur pourrait soumettre plus de propositions après la fin du jeu, ce qui gâcherait les choses.</li>
+ <li>Les trois lignes suivantes génèrent un nouvel {{htmlelement("button")}} élément, avec le libellé "Démarrer une nouvelle partie" et l'ajoute au bas du HTML existant.</li>
+ <li>La dernière ligne définit un écouteur d'événement sur ce nouveau bouton : un click sur le bouton déclenchera un appel de la fonction  <code>resetGame()</code>.</li>
+</ul>
+
+<p>Reste à définir cette fonction ! Ajoutez le code suivant, tout en bas de votre JavaScript :</p>
+
+<pre class="brush: js">function resetGame() {
+ guessCount = 1;
+
+ let resetParas = document.querySelectorAll('.resultParas p');
+ for (let i = 0 ; i &lt; resetParas.length ; i++) {
+ resetParas[i].textContent = '';
+ }
+
+ resetButton.parentNode.removeChild(resetButton);
+
+ guessField.disabled = false;
+ guessSubmit.disabled = false;
+ guessField.value = '';
+ guessField.focus();
+
+ lastResult.style.backgroundColor = 'white';
+
+ randomNumber = Math.floor(Math.random() * 100) + 1;
+}</pre>
+
+<p>Ce bloc de code assez long réinitialise complètement les paramètres du jeu (le joueur pourra commencer une nouvelle partie). Il permet de  :</p>
+
+<ul>
+ <li>Remettre le compteur <code>guessCount</code> à 1.</li>
+ <li>Effacer tous les paragraphes d'information.</li>
+ <li>Supprimer le bouton de réinitialisation de notre code.</li>
+ <li>Activer les éléments de formulaire, vide et met au point le champ de texte, prêt à entrer une nouvelle proposition.</li>
+ <li>Supprimer la couleur d'arrière-plan du paragraphe <code>lastResult</code>.</li>
+ <li>Génèrer un nouveau nombre aléatoire afin que vous ne deviniez plus le même nombre !</li>
+</ul>
+
+<p><strong>À ce stade, vous devriez avoir un jeu (simple) entièrement fonctionnel — félicitations!</strong></p>
+
+<p>Pour finir, c'est le moment de faire une synthèse sur  quelques caractéristiques importantes du code ;  vous les avez déjà vues, sans forcément vous en rendre compte.</p>
+
+<h3 id="Boucles">Boucles</h3>
+
+<p>Dans le code précédent, une partie à examiner de plus près est la boucle <a href="/fr/docs/Web/JavaScript/Reference/Instructions/for">for</a>. Les boucles sont un concept très important dans la programmation, qui vous permet de continuer à exécuter un morceau de code encore et encore, jusqu'à ce qu'une certaine condition soit remplie.</p>
+
+<p>Pour commencer, allez sur votre <a href="/fr/Apprendre/D%C3%A9couvrir_outils_d%C3%A9veloppement_navigateurs">console developpeur Javascript</a> et entrez ce qui suit :</p>
+
+<pre class="brush: js">for (let i = 1 ; i &lt; 21 ; i++) { console.log(i) }</pre>
+
+<p>Que s'est-il passé ? Les nombres de 1 à 20 s'affichent dans la console. C'est à cause de la boucle. Une boucle : <code>for</code>  prend trois valeurs d'entrée (arguments)</p>
+
+<ol>
+ <li><strong>Une valeur de départ </strong>: Dans ce cas, nous commençons un compte à 1, mais cela pourrait être n'importe quel nombre. Vous pouvez remplacer <code>i</code> par n'importe quel nom (ou presque...) , mais <code>i</code> est utilisé par convention car il est court et facile à retenir.</li>
+ <li><strong>Une condition de fin </strong>: Ici, nous avons spécifié  <code>i &lt; 21</code> la boucle continuera jusqu'à ce que  <code>i</code>  ne soit plus inférieur à 21. Quand <code>i</code> atteindra ou dépassera 21, la boucle s'arrêtera.</li>
+ <li><strong>Un incrémenteur </strong>:  Nous avons spécifié <code>i++</code>, ce qui signifie "ajouter 1 à i". La boucle sera exécutée une fois pour chaque valeur de <code>i</code>, jusqu'a ce que <code>i</code> atteigne une valeur de 21 (comme indiqué ci-dessus). Dans ce cas, nous imprimons simplement la valeur de <code>i</code>  sur la console à chaque itération en utilisant {{domxref("Console.log", "console.log()")}}.</li>
+</ol>
+
+<p>Maintenant, regardons la boucle dans notre jeu de devinettes de nombres <strong>—</strong> ce qui suit peut être trouvé dans la fonction <code>resetGame()</code> :</p>
+
+<pre class="brush: js">let resetParas = document.querySelectorAll('.resultParas p');
+for (let i = 0 ; i &lt; resetParas.length ; i++) {
+ resetParas[i].textContent = '';
+}</pre>
+
+<p>Ce code crée une variable contenant une liste de tous les paragraphes à l'intérieur de <code>&lt;div class="resultParas"&gt;</code>  en utilisant la méthode {{domxref ("Document.querySelectorAll", "querySelectorAll ()")}}, puis il passe dans la boucle et pour chacun d'entre eux supprime le contenu du texte.</p>
+
+<h3 id="Une_petite_discussion_sur_les_objets">Une petite discussion sur les objets</h3>
+
+<p>Voyons une dernière amélioration avant d'aborder cette discussion. Ajoutez la ligne suivante juste en dessous de <code>let resetButton;</code> ligne près du haut de votre JavaScript, puis enregistrez votre fichier :</p>
+
+<pre class="brush: js">guessField.focus();</pre>
+
+<p>Cette ligne utilise la méthode{{domxref("HTMLElement.focus", "focus()")}} pour placer automatiquement le curseur dans le champ texte {{htmlelement ("input")}} dès le chargement de la page, permettant à l'utilisateur de commencer à taper sa première proposition de suite sans avoir à cliquer préalablement dans le champ. Ce n'est qu'un petit ajout, mais cela améliore la convivialité  en donnant à l'utilisateur une bonne idée visuelle de ce qu'il doit faire pour jouer.</p>
+
+<p>Analysons ce qui se passe ici un peu plus en détail. En JavaScript, tout est objet. Un objet JavaScript possède des propriétés, chacune définissant une caractéristique. Vous pouvez créer vos propres objets, mais cela est une notion assez avancée, nous ne la couvrirons que beaucoup plus tard dans le cours. Pour l'instant, nous allons discuter brièvement des objets intégrés que contient votre navigateur, ce qui vous permet de faire beaucoup de choses utiles.</p>
+
+<p>Dans ce cas particulier, nous avons d'abord créé une variable <code>guessField</code> qui stocke une référence au champ de formulaire de saisie de texte dans notre HTML <strong>—</strong> la ligne suivante se trouve parmi nos déclarations de variables en haut du code :</p>
+
+<pre class="brush: js">let guessField = document.querySelector('.guessField');</pre>
+
+<p>Pour obtenir cette référence, nous avons utilisé la méthode {{domxref("document.querySelector", "querySelector()")}} de l'objet {{domxref ("document")}}. <code>querySelector()</code> prend une information - un <a href="/fr/docs/Apprendre/CSS/Introduction_à_CSS/Les_sélecteurs">sélecteur CSS </a>qui sélectionne l'élément auquel vous voulez faire référence.</p>
+
+<p>Parce que <code>guessField</code> contient maintenant une référence à un élément {{htmlelement ("input")}}, il aura maintenant accès à un certain nombre de propriétés (essentiellement des variables stockées dans des objets, dont certaines ne peuvent pas être modifiées) et des méthodes (essentiellement des fonctions stockées dans des objets). Une méthode disponible pour entrer des éléments est <code>focus()</code>, donc nous pouvons maintenant utiliser cette ligne pour focaliser l'entrée de texte :</p>
+
+<pre class="brush: js">guessField.focus();</pre>
+
+<p>Les variables qui ne contiennent pas de références aux éléments de formulaire n'auront pas de <code>focus()</code> à leur disposition. Par exemple, la variable <code>guesses</code> contient une référence à un élément {{htmlelement ("p")}} et <code>guessCount</code> contient un nombre.</p>
+
+<h3 id="Jouer_avec_les_objets_du_navigateur">Jouer avec les objets du navigateur</h3>
+
+<p>Jouons un peu avec certains objets du navigateur.</p>
+
+<ol>
+ <li> Tout d'abord, ouvrez votre programme dans un navigateur.</li>
+ <li> Ensuite, ouvrez les <a href="/fr/docs/Apprendre/Découvrir_outils_développement_navigateurs">outils de développement</a> de votre navigateur et assurez-vous que l'onglet de la console JavaScript est ouvert.</li>
+ <li> Tapez <code>guessField</code> et la console vous montrera que la variable contient un élément {{htmlelement ("input")}}. Vous remarquerez également que la console complète automatiquement les noms d'objets existant dans l'environnement d'exécution, y compris vos variables!</li>
+ <li>
+ <p> Maintenant, tapez ce qui suit :</p>
+
+ <pre class="brush: js">guessField.value = 'Hello';
+</pre>
+
+ <p class="brush: js">La propriété <code>value</code> représente la valeur courante entrée dans un champs de texte. Vous verrez qu'en entrant cette commande nous avons changé ce que c'est.</p>
+ </li>
+ <li>Tapez maintenant <code>guesses</code> and appuyez sur entrée. La console vous montrera que la variable contient un élément {{htmlelement ("p")}}.</li>
+ <li>
+ <p>Maintenant, essayez d'entrer la ligne suivante :</p>
+
+ <pre class="brush: js">guesses.value
+</pre>
+
+ <p class="brush: js">Le navigateur va retourner <code>undefined</code>, parce que <code>value</code> n'existe pas dans le paragraphe.</p>
+ </li>
+ <li>
+ <p>Pour changer le texte dans le paragraphe vous aurez besoin de  la propriété {{domxref("Node.textContent", "textContent")}} à la place.<br>
+ Essayez ceci :</p>
+
+ <pre class="brush: js">guesses.textContent = 'Where is my paragraph?';
+</pre>
+ </li>
+ <li>Maintenant, pour des trucs amusants. Essayez d'entrer les lignes ci-dessous, une par une :</li>
+</ol>
+
+<pre class="brush: js" dir="rtl">guesses.style.backgroundColor = 'yellow';
+guesses.style.fontSize = '200%';
+guesses.style.padding = '10px';
+guesses.style.boxShadow = '3px 3px 6px black';</pre>
+
+<p>Chaque élément d'une page possède une propriété de <code>style</code> , qui contient elle-même un objet dont les propriétés contiennent tous les styles CSS en ligne appliqués à cet élément. Cela nous permet de définir dynamiquement de nouveaux styles CSS sur des éléments en utilisant JavaScript.</p>
+
+<h2 id="Cest_fini_pour_le_moment...">C'est fini pour le moment...</h2>
+
+<p>Vous voilà parvenu au bout de cet exemple, bravo ! Essayez votre code enfin complété ou<a href="https://mdn.github.io/learning-area/javascript/introduction-to-js-1/first-splash/number-guessing-game.html"> jouez avec notre version finale ici</a>. Si vous ne parvenez pas à faire fonctionner l'exemple, vérifiez-le par rapport <a href="https://github.com/mdn/learning-area/blob/master/javascript/introduction-to-js-1/first-splash/number-guessing-game.html">au code source.</a></p>
+
+<p>{{PreviousMenuNext("Learn/JavaScript/First_steps/What_is_JavaScript", "Learn/JavaScript/First_steps/What_went_wrong", "Learn/JavaScript/First_steps")}}</p>
diff --git a/files/fr/learn/javascript/first_steps/index.html b/files/fr/learn/javascript/first_steps/index.html
new file mode 100644
index 0000000000..70e5a0c1f0
--- /dev/null
+++ b/files/fr/learn/javascript/first_steps/index.html
@@ -0,0 +1,70 @@
+---
+title: Premiers pas en JavaScript
+slug: Learn/JavaScript/First_steps
+tags:
+ - Article
+ - Auto-évaluation
+ - Chaînes de caractères
+ - Débutant
+ - Guide
+ - JavaScript
+ - Module
+ - Nombres
+ - Opérateurs
+ - Tableaux
+ - Variables
+translation_of: Learn/JavaScript/First_steps
+---
+<div>{{LearnSidebar}}</div>
+
+<p class="summary">Dans notre premier module consacré à JavaScript, nous allons tout d'abord répondre à des questions fondamentales comme « qu'est-ce que JavaScript ? », « à quoi ressemble-t-il ? » et « de quoi est-il capable ? ». Nous vous accompagnerons ensuite dans votre première expérience pratique consistant à écrire du code JavaScript. Après cela, nous examinerons en détail quelques briques de base, telles que les variables, les chaînes de caractères, les nombres, et les tableaux.</p>
+
+<h2 id="Prérequis"><strong>Prérequis</strong></h2>
+
+<p>Avant d'entamer ce module, vous n'avez besoin d'aucune connaissance préalable en JavaScript, mais vous devriez être familier avec HTML et CSS. Nous vous conseillons de lire les modules suivants avant d'aller plus loin :</p>
+
+<ul>
+ <li><a href="https://developer.mozilla.org/fr/Apprendre/HTML/Introduction_%C3%A0_HTML">Commencer avec le Web</a> (qui inclut une <a href="/en-US/docs/Learn/Getting_started_with_the_web/JavaScript_basics">présentation basique de JavaScript</a>).</li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Introduction">Introduction au langage HTML</a>.</li>
+ <li><a href="https://developer.mozilla.org/fr/Apprendre/CSS/Introduction_%C3%A0_CSS">Introduction au langage CSS</a>.</li>
+</ul>
+
+<div class="note">
+<p><strong>Note </strong>: Si vous travaillez depuis un ordinateur, une tablette ou depuis un autre appareil sur lequel vous ne pouvez pas créer vos propres fichiers, vous pourrez tester la plupart des exemples en ligne grâce à des outils comme <a href="http://jsbin.com/">JSBin</a> ou <a href="https://thimble.mozilla.org/">Thimble</a>.</p>
+</div>
+
+<h2 id="Guides">Guides</h2>
+
+<dl>
+ <dt><a href="https://developer.mozilla.org/fr/docs/Learn/JavaScript/First_steps/What_is_JavaScript">Qu'est-ce que JavaScript ?</a></dt>
+ <dd>Bienvenue dans le cours de JavaScript pour débutants proposé par MDN ! Dans ce premier article, nous aborderons JavaScript sous un angle général afin de comprendre ce qu'il est et à quoi il sert. Nous nous assurerons ici que vous cernez bien le but premier du langage.</dd>
+ <dt><a href="/fr/docs/Learn/JavaScript/First_steps/A_first_splash">Notre premier code JavaScript</a></dt>
+ <dd>
+ <p>Maintenant que vous en savez un peu plus sur la partie théorique de JavaScript et sur ce que vous pouvez réaliser avec, nous allons poursuivre avec un cours accéléré sur les fonctionnalités de base du langage par le biais d'un tutoriel axé sur la pratique. Vous développerez ici, pas à pas, un jeu simple consistant à faire deviner un nombre.</p>
+ </dd>
+ <dt><a href="/fr/docs/Learn/JavaScript/First_steps/What_went_wrong">Qu'est-ce qui n'a pas fonctionné ? Déboguer du code JavaScript</a></dt>
+ <dd>
+ <p>Quand vous développiez le jeu de devinette dans le cadre du tutoriel précédent, vous avez pu constater que notre programme ne fonctionnait pas. Pas de panique — cet article est là pour vous éviter de vous arracher les cheveux sur de tels problèmes en vous donnant quelques conseils simples sur la manière de trouver et résoudre les erreurs dans vos programmes JavaScript.</p>
+ </dd>
+ <dt><a href="/fr/docs/Learn/JavaScript/First_steps/Variables">Stocker les informations dont vous avez besoin — les variables</a></dt>
+ <dd>
+ <p>Après avoir lu les articles précédents, vous devriez maintenant mieux comprendre ce qu'est JavaScript, ce qu'il peut faire pour vous, comment l'utiliser de pair avec d'autres technologies du Web, et à quoi ressemblent ses principales fonctionnalités d'un point de vue global. Dans cet article, nous allons aborder les véritables fondements, en présentant l'une des pierres angulaires du langage : les variables.</p>
+ </dd>
+ <dt><a href="/fr/docs/Learn/JavaScript/First_steps/Math">Mathématiques de base en JavaScript — nombres et opérateurs</a></dt>
+ <dd>À ce stade du cours, nous allons parler de mathématiques en JavaScript, à savoir comment combiner des opérateurs arithmétiques avec d'autres fonctionnalités du langage pour arriver à nos fins.</dd>
+ <dt><a href="/fr/docs/Learn/JavaScript/First_steps/Strings">Gérer du texte — les chaînes de caractères en JavaScript</a></dt>
+ <dd>Attaquons-nous maintenant aux chaînes de caractères — le nom savant désignant en programmation des portions de texte. Dans cet article, nous allons voir les bases que vous devez impérativement connaître lors de votre apprentissage de JavaScript, comme la création de chaînes, l'échappement de caractères et la jonction de plusieurs chaînes.</dd>
+ <dt><a href="/fr/docs/Learn/JavaScript/First_steps/methode_chaine_utile">Méthodes utiles pour les chaînes de caractères</a></dt>
+ <dd>Maintenant que nous avons vu les bases relatives aux chaînes de catactères, passons à la vitesse supérieure et regardons ce que nous pouvons faire de plus poussé avec lesdites chaînes grâce aux méthodes natives, comme par exemple déterminer la longueur d'un texte, joindre et séparer des chaînes, remplacer un caractère par un autre, et bien plus encore.</dd>
+ <dt><a href="/fr/docs/Learn/JavaScript/First_steps/tableaux">Les tableaux</a></dt>
+ <dd>Dans le dernier article de ce module, nous allons nous pencher sur les tableaux — un moyen ingénieux de stocker une liste d'éléments dans une unique variable. Ici nous allons voir en quoi cela est pratique, puis nous verrons entre autres comment créer un tableau et comment récupérer, ajouter et supprimer des éléments stockés.</dd>
+</dl>
+
+<h2 id="Auto-évaluation">Auto-évaluation</h2>
+
+<p>L'auto-évaluation suivante teste votre compréhension des bases de JavaScript abordées dans le guide ci-dessus.</p>
+
+<dl>
+ <dt><a href="https://developer.mozilla.org/fr/docs/Learn/JavaScript/First_steps/Silly_story_generator">Génerateur d'histoires absurdes</a></dt>
+ <dd>Dans le cadre de cette évaluation, votre tâche sera d'utiliser les connaissances que vous avez apprises dans les articles de ce module et de les appliquer pour créer une appli ludique qui génère aléatoirement des histoires absurdes. Amusez-vous bien !</dd>
+</dl>
diff --git a/files/fr/learn/javascript/first_steps/math/index.html b/files/fr/learn/javascript/first_steps/math/index.html
new file mode 100644
index 0000000000..2d35ee076b
--- /dev/null
+++ b/files/fr/learn/javascript/first_steps/math/index.html
@@ -0,0 +1,449 @@
+---
+title: Mathématiques de base en JavaScript — nombres et opérateurs
+slug: Learn/JavaScript/First_steps/Math
+tags:
+ - Apprendre
+ - Article
+ - Codage de scripts
+ - Débutant
+ - Guide
+ - Incrémentation
+ - JavaScript
+ - Math
+ - Opérateurs
+ - augmenté
+ - maths
+ - modulo
+translation_of: Learn/JavaScript/First_steps/Math
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/JavaScript/First_steps/Variables", "Learn/JavaScript/First_steps/Strings", "Learn/JavaScript/First_steps")}}</div>
+
+<p class="summary">À ce point du didacticiel, nous parlerons de « mathématiques en JavaScript » — comment utiliser les {{Glossary("Operator","operators")}} et autres fonctionnalités pour manier avec succès les nombres pour faire nos bricolages.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Prérequis :</th>
+ <td>Vocabulaire courant de l'informatique, bases de HTML et CSS, compréhension de ce que fait JavaScript.</td>
+ </tr>
+ <tr>
+ <th scope="row">Objectif :</th>
+ <td>Se familiariser avec les bases des maths en JavaScript.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Tout_le_monde_aime_les_maths">Tout le monde aime les maths</h2>
+
+<p>Mouais, peut‑être pas. Certains parmi nous aiment les maths, d'autres les détestent depuis qu'il leur a fallu apprendre les tables de multiplication et les longues divisions à l'école, d'autres se situent entre les deux. Mais personne ne peut nier que les mathématiques sont une connaissance fondamentale dont il n'est pas possible de se passer. Cela devient particulièrement vrai lorsque nous apprenons à programmer en JavaScript (ou tout autre langage d'ailleurs) — une grande part de ce que nous faisons reposant en effet sur le traitement de données numériques, le calcul de nouvelles valeurs, etc. ; vous ne serez donc pas étonné d'apprendre que JavaScript dispose d'un ensemble complet de fonctions mathématiques.</p>
+
+<p>Cet article ne traite que des éléments de base nécessaires pour débuter.</p>
+
+<h3 id="Types_de_nombres">Types de nombres</h3>
+
+<p>En programmation, même l'ordinaire système des nombres décimaux que nous connaissons tous si bien est plus compliqué qu'on ne pourrait le croire. Nous utilisons divers termes pour décrire différents types de nombres décimaux, par exemple :</p>
+
+<ul>
+ <li><strong>Entier :</strong> (<em>Integer </em>en anglais) c'est un nombre sans partie fractionnaire, comme son nom l'indique, par exemple 10, 400 ou -5</li>
+ <li><strong>Nombre à virgule flottante : </strong>(<em>float </em>en anglais) il a un <strong>point</strong> de séparation entre la partie entière et la partie fractionnaire (là où en France nous mettons une virgule), par exemple 12<strong>.</strong>5 et 56<strong>.</strong>7786543</li>
+ <li><strong>Doubles</strong> : (pour double précision) ce sont des nombres à virgule flottante de précision supérieure aux précédents (on les dit plus précis en raison du plus grand nombre de décimales possibles).</li>
+</ul>
+
+<p>Nous disposons même de plusieurs systèmes de numération !  Le décimal a pour base 10 (ce qui signifie qu'il se sert de chiffres entre 0 et 9 dans chaque rang), mais il en existe d'autres :</p>
+
+<ul>
+ <li><strong>Binaire</strong> — utilisé par le plus bas niveau de langage des ordinateurs, il est composé de 0 et de 1.</li>
+ <li><strong>Octal</strong> — de base 8, utilise les chiffres entre 0 et 7 dans chaque rang.</li>
+ <li><strong>Hexadécimal</strong> — de base 16, utilise les chiffres entre 0 et 9 puis les lettres de a à f dans chaque rang. Vous avez peut-être déjà rencontré ces nombres en définissant des couleurs dans les <a href="/en-US/Learn/CSS/Introduction_to_CSS/Values_and_units#Hexadecimal_values">CSS</a>.</li>
+</ul>
+
+<p><strong>Avant que votre cervelle ne se mette à bouillir, stop !</strong> Pour commencer, nous ne nous intéresserons qu'aux nombres décimaux dans ce cours ; vous aurez rarement besoin de vous servir des autres types, peut-être même jamais.</p>
+
+<p>L'autre bonne nouvelle, c'est que contrairement à d'autres langages de programmation, JavaScript n'a qu'un seul type de donnée pour les nombres, vous l'avez deviné : {{jsxref("Number")}}. Cela signifie que, en JavaScript, quels que soient les types de nombre avec lesquels vous travaillerez, vous les manipulerez tous exactement de la même façon.</p>
+
+<h3 id="Ce_ne_sont_que_des_nombres_pour_moi">Ce ne sont que des nombres pour moi</h3>
+
+<p>Amusons‑nous avec quelques chiffres pour nous familiariser avec la syntaxe de base dont nous aurons besoin. Entrez les commandes listées ci-dessous dans la <a href="/en-US/docs/Learn/Common_questions/What_are_browser_developer_tools">console JavaScript des outils de développement</a>, ou utilisez la simple console intégrée que vous voyez ci-dessous si vous préférez.</p>
+
+<p>{{EmbedGHLiveSample("learning-area/javascript/introduction-to-js-1/variables/index.html", '100%', 300)}}</p>
+
+<p><strong><a href="https://mdn.github.io/learning-area/javascript/introduction-to-js-1/variables/">Ouvrir la console dans une nouvelle fenêtre</a></strong></p>
+
+<ol>
+ <li>Premièrement, déclarons une paire de variables et initialisons‑les respectivement  avec un entier et un nombre avec des décimales, puis saisissons les noms des variables à nouveau pour vérifier que tout est correct :
+ <pre class="brush: js notranslate">var myInt = 5;
+var myFloat = 6.667;
+myInt;
+myFloat;</pre>
+ </li>
+ <li>Les nombres sont saisis sans guillemets — essayez de déclarer et initialiser deux ou trois variables de plus contenant des nombres avant de continuer.</li>
+ <li>Maintenant vérifions que les deux variables d'origine sont du même type de donnée. En JavaScript, l'opérateur nommé {{jsxref("Operators/typeof", "typeof")}} est prévu pour cela. Entrez les deux lignes ci‑dessous comme indiqué :</li>
+ <li>
+ <pre class="brush: js notranslate" dir="rtl">typeof myInt;
+typeof myFloat;</pre>
+ </li>
+ <li><code>"number"</code> est renvoyé dans les deux cas — cela nous facilite les choses quand nous avons des nombres différents de types variés et que nous avons à les traiter de diverses façons. Ouf !</li>
+</ol>
+
+<h3 id="Méthodes_de_nombres_utiles">Méthodes de nombres utiles</h3>
+
+<p>L'objet <code><a href="https://wiki.developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number">Number</a></code> , une instance qui représente tous les nombres standards que vous utiliserez dans votre JavaScript, a de nombreuses méthodes disponibles pour vous permettre de manipuler les nombres. Nous ne les étudierons pas tous en détail dans cet article car nous voulons qu'il reste une simple introduction et nous verrons seulement les bases essentielles pour le moment; cependant, une fois que vous aurez lu ce module plusieurs fois, il pourra être  utile de visiter les pages de référence d'objet et d'en apprendre plus sur ce qui est disponible.</p>
+
+<p>Par exemple, pour arrondir votre nombre avec un nombre fixe de décimales, utilisez la méthode <code><a href="https://wiki.developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed">toFixed()</a></code>. Tapez les lignes suivantes dans la <a href="https://wiki.developer.mozilla.org/en-US/docs/Tools/Web_Console">console de votre navigateur</a>:</p>
+
+<pre class="brush: js notranslate">let lotsOfDecimal = 1.766584958675746364;
+lotsOfDecimal;
+let twoDecimalPlaces = lotsOfDecimal.toFixed(2);
+twoDecimalPlaces;</pre>
+
+<h3 id="Convertir_en_type_de_données_numérique">Convertir en type de données numérique</h3>
+
+<p>Parfois vous pourriez finir avec un nombre stocké de type "string", ce qui rendra difficile le fait d'effectuer un calcul avec. Ca arrive le plus souvent lorsqu'une donnée est entrée dans une entrée de <a href="https://wiki.developer.mozilla.org/en-US/docs/Learn/Forms">formulaire</a>, et le <a href="https://wiki.developer.mozilla.org/en-US/docs/Web/HTML/Element/input/text">type de donnée entré est du texte</a>. Il éxiste une façon de résoudre ce problème — passer la valeur de "string" dans le constructeur <code><a href="https://wiki.developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/Number">Number()</a></code> pour retourner  une version numérique de la même valeur.</p>
+
+<p>Par exemple, essayez de taper ces lignes dans votre console:</p>
+
+<pre class="brush: js notranslate">let myNumber = '74';
+myNumber + 3;</pre>
+
+<p>Vous obtenez le résultat 743, et non pas 77, car <code>myNumber</code> est en fait défini en tant que "string". Vous pouvez tester en tapant la ligne suivante:</p>
+
+<pre class="brush: js notranslate">typeof myNumber;</pre>
+
+<p>Pour réparer le calcul, vous pouvez faire ceci:</p>
+
+<pre class="brush: js notranslate">Number(myNumber) + 3;</pre>
+
+<h2 id="Opérateurs_arithmétiques">Opérateurs arithmétiques</h2>
+
+<p>Ce sont les opérateurs de base pour effectuer diverses opérations :</p>
+
+<table class="standard-table">
+ <thead>
+ <tr>
+ <th scope="col">Operateur</th>
+ <th scope="col">Nom</th>
+ <th scope="col">But</th>
+ <th scope="col">Exemple</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td><code>+</code></td>
+ <td>Addition</td>
+ <td>Ajoute deux nombres.</td>
+ <td><code>6 + 9</code></td>
+ </tr>
+ <tr>
+ <td><code>-</code></td>
+ <td>Soustraction</td>
+ <td>Soustrait le nombre de droite de celui de gauche.</td>
+ <td><code>20 - 15</code></td>
+ </tr>
+ <tr>
+ <td><code>*</code></td>
+ <td>Multiplication</td>
+ <td>Multiplie les deux nombrer.</td>
+ <td><code>3 * 7</code></td>
+ </tr>
+ <tr>
+ <td><code>/</code></td>
+ <td>Division</td>
+ <td>Divise le nombre de gauche par celui de droite.</td>
+ <td><code>10 / 5</code></td>
+ </tr>
+ <tr>
+ <td><code>%</code></td>
+ <td>
+ <p>Reste (quelquefois nommé modulo)</p>
+ </td>
+ <td>
+ <p>Renvoie le reste de la division du nombre de gauche par celui de droite.</p>
+ </td>
+ <td><code>8 % 3</code> (renvoie 2, car 3 est contenu 2 fois dans 8, et il reste 2.)</td>
+ </tr>
+ </tbody>
+</table>
+
+<div class="note">
+<p><strong>Note </strong>: Quelquefois les nombres impliqués dans des opérations sont nommés {{Glossary("Operand", "operands")}}.</p>
+</div>
+
+<p>Nous n'avons certainement pas besoin de vous apprendre les quatre opérations, mais ce serait bien de tester si vous avez bien compris la syntaxe. Entrez les exemples ci‑dessous dans la <a href="/en-US/docs/Learn/Common_questions/What_are_browser_developer_tools">console des outils de développement JavaScript</a> ou servez vous de la console intégrée plus haut, comme vous préférez, pour vous familiariser avec la syntaxe.</p>
+
+<ol>
+ <li>Essayez de saisir quelques exemples simples de votre cru, comme :
+ <pre class="brush: js notranslate">10 + 7
+9 * 8
+60 % 3</pre>
+ </li>
+ <li>Déclarez et initialisez quelques variables, puis utilisez‑les dans des opérations — les variables se comporteront exactement comme les valeurs qu'elles contiennent pour les besoins de l'opération. Par exemple :
+ <pre class="brush: js notranslate">var num1 = 10;
+var num2 = 50;
+9 * num1;
+num2 / num1;</pre>
+ </li>
+ <li>Pour terminer cette partie, entrez quelques expressions plus compliquées, comme :
+ <pre class="brush: js notranslate">5 + 10 * 3;
+num2 % 9 * num1;
+num2 + num1 / 8 + 2;</pre>
+ </li>
+</ol>
+
+<p>Certaines opérations de cet ensemble ne vous renvoient peut-être pas le résultat attendu ; le paragraphe qui suit vous explique pourquoi.</p>
+
+<h3 id="Priorité_des_opérateurs">Priorité des opérateurs</h3>
+
+<p>Revenons sur le dernier exemple ci‑dessus, en supposant que <code>num2</code> contient la valeur 50 et <code>num1</code> contient 10 (comme défini plus haut) :</p>
+
+<pre class="brush: js notranslate">num2 + num1 / 8 + 2;</pre>
+
+<p>En tant qu'humain, vous pouvez lire  « <em>50 plus 10 égale 60 »</em>, puis « <em>8 plus 2 égale 10 »</em> et finalement « <em>60 divisé par 10 égale 6 »</em>.</p>
+
+<p>Mais le navigateur <em>calcule « 10 sur 8 égale 1.25 »</em>, puis « <em>50 plus 1.25 plus 2 égale 53.25 »</em>.</p>
+
+<p>Cela est dû aux <strong>priorités entre opérateurs</strong> — certains sont appliqués avant d'autres dans une opération (on parle d'une expression en programmation). En JavaScript, la priorité des opérateurs est identique à celle enseignée à l'école — Multiplication et Division sont toujours effectuées en premier, suivies d'Addition et Soustraction (le calcul est toujours exécuté de la gauche vers la droite).</p>
+
+<p>Si vous voulez contourner les règles de priorité des opérateurs, vous pouvez mettre entre parenthèses les parties que vous souhaitez voir calculées en premier. Pour obtenir un résultat égal à 6, nous devons donc écrire :</p>
+
+<pre class="brush: js notranslate">(num2 + num1) / (8 + 2);</pre>
+
+<p>Essayez-le et voyez.</p>
+
+<div class="note">
+<p><strong>Note </strong>: La liste complète de tous les opérateurs JavaScript et leur priorité peut être trouvée dans <a href="/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Operator_precedence">Expressions and operators</a>.</p>
+</div>
+
+<h2 id="Opérateurs_dincrémentation_et_de_décrémentation">Opérateurs d'incrémentation et de décrémentation</h2>
+
+<p>Quelquefois vous aurez besoin d'ajouter ou retrancher 1 à une valeur de variable de manière répétitive. On effectue commodément cette opération à l'aide des opérateurs d'incrémentation (<code>++</code>) ou de décrementation (<code>--</code>). Nous nous sommes servis de <code>++</code> dans le jeu « Devinez le nombre » dans notre article <a href="/en-US/docs/Learn/JavaScript/Introduction_to_JavaScript_1/A_first_splash">Première plongée dans le JavaScript</a> pour ajouter 1 à la variable <code>guessCount</code> pour décompter le nombre de suppositions restantes après chaque tour.</p>
+
+<pre class="brush: js notranslate">guessCount++;</pre>
+
+<div class="note">
+<p><strong>Note</strong> : Ces opérateurs sont couramment utilisés dans des <a href="/en-US/docs/Web/JavaScript/Guide/Loops_and_iteration">boucles ;</a> nous les verrons plus loin dans ce cours. Par exemple, disons que vous voulez parcourir une liste de prix et ajouter les taxes à chacun. Vous utiliserez une boucle pour obtenir chaque valeur une à une et exécuterez le calcul voulu pour ajouter les taxes à chacune. L'incrément s'utilise pour aller à la valeur suivante. Nous avons mis un exemple concret montrant comment faire — voyez‑le tout de suite, examinez le code source et notez les opérateurs d'incrémentation ! Nous reverrons les boucles en détail plus loin dans ce cours.</p>
+</div>
+
+<p>Jouons avec ces opérateurs dans la console. Notez d'abord qu'il n'est pas possible de les appliquer directement à un nombre, ce qui peut paraître étrange, mais cet opérateur assigne à une variable une nouvelle valeur mise à jour, il n'agit pas sur la valeur elle‑même. Ce qui suit renvoie une erreur :</p>
+
+<pre class="brush: js notranslate">3++;</pre>
+
+<p>Vous ne pouvez donc incrémenter qu'une variable déjà existante. Essayez ceci :</p>
+
+<pre class="brush: js notranslate">var num1 = 4;
+num1++;</pre>
+
+<p>Ok, curieuse la ligne 2 ! En écrivant cela, elle renvoie la valeur 4 — c'est dû au fait que l'explorateur renvoie la valeur courante, <em>puis</em> incrémente la variable. Vous constaterez qu'elle a bien été incrémentée si vous demandez de la revoir :</p>
+
+<pre class="brush: js notranslate">num1;</pre>
+
+<p>C'est pareil avec <code>--</code> : essayez ce qui suit</p>
+
+<pre class="brush: js notranslate">var num2 = 6;
+num2--;
+num2;</pre>
+
+<div class="note">
+<p><strong>Note </strong>: En mettant l'opérateur avant la variable au lieu d'après, le navigateur agira dans l'ordre inverse — incrément/décrément de la variable <em>puis</em> renvoi de la valeur — . Essayez les exemples plus haut, mais cette fois avec <code>++num1</code> et <code>--num2</code>.</p>
+</div>
+
+<h2 id="Opérateurs_dassignation">Opérateurs d'assignation</h2>
+
+<p>Les opérateurs d'assignation sont ceux qui fixent la valeur d'une variable. Nous avons déjà utilisé plusieurs fois le plus élémentaire, <code>=</code> — il donne à la variable de gauche la valeur indiquée à droite :</p>
+
+<pre class="brush: js notranslate">var x = 3; // x contient la valeur 3
+var y = 4; // y contient la valeur 4
+x = y; // x contient maintenant la même valeur que y, 4</pre>
+
+<p>Mais il existe des types plus complexes, qui procurent des raccourcis utiles pour un code plus propre et plus efficace. Les plus courants sont listés ici :</p>
+
+<table class="standard-table">
+ <thead>
+ <tr>
+ <th scope="col" style="width: 13%;">Opérateur</th>
+ <th scope="col" style="width: 17%;">Nom</th>
+ <th scope="col" style="width: 40%;">But</th>
+ <th scope="col" style="width: 12%;">Exemple</th>
+ <th scope="col" style="width: 18%;">Raccourci pour</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td><code>+=</code></td>
+ <td>Addition et assignation</td>
+ <td>Ajoute la valeur de droite à la valeur de la variable de gauche, puis renvoie la nouvelle valeur de la variable</td>
+ <td><code>x = 3;<br>
+ x += 4;</code></td>
+ <td><code>x = 3;<br>
+ x = x + 4;</code></td>
+ </tr>
+ <tr>
+ <td><code>-=</code></td>
+ <td>Soustraction et assignation</td>
+ <td>Soustrait la valeur de droite à la valeur de la variable de gauche, puis renvoie la nouvelle valeur de la variable</td>
+ <td><code>x = 6;<br>
+ x -= 3;</code></td>
+ <td><code>x = 6;<br>
+ x = x - 3;</code></td>
+ </tr>
+ <tr>
+ <td><code>*=</code></td>
+ <td>Multiplication et assignation</td>
+ <td>Multiplie la valeur de droite par la valeur de la variable de gauche, puis renvoie la nouvelle valeur de la variable</td>
+ <td><code>x = 2;<br>
+ x *= 3;</code></td>
+ <td><code>x = 2;<br>
+ x = x * 3;</code></td>
+ </tr>
+ <tr>
+ <td><code>/=</code></td>
+ <td>Division et assignation</td>
+ <td>Divise la valeur de la variable de gauche par la valeur de droite, puis renvoie la nouvelle valeur de la variable</td>
+ <td><code>x = 10;<br>
+ x /= 5;</code></td>
+ <td><code>x = 10;<br>
+ x = x / 5;</code></td>
+ </tr>
+ </tbody>
+</table>
+
+<p>Saisissez quelques uns de ces exemples dans la console pour avoir une idée de leur fonctionnement. Dans chaque cas, voyez si vous avez deviné la valeur avant de saisir la deuxième ligne.</p>
+
+<p>Notez que vous pouvez opportunément utiliser une autre variable comme opérateur sur la droite de chaque expression, par exemple :</p>
+
+<pre class="brush: js notranslate">var x = 3; // x contient la valeur 3
+var y = 4; // y contient la valeur 4
+x *= y; // x contient maintenant la valeur 12</pre>
+
+<div class="note">
+<p><strong>Note </strong>: Il y a des tas d'<a href="/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Assignment_operators">autres opérateurs d'assignation disponibles</a>, mais ceux‑ci sont les plus courants que vous devez les connaître dès maintenant.</p>
+</div>
+
+<h2 id="Apprentissage_actif_dimensionner_une_boîte_à_canevas">Apprentissage actif : dimensionner une boîte à canevas</h2>
+
+<p>Dans cet exercice, vous allez manier quelques nombres et opérateurs pour changer la taille d'une boîte. La boîte est tracée à l'aide de l'API de navigateur nommée {{domxref("Canvas API", "", "", "true")}}. Pas besoin de savoir comment elle fonctionne — concentrez-vous simplement sur les mathématiques pour l'instant. Les largeur et hauteur de la boîte (en pixels) sont définies par les variables <code>x</code> et <code>y</code>, qui sont toutes deux initialisées avec la valeur 50.</p>
+
+<p>{{EmbedGHLiveSample("learning-area/javascript/introduction-to-js-1/maths/editable_canvas.html", '100%', 520)}}</p>
+
+<p><strong><a href="https://mdn.github.io/learning-area/javascript/introduction-to-js-1/maths/editable_canvas.html">Ouvrir dans une nouvelle fenêtre</a></strong></p>
+
+<p>Le code dans la boîte ci-desssus peut être modifié. Un commentaire signale les deux lignes suivantes, que vous devez mettre à jour pour faire en sorte que la boîte grossisse ou rétrécisse aux tailles données, en utilisant certains opérateurs et/ou valeurs dans chaque cas. Essayez ce qui suit en réinitialisant à chaque étape :</p>
+
+<ul>
+ <li>Modifier la ligne qui calcule x pour que la boîte conserve sa largeur de 50 pixels, mais que 50 soit calculé avec les nombres 43 et 7 ainsi qu'un opérateur arithmétique.</li>
+ <li>Modifier la ligne qui calcule y pour que la boîte prenne une hauteur de 75 pixels, mais que 75 ait été calculé avec les nombres 25 et 3 ainsi qu'un opérateur arithmétique.</li>
+ <li>Modifier la ligne qui calcule x pour que la boîte prenne une largeur de 250pixels, mais que 250 ait été calculé avec deux nombres ainsi que l'opérateur <strong>reste</strong> (modulo).</li>
+ <li>Modifier la ligne qui calcule y pour que la boîte prenne une hauteur de 150pixels, mais que 150 ait été calculé en utilisant 3 nombres et les opérateurs <strong>soustraction </strong>et <strong>division</strong>.</li>
+ <li>Modifier la ligne qui calcule x pour que la boîte prenne une largeur de 200pixels, mais que 200 ait été calculé en se servant du nombre 4 et d'un opérateur d'<strong>assignation</strong>.</li>
+ <li>Modifier la ligne qui calcule y pour que la boîte prenne une hauteur de 200 pixels, mais que 200 ait été calculé en utilisant les nombres 50 et 3 ainsi que les opérateurs <strong>multiplication</strong>, <strong>addition </strong>et <strong>assignation</strong>.</li>
+</ul>
+
+<p>Pas d'inquiétude si vous vous trompez. Vous pouvez toujours presser le bouton Reset et les choses fonctionneront à nouveau. Après avoir répondu correctement aux questions posées, amusez‑vous avec ce code ou définissez vous‑même les défis.</p>
+
+<h2 id="Opérateurs_de_comparaison">Opérateurs de comparaison</h2>
+
+<p>Parfois nous avons besoin d'exécuter des tests vrai/faux (true/false), puis d'agir en fonction du résultat — pour ce faire, nous utilisons des <strong>opérateurs de comparaison</strong>.</p>
+
+<table class="standard-table">
+ <thead>
+ <tr>
+ <th scope="col">Operateur</th>
+ <th scope="col">Nom</th>
+ <th scope="col">But</th>
+ <th scope="col">Exemple</th>
+ </tr>
+ <tr>
+ <td><code>===</code></td>
+ <td>Égalité stricte</td>
+ <td>Teste si les valeurs de droite et de gauche sont identiques</td>
+ <td><code>5 === 2 + 4</code></td>
+ </tr>
+ <tr>
+ <td><code>!==</code></td>
+ <td>Non-égalité stricte</td>
+ <td>Teste si les valeurs de doite et de gauche ne sont pas identiques</td>
+ <td><code>5 !== 2 + 3</code></td>
+ </tr>
+ <tr>
+ <td><code>&lt;</code></td>
+ <td>Inférieur à</td>
+ <td>Teste si la valeur de gauche est plus petite que celle de droite.</td>
+ <td><code>10 &lt; 6</code></td>
+ </tr>
+ <tr>
+ <td><code>&gt;</code></td>
+ <td>Supérieur à</td>
+ <td>Teste si la valeur de gauche est plus grande que celle de droite.</td>
+ <td><code>10 &gt; 20</code></td>
+ </tr>
+ <tr>
+ <td>&lt;=</td>
+ <td>Inférieur ou égal à</td>
+ <td>Teste si la valeur de gauche est plus petite ou égale à celle de droite.</td>
+ <td><code>3 &lt;= 2</code></td>
+ </tr>
+ <tr>
+ <td>&gt;=</td>
+ <td>Supérieur ou égal à</td>
+ <td>Teste si la valeur de gauche est supérieure ou égale à celle de droite.</td>
+ <td><code>5 &gt;= 4</code></td>
+ </tr>
+ </thead>
+</table>
+
+<div class="note">
+<p><strong>Note </strong>: Vous verrez peut‑être certaines personnes utiliser <code>==</code> et <code>!=</code> pour leurs test d'égalité ou non-égalité. Ces opérateurs sont valides en JavaScript, mais différents de <code>===</code>/<code>!==</code>. Les versions avec deux caractères testent si les valeurs sont les mêmes, mais pas si les types de données sont les mêmes.  Les versions strictes à trois caractères testent à la fois l'égalité des valeurs <em>et</em> des types de données. Il y a moins d'erreurs avec les versions strictes, donc nous vous engageons à les utiliser dans tous les cas.</p>
+</div>
+
+<p>Si vous entrez certaines de ces valeurs dans une console, vous constaterez que toutes renvoient une valeur <code>true</code>/<code>false</code> — les booléens mentionnés dans l'article précédent. Ces opérateurs sont très utiles car il nous permettent de prendre des décisions dans le code, et ils sont utilisés chaque fois que nous avons besoin de faire un choix. Par exemple, les booléens s'utilisent pour :</p>
+
+<ul>
+ <li>Afficher l'étiquette textuelle ad-hoc sur un bouton selon qu'une fonctionnalité est active ou pas</li>
+ <li>Afficher un message de fin de jeu si un jeu est terminé ou un message de victoire si le jeu a été remporté</li>
+ <li>Afficher des remerciements saisonniers corrects selon la saison de vacances</li>
+ <li>Faire un zoom avant ou arrière sur une carte selon le niveau de zoom choisi</li>
+</ul>
+
+<p>Nous verrons comment coder cette logique quand nous étudierons les directives conditionnelles dans un article ultérieur. Pour le moment, regardons un exemple rapide :</p>
+
+<pre class="brush: html notranslate">&lt;button&gt;Démarrer la machine&lt;/button&gt;
+&lt;p&gt;La machine est arrêtée.&lt;/p&gt;
+</pre>
+
+<pre class="brush: js notranslate">var btn = document.querySelector('button');
+var txt = document.querySelector('p');
+
+btn.addEventListener('click', updateBtn);
+
+function updateBtn() {
+ if (btn.textContent === 'Démarrer la machine') {
+ btn.textContent = 'Arrêter la machine';
+ txt.textContent = 'La machine est en marche !';
+ } else {
+ btn.textContent = 'Démarrer la machine';
+ txt.textContent = 'La machine est arrêtée.';
+ }
+}</pre>
+
+<p>{{EmbedGHLiveSample("learning-area/javascript/introduction-to-js-1/maths/conditional.html", '100%', 100)}}</p>
+
+<p><strong><a href="https://mdn.github.io/learning-area/javascript/introduction-to-js-1/maths/conditional.html">Ouvrir dans une nouvelle fenêtre</a></strong></p>
+
+<p>Vous pouvez voir l'utilisation de l'opérateur d'égalité stricte dans la fonction <code>updateBtn()</code>. Dans ce cas, nous ne testons pas si deux expressions mathématiques ont la même valeur — nous testons si le contenu textuel d'un bouton contient une certaine chaîne — mais c'est toujours le même principe. Si le bouton affiche « Démarrer la machine » quand on le presse, nous changeons son étiquette en « Arrêter la machine » et mettons à jour l'étiquette comme il convient. Si le bouton indique « Arrêter la machine » au moment de le presser, nous basculons l'étiquette à nouveau.</p>
+
+<div class="note">
+<p><strong>Note </strong>: Un contrôle qui alterne entre deux états porte généralement le nom de <strong>toggle</strong> (bascule). Il bascule d'un état l'autre — allumé, éteint, etc.</p>
+</div>
+
+<h2 id="Résumé">Résumé</h2>
+
+<p>Dans cet article, nous avons exposé les informations fondamentales concernant les nombres en JavaScript, à connaître absolument pour débuter convenablement. Vous verrez encore et encore des utilisations de nombres tout au long de cet introduction au JavaScript, prenons donc une pause pour le moment. Si vous êtes de ceux qui n'aiment pas les maths, vous noterez avec satisfaction que ce chapitre était vraiment très court.</p>
+
+<p>Dans l'article suivant, nous étudierons le texte et les façons dont JavaScript nous permet de le manipuler.</p>
+
+<div class="note">
+<p><strong>Note</strong> : Si les Maths vous plaisent et que vous souhaitez en savoir plus sur la manière dont elles sont implémentées en JavaScript, vous trouverez plus de précisions dans la section principale JavaScript du MDN. Une grande place est réservée dans ces articles aux <a href="/en-US/docs/Web/JavaScript/Guide/Numbers_and_dates">Nombres et dates</a> et aux <a href="/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators">Expressions et opérateurs</a>.</p>
+</div>
+
+<p>{{PreviousMenuNext("Learn/JavaScript/First_steps/Variables", "Learn/JavaScript/First_steps/Strings", "Learn/JavaScript/First_steps")}}</p>
diff --git a/files/fr/learn/javascript/first_steps/methode_chaine_utile/index.html b/files/fr/learn/javascript/first_steps/methode_chaine_utile/index.html
new file mode 100644
index 0000000000..d81c3ccb4e
--- /dev/null
+++ b/files/fr/learn/javascript/first_steps/methode_chaine_utile/index.html
@@ -0,0 +1,479 @@
+---
+title: Méthodes utiles pour les chaînes de caractères
+slug: Learn/JavaScript/First_steps/methode_chaine_utile
+tags:
+ - Apprentissage
+ - Article
+ - Codage
+ - Débutant
+ - JavaScript
+ - Longueur
+ - cas
+ - couper
+ - indexof
+ - majuscule
+ - minuscule
+ - remplacer
+translation_of: Learn/JavaScript/First_steps/Useful_string_methods
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/JavaScript/First_steps/Strings", "Learn/JavaScript/First_steps/Arrays", "Learn/JavaScript/First_steps")}}</div>
+
+<p class="summary">À présent que nous avons vu les bases de la manipulation des chaînes de caractères, allons un cran plus loin et commençons à imaginer les opérations utiles que nous pourrions faire sur les chaînes de caractères avec les méthodes intégrées : trouver la longueur d'une chaîne, assembler ou couper des chaînes, substituer un caractère à un autre dans une chaîne, et plus encore.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Prérequis :</th>
+ <td>Vocabulaire courant de l'informatique, bases de HTML et CSS, compréhension de ce que fait JavaScript.</td>
+ </tr>
+ <tr>
+ <th scope="row">Objectif :</th>
+ <td>Comprendre que les chaînes de caractères sont des objets, et apprendre à utiliser certaines méthodes basiques disponibles sur ces objets pour manipuler les chaînes.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Les_chaînes_de_caractères_sont_des_objets">Les chaînes de caractères sont des objets</h2>
+
+<p id="Useful_string_methods">Nous l'avons déjà dit, et nous le redirons — <em>tout</em> est objet en JavaScript. Lorsque vous créez une chaîne, par exemple en utilisant :</p>
+
+<pre class="brush: js">let string = 'Ceci est une chaîne';</pre>
+
+<p>votre variable devient une instance de l'objet <code>String</code>, et par conséquent possède un grand nombre de propriétés et de méthodes associées. Allez sur la page de l'objet {{jsxref("String")}} et regardez la liste sur le côté de la page !</p>
+
+<p><strong>Avant que votre cervelle ne commence à bouillir, pas de panique !</strong> Vous n'avez vraiment pas besoin de connaître la plupart des méthodes de cette liste au début de cet apprentissage. Mais il est probable que vous utiliserez  certaines assez souvent. Nous allons les voir maintenant.</p>
+
+<p>Entrez quelques exemples dans une console vierge. En voici une ci-dessous (vous pouvez aussi <a href="https://mdn.github.io/learning-area/javascript/introduction-to-js-1/variables/index.html">ouvrir cette console</a> dans un onglet ou une fenêtre séparés, ou utiliser la <a href="https://developer.mozilla.org/en-US/docs/Learn/Common_questions/What_are_browser_developer_tools">console de développement du navigateur</a> si vous préférez).</p>
+
+<div class="hidden">
+<h6 id="Hidden_code">Hidden code</h6>
+
+<pre class="brush: html">&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+ &lt;head&gt;
+ &lt;meta charset="utf-8"&gt;
+ &lt;title&gt;JavaScript console&lt;/title&gt;
+ &lt;style&gt;
+ * {
+ box-sizing: border-box;
+ }
+
+ html {
+ background-color: #0C323D;
+ color: #809089;
+ font-family: monospace;
+ }
+
+ body {
+ max-width: 700px;
+ }
+
+ p {
+ margin: 0;
+ width: 1%;
+ padding: 0 1%;
+ font-size: 16px;
+ line-height: 1.5;
+ float: left;
+ }
+
+ .input p {
+ margin-right: 1%;
+ }
+
+ .output p {
+ width: 100%;
+ }
+
+ .input input {
+ width: 96%;
+ float: left;
+ border: none;
+ font-size: 16px;
+ line-height: 1.5;
+ font-family: monospace;
+ padding: 0;
+ background: #0C323D;
+ color: #809089;
+ }
+
+ div {
+ clear: both;
+ }
+
+ &lt;/style&gt;
+ &lt;/head&gt;
+ &lt;body&gt;
+
+
+ &lt;/body&gt;
+
+ &lt;script&gt;
+ var geval = eval;
+ function createInput() {
+ var inputDiv = document.createElement('div');
+ var inputPara = document.createElement('p');
+ var inputForm = document.createElement('input');
+
+ inputDiv.setAttribute('class', 'input');
+ inputPara.textContent = '&gt;';
+ inputDiv.appendChild(inputPara);
+ inputDiv.appendChild(inputForm);
+ document.body.appendChild(inputDiv);
+
+ inputForm.addEventListener('change', executeCode);
+ }
+
+ function executeCode(e) {
+ try {
+ var result = geval(e.target.value);
+ } catch(e) {
+ var result = 'error — ' + e.message;
+ }
+
+ var outputDiv = document.createElement('div');
+ var outputPara = document.createElement('p');
+
+ outputDiv.setAttribute('class','output');
+ outputPara.textContent = 'Result: ' + result;
+ outputDiv.appendChild(outputPara);
+ document.body.appendChild(outputDiv);
+
+ e.target.disabled = true;
+ e.target.parentNode.style.opacity = '0.5';
+
+ createInput()
+ }
+
+ createInput();
+
+ &lt;/script&gt;
+&lt;/html&gt;</pre>
+</div>
+
+<p>{{ EmbedLiveSample('Hidden_code', '100%', 300) }}</p>
+
+<h3 id="Trouver_la_longueur_dune_chaîne">Trouver la longueur d'une chaîne</h3>
+
+<p>C'est facile — il suffit d'utiliser la propriété {{jsxref("String.prototype.length", "length")}}. Entrez ceci :</p>
+
+<pre class="brush: js">let browserType = 'mozilla';
+browserType.length;</pre>
+
+<p>Cette commande doit renvoyer le nombre 7, parce que « mozilla » comporte 7 caractères. C'est utile pour de nombreuses raisons ; par exemple, vous pourriez avoir besoin de trouver les longueurs d'une série de noms pour les afficher par taille ou faire savoir à un utilisateur qu'il a entré un nom trop long dans un champ de formulaire à partir du moment où il dépasse une certaine taille.</p>
+
+<h3 id="Retrouver_un_caractère_donné_dans_une_chaîne">Retrouver un caractère donné dans une chaîne</h3>
+
+<p>Dans le même ordre d'idées, il est possible de faire renvoyer tout caractère d'une chaîne avec <strong>la notation crochets</strong> — c'est-à-dire en ajoutant des crochets (<code>[]</code>) à la fin du nom de la variable. Entre les crochets, mettez le rang du caractère à retrouver ; par exemple, pour retrouver le premier caractère, vous devez  écrire ceci :</p>
+
+<pre class="brush: js">browserType[0];</pre>
+
+<p>Les ordinateurs décomptent à partir de 0, pas de 1 ! Pour retrouver le dernier caractère de <em>n'importe quelle</em> chaîne, on peut utiliser la commande qui suit ; elle combine cette technique avec la propriété <code>length</code>  que nous avons vue plus haut :</p>
+
+<pre class="brush: js">browserType[browserType.length-1];</pre>
+
+<p>La longueur de « mozilla » est de 7 caractères, mais comme le décompte se fait à partir de 0, la position du caractère est 6, d'où la nécessité d'écrire <code>length-1</code>. Vous pourrez utiliser cette propriété pour, par exemple, trouver la première lettre d'une série de chaînes et les trier alphabétiquement.</p>
+
+<h3 id="Trouver_une_sous-chaîne_à_lintérieur_dune_chaîne_et_lextraire">Trouver une sous-chaîne à l'intérieur d'une chaîne et l'extraire</h3>
+
+<ol>
+ <li>Parfois, vous aurez besoin de trouver si une chaîne est présente à l'intérieur d'une autre chaîne plus grande (on dit en général <em>si une sous-chaîne est présente à l'intérieur d'une chaîne</em>). La méthode {{jsxref("String.prototype.indexOf()", "indexOf()")}} permet de le faire ; elle prend un unique ({{glossary("parameter")}}) — la sous-chaîne recherchée. Essayez :
+
+ <pre class="brush: js">browserType.indexOf('zilla');</pre>
+ La commande donne 2 comme résultat, car la sous-chaîne « zilla » commence à la position 2 (0, 1, 2 — donc au troisième caractère) dans « mozilla ». Un tel code s'utilise pour filtrer des chaînes. Par exemple, vous pourriez avoir une liste d'adresses web et ne vouloir afficher que celles qui contiennent « mozilla ».</li>
+</ol>
+
+<ol start="2">
+ <li>On peut faire cela autrement, peut-être plus efficacement encore. Écrivez :
+ <pre class="brush: js">browserType.indexOf('vanilla');</pre>
+ Cela doit vous donner <code>-1</code> comme résultat — renvoyé quand la sous-chaîne, en l'occurence « vanilla », n'est pas trouvée dans la chaîne principale.<br>
+ <br>
+ Vous pouvez utiliser cette propriété pour trouver tous les cas de chaînes <strong>ne</strong> <strong>contenant</strong> <strong>pas</strong> la sous-chaîne « mozilla », ou bien <strong>la contenant</strong>, si vous utilisez l'opérateur négation logique, tel que montré ci-dessous. Vous pourriez faire quelque chose comme :
+
+ <pre class="brush: js">if(browserType.indexOf('mozilla') !== -1) {
+ // faire des tas de choses avec la chaîne
+}</pre>
+ </li>
+ <li>Lorsque vous savez où la sous-chaîne commence à l'intérieur de la chaîne, et savez à quel caractère elle prend fin, vous pouvez utiliser {{jsxref("String.prototype.slice()", "slice()")}} pour l'extraire. Voyez ce code :
+ <pre class="brush: js">browserType.slice(0,3);</pre>
+ Il renvoie « moz » — le premier paramètre est la position du caractère où doit commencer l'extraction, et le second paramètre est la position du caractère se trouvant après le dernier à extraire. Ainsi, l'extraction va de la première position à la dernière, celle-ci non comprise. On peut dire, dans notre cas, que le second paramètre est égal à la longueur de la chaîne retournée.</li>
+ <li>Également, si vous souhaitez extraire tous les caractères après un caractère donné jusqu'à la fin de la chaîne, vous n'avez pas à mettre le second paramètre ! Il suffit d'indiquer la position du caractère à partir duquel vous voulez extraire les caractères restants dans la chaîne. Essayez la commande :
+ <pre class="brush: js">browserType.slice(2);</pre>
+ Elle renvoie « zilla » — le caractère à la position 2 est « z » et comme nous n'avons pas mis de second paramètre, la sous-chaîne retournée comporte tous les caractères restants de la chaîne.</li>
+</ol>
+
+<div class="note">
+<p><strong>Note</strong> : Le second paramètre de <code>slice()</code> est optionnel : s'il n'est pas defini, l'extraction va jusqu'à la fin de la chaîne originale. Il existe aussi d'autres options, allez à la page de {{jsxref("String.prototype.slice()", "slice()")}} pour voir ces autres options.</p>
+</div>
+
+<h3 id="Changer_la_casse">Changer la casse</h3>
+
+<p>Les méthodes {{jsxref("String.prototype.toLowerCase()", "toLowerCase()")}} et {{jsxref("String.prototype.toUpperCase()", "toUpperCase()")}} s'appliquent à une chaîne et en convertissent tous les caractères, respectivement en minuscules ou en majuscules. C'est utile si, par exemple, vous souhaitez normaliser toutes les données entrées par des utilisateurs avant de les stocker dans une base de données.</p>
+
+<p>Essayons d'entrer les lignes suivantes et voyons ce qui se passe :</p>
+
+<pre class="brush: js">let radData = 'My NaMe Is MuD';
+radData.toLowerCase();
+radData.toUpperCase();</pre>
+
+<h3 id="Actualiser_des_parties_de_chaîne">Actualiser des parties de chaîne</h3>
+
+<p>Vous pouvez remplacer une sous-chaîne à l'intérieur d'une chaîne avec une autre sous-chaîne à l'aide de la méthode {{jsxref("String.prototype.replace()", "replace()")}}. Cela fonctionne très simplement au niveau basique, bien qu'il soit possible de faire des choses plus avancées, mais nous ne y attarderons pas maintenant.</p>
+
+<p>La méthode prend deux paramètres — la chaîne que vous voulez remplacer et la chaîne avec laquelle vous voulez la remplacer. Essayez avec cet exemple :</p>
+
+<pre class="brush: js">browserType.replace('moz','van');</pre>
+
+<p>À noter : pour que, dans un programme réel, la variable <code>browserType</code> reflète effectivement la valeur actualisée, il faut assigner à la valeur de la variable le résultat de l'opération ; cette dernière ne met pas à jour automatiquement la valeur de la sous-chaîne. Pour ce faire, il faut écrire :<code> browserType = browserType.replace('moz','van');</code></p>
+
+<h2 id="Apprendre_en_pratiquant">Apprendre en pratiquant</h2>
+
+<p>Dans cette section, vous allez pouvoir vous entraîner à écrire du code de manipulation de chaîne. Dans chacun des exercices ci-dessous, nous avons un tableau de chaînes, une boucle qui traîte chaque valeur dans le tableau et l'affiche dans une liste à puces. Vous n'avez pas besoin de comprendre comment fonctionnent les tableaux ou les boucles dès maintenant — cela vous sera expliqué dans de prochains articles. Tout ce dont vous avez besoin dans chaque cas est d'écrire le code qui va renvoyer les chaînes dans le format souhaité.</p>
+
+<p>Chaque exemple est accompagné d'un bouton « Réinitialiser », que vous pouvez utiliser pour réinitialiser le code si vous faites une erreur et que vous ne parvenez pas à la corriger, et un bouton « Montrer la solution » sur lequel vous pouvez cliquer pour afficher une réponse possible si jamais vous êtes vraiment bloqué.</p>
+
+<h3 id="Filtrer_des_messages_de_vœux">Filtrer des messages de vœux</h3>
+
+<p>Dans ce premier exercice, nous commencerons simplement — nous avons un tableau de carte de voeux, mais nous voulons les trier pour ne lister que les messages concernant Noël. Nous attendons de vous que vous utilisiez un test conditionnel à l'intérieur d'une structure <code>if( ... )</code>, pour tester chaque chaîne et ne l'afficher dans la liste que si elle contient un message concernant Noël.</p>
+
+<ol>
+ <li>Réfléchissez d'abord à comment vérifier que le message concerne Noël. Quelle chaîne est présente dans tous ces messages, et quelle méthode pourriez-vous utiliser pour en tester la présence ?</li>
+ <li>Il vous faudra alors écrire un test conditionnel sous la forme <em>opérande1 opérateur opérande2</em>. La chose à gauche est-elle égale à la chose à droite ? Ou dans notre cas, l'appel de méthode de gauche renvoie-t-il le résultat de droite ?</li>
+ <li>Conseil : dans notre cas, il est probablement plus utile de tester si le résultat de l'appel de notre méthode <em>n'est pas égal</em> à un certain résultat.</li>
+</ol>
+
+<div class="hidden">
+<h6 id="Playable_code">Playable code</h6>
+
+<pre class="brush: html">&lt;div class="output" style="min-height: 125px;"&gt;
+
+&lt;ul&gt;
+
+&lt;/ul&gt;
+
+&lt;/div&gt;
+
+&lt;textarea id="code" class="playable-code" style="height: 290px;"&gt;
+var list = document.querySelector('.output ul');
+list.innerHTML = '';
+var greetings = ['Happy Birthday!',
+ 'Merry Christmas my love',
+ 'A happy Christmas to all the family',
+ 'You\'re all I want for Christmas',
+ 'Get well soon'];
+
+for (var i = 0; i &lt; greetings.length; i++) {
+ var input = greetings[i];
+ // Your conditional test needs to go inside the parentheses
+ // in the line below, replacing what's currently there
+ if (greetings[i]) {
+ var result = input;
+ var listItem = document.createElement('li');
+ listItem.textContent = result;
+ list.appendChild(listItem);
+ }
+}
+&lt;/textarea&gt;
+
+&lt;div class="playable-buttons"&gt;
+ &lt;input id="reset" type="button" value="Reset"&gt;
+ &lt;input id="solution" type="button" value="Show solution"&gt;
+&lt;/div&gt;
+</pre>
+
+<pre class="brush: js">var textarea = document.getElementById('code');
+var reset = document.getElementById('reset');
+var solution = document.getElementById('solution');
+var code = textarea.value;
+
+function updateCode() {
+ eval(textarea.value);
+}
+
+reset.addEventListener('click', function() {
+ textarea.value = code;
+ updateCode();
+});
+
+solution.addEventListener('click', function() {
+ textarea.value = jsSolution;
+ updateCode();
+});
+
+var jsSolution = 'var list = document.querySelector(\'.output ul\');\nlist.innerHTML = \'\';\nvar greetings = [\'Happy Birthday!\',\n \'Merry Christmas my love\',\n \'A happy Christmas to all the family\',\n \'You\\\'re all I want for Christmas\',\n \'Get well soon\'];\n\nfor(var i = 0; i &lt; greetings.length; i++) {\n var input = greetings[i];\n if(greetings[i].indexOf(\'Christmas\') !== -1) {\n var result = input;\n var listItem = document.createElement(\'li\');\n listItem.textContent = result;\n list.appendChild(listItem);\n }\n}';
+
+textarea.addEventListener('input', updateCode);
+window.addEventListener('load', updateCode);
+</pre>
+</div>
+
+<p>{{ EmbedLiveSample('Playable_code', '100%', 490) }}</p>
+
+<h3 id="Remettre_les_majuscules">Remettre les majuscules</h3>
+
+<p>Dans cet exercice, nous avons des noms des villes du Royaume-Uni, mais les majuscules ne sont pas au bon endroit. Nous souhaitons modifier les noms pour qu'ils soient en minuscules à l'exception de la première lettre qui doit être une majuscule. Une bonne manière de faire ceci :</p>
+
+<ol>
+ <li>Convertissez la totalité de la chaîne contenue dans la variable <code>input</code> en minuscules et stockez-la dans une nouvelle variable.</li>
+ <li>Récupérez la première lettre de la chaîne dans cette nouvelle variable et stockez-la dans une autre variable.</li>
+ <li>En utilisant la dernière variable comme une sous-chaîne, remplacez la première lettre de la chaîne en minuscules par la première lettre de la chaîne en minuscules transformé en majuscules. Stockez le résultat de cette procédure de remplacement dans une autre nouvelle variable.</li>
+ <li>Changez la valeur de la variable <code>result</code> afin qu'elle soit égale au résultat final plutôt qu'à <code>input</code>.</li>
+</ol>
+
+<div class="note">
+<p><strong>Note</strong>: Un conseil — les paramètres des méthodes de chaîne n'ont pas besoin d'être des chaînes, elle peuvent aussi être des variables, ou même des variables avec une méthode invoquée sur elles.</p>
+</div>
+
+<div class="hidden">
+<h6 id="Playable_code_2">Playable code 2</h6>
+
+<pre class="brush: html">&lt;div class="output" style="min-height: 125px;"&gt;
+
+&lt;ul&gt;
+
+&lt;/ul&gt;
+
+&lt;/div&gt;
+
+&lt;textarea id="code" class="playable-code" style="height: 250px;"&gt;
+var list = document.querySelector('.output ul');
+list.innerHTML = '';
+var cities = ['lonDon', 'ManCHESTer', 'BiRmiNGHAM', 'liVERpoOL'];
+for(var i = 0; i &lt; cities.length; i++) {
+ var input = cities[i];
+ // write your code just below here
+
+ var result = input;
+ var listItem = document.createElement('li');
+ listItem.textContent = result;
+ list.appendChild(listItem);
+}
+&lt;/textarea&gt;
+
+&lt;div class="playable-buttons"&gt;
+ &lt;input id="reset" type="button" value="Reset"&gt;
+ &lt;input id="solution" type="button" value="Show solution"&gt;
+&lt;/div&gt;
+</pre>
+
+<pre class="brush: js">var textarea = document.getElementById('code');
+var reset = document.getElementById('reset');
+var solution = document.getElementById('solution');
+var code = textarea.value;
+
+function updateCode() {
+ eval(textarea.value);
+}
+
+reset.addEventListener('click', function() {
+ textarea.value = code;
+ updateCode();
+});
+
+solution.addEventListener('click', function() {
+ textarea.value = jsSolution;
+ updateCode();
+});
+
+var jsSolution = 'var list = document.querySelector(\'.output ul\');\nlist.innerHTML = \'\';\nvar cities = [\'lonDon\', \'ManCHESTer\', \'BiRmiNGHAM\', \'liVERpoOL\'];\n\nfor(var i = 0; i &lt; cities.length; i++) {\n var input = cities[i];\n var lower = input.toLowerCase();\n var firstLetter = lower.slice(0,1);\n var capitalized = lower.replace(firstLetter,firstLetter.toUpperCase());\n var result = capitalized;\n var listItem = document.createElement(\'li\');\n listItem.textContent = result;\n list.appendChild(listItem);\n\n}';
+
+textarea.addEventListener('input', updateCode);
+window.addEventListener('load', updateCode);
+</pre>
+</div>
+
+<p>{{ EmbedLiveSample('Playable_code_2', '100%', 450) }}</p>
+
+<h3 id="Créer_de_nouvelles_chaînes_à_partir_de_morceaux">Créer de nouvelles chaînes à partir de morceaux</h3>
+
+<p>Dans ce dernier exercice, le tableau contient un lot de chaînes contenant des informations à propos d'arrêts de train dans le nord de l'Angleterre. Les chaînes sont des éléments de données contenant le code en trois lettres de l'arrêt, suivi par des données lisibles par machine, suivi par un point-virgule, et enfin le nom de la station lisible par un humain. Par exemple :</p>
+
+<pre>MAN675847583748sjt567654;Manchester Piccadilly</pre>
+
+<p>Nous voulons extraire le code de la station et son nom, et les associer dans une chaîne avec la structure suivante :</p>
+
+<pre>MAN: Manchester Piccadilly</pre>
+
+<p>Nous vous recommandons de procéder de la manière suivante :</p>
+
+<ol>
+ <li>Extraire le code de trois lettres de la station et le stocker dans une nouvelle variable.</li>
+ <li>Trouver la position du caractère point-virgule.</li>
+ <li>Extraire le nom de la station lisible par un humain en utilisant la position du caractère point virgule comme référence, et le stocker dans une nouvelle variable.</li>
+ <li>Concaténer les deux nouvelles variables et une chaîne pour fabriquer la chaîne finale.</li>
+ <li>Changer la valeur de la variable <code>result</code> pour qu'elle soit égale à la chaîne finale, plutôt qu'à <code>input</code>.</li>
+</ol>
+
+<div class="hidden">
+<h6 id="Playable_code_3">Playable code 3</h6>
+
+<pre class="brush: html">&lt;div class="output" style="min-height: 125px;"&gt;
+
+&lt;ul&gt;
+
+&lt;/ul&gt;
+
+&lt;/div&gt;
+
+&lt;textarea id="code" class="playable-code" style="height: 285px;"&gt;
+var list = document.querySelector('.output ul');
+list.innerHTML = '';
+var stations = ['MAN675847583748sjt567654;Manchester Piccadilly',
+ 'GNF576746573fhdg4737dh4;Greenfield',
+ 'LIV5hg65hd737456236dch46dg4;Liverpool Lime Street',
+ 'SYB4f65hf75f736463;Stalybridge',
+ 'HUD5767ghtyfyr4536dh45dg45dg3;Huddersfield'];
+
+for (var i = 0; i &lt; stations.length; i++) {
+ var input = stations[i];
+ // write your code just below here
+
+ var result = input;
+ var listItem = document.createElement('li');
+ listItem.textContent = result;
+ list.appendChild(listItem);
+}
+&lt;/textarea&gt;
+
+&lt;div class="playable-buttons"&gt;
+ &lt;input id="reset" type="button" value="Reset"&gt;
+ &lt;input id="solution" type="button" value="Show solution"&gt;
+&lt;/div&gt;
+</pre>
+
+<pre class="brush: js">var textarea = document.getElementById('code');
+var reset = document.getElementById('reset');
+var solution = document.getElementById('solution');
+var code = textarea.value;
+
+function updateCode() {
+ eval(textarea.value);
+}
+
+reset.addEventListener('click', function() {
+ textarea.value = code;
+ updateCode();
+});
+
+solution.addEventListener('click', function() {
+ textarea.value = jsSolution;
+ updateCode();
+});
+
+var jsSolution = 'var list = document.querySelector(\'.output ul\');\nlist.innerHTML = \'\';\nvar stations = [\'MAN675847583748sjt567654;Manchester Piccadilly\',\n \'GNF576746573fhdg4737dh4;Greenfield\',\n \'LIV5hg65hd737456236dch46dg4;Liverpool Lime Street\',\n \'SYB4f65hf75f736463;Stalybridge\',\n \'HUD5767ghtyfyr4536dh45dg45dg3;Huddersfield\'];\n\nfor(var i = 0; i &lt; stations.length; i++) {\n var input = stations[i];\n var code = input.slice(0,3);\n var semiC = input.indexOf(\';\');\n var name = input.slice(semiC + 1);\n var result = code + \': \' + name;\n var listItem = document.createElement(\'li\');\n listItem.textContent = result;\n list.appendChild(listItem);\n}';
+
+
+textarea.addEventListener('input', updateCode);
+window.addEventListener('load', updateCode);
+</pre>
+</div>
+
+<p>{{ EmbedLiveSample('Playable_code_3', '100%', 485) }}</p>
+
+<h2 id="Conclusion">Conclusion</h2>
+
+<p>Il n'est pas possible d'éluder le fait qu'il est très important de savoir manipuler des mots et des phrases lorsqu'on programme — tout particulièrement en JavaScript, dans la mesure où les sites web servent à la communication entre les personnes. Cet article vous a indiqué, pour l'instant, les bases à connaître pour manipuler les chaînes. Ce sera utile lorsque vous aborderez des sujets plus complexes à l'avenir. Pour suivre, nous allons nous intéresser au dernier grand type de données sur lequel nous devons nous concentrer à court terme — les tableaux.</p>
+
+<p>{{PreviousMenuNext("Learn/JavaScript/First_steps/Strings", "Learn/JavaScript/First_steps/Arrays", "Learn/JavaScript/First_steps")}}</p>
diff --git a/files/fr/learn/javascript/first_steps/silly_story_generator/index.html b/files/fr/learn/javascript/first_steps/silly_story_generator/index.html
new file mode 100644
index 0000000000..b2eae8fff5
--- /dev/null
+++ b/files/fr/learn/javascript/first_steps/silly_story_generator/index.html
@@ -0,0 +1,143 @@
+---
+title: Générateur d'histoires absurdes
+slug: Learn/JavaScript/First_steps/Silly_story_generator
+translation_of: Learn/JavaScript/First_steps/Silly_story_generator
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenu("Learn/JavaScript/First_steps/Arrays", "Learn/JavaScript/First_steps")}}</div>
+
+<p class="summary">Dans cette évaluation, vous aurez pour tâche d'utiliser les connaissances que vous avez apprises dans les articles de ce module et de les appliquer dans le but de créer une appli ludique qui génère des histoires absurdes au hasard. Amusez-vous bien !</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Prérequis :</th>
+ <td>
+ <p>Avant de vous lancer dans cette évaluation, vous devez avoir déjà travaillé sur tous les articles de ce module.</p>
+ </td>
+ </tr>
+ <tr>
+ <th scope="row">Objectif :</th>
+ <td>
+ <p>Tester la compréhension des fondamentaux JavaScript tels que les variables, les nombres, les opérateurs, les chaînes de caractères et les tableaux.</p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Point_de_départ">Point de départ</h2>
+
+<p>Pour commencer cette évaluation :</p>
+
+<ul>
+ <li>Allez <a href="https://github.com/mdn/learning-area/blob/master/javascript/introduction-to-js-1/assessment-start/index.html">chercher le fichier HTML</a> d'exemple et enregistrez-en une copie locale sous le nom <code>index.html</code> dans un nouveau dossier quelque part sur votre ordinateur. Ce fichier contient également la CSS pour mettre en forme l'exemple qui l'accompagne.</li>
+ <li>Allez sur la <a href="https://github.com/mdn/learning-area/blob/master/javascript/introduction-to-js-1/assessment-start/raw-text.txt">page qui contient le texte brut</a> et gardez la fenêtre ouverte dans un onglet différent de votre navigateur. Vous en aurez besoin plus tard.</li>
+</ul>
+
+<div class="note">
+<p><strong>Note</strong>: Vous pouvez aussi utiliser un site tel que que <a class="external external-icon" href="http://jsbin.com/">JSBin</a> ou <a class="external external-icon" href="https://thimble.mozilla.org/">Thimble</a> pour votre évaluation. Vous pouvez copier-coller le HTML, CSS et JavaScript vers l'un de ces éditeurs en ligne. Si l'éditeur en ligne que vous utilisez ne propose pas d'onglet JavaScript séparé, n'hésitez pas à en intégrer un dans une balise <code>&lt;script&gt;</code> au sein de la page HTML.</p>
+</div>
+
+<h2 id="Résumé_du_projet">Résumé du projet</h2>
+
+<p>On vous a fourni du code HTML/CSS brut ainsi que quelques chaînes de caractères et fonctions JavaScript : vous devez écrire le code JavaScript nécessaire pour transformer ces éléments en un programme fonctionnel, qui fera les choses suivantes :</p>
+
+<ul>
+ <li>Générer une histoire absurde quand on appuie sur le bouton "Generate random story" (Générer une histoire au hasard).</li>
+ <li>Remplacer dans l'histoire le nom par défaut "Bob" par un nom personnalisé, dans le cas où le champ "Enter custom name" (Entrer un nom personnalisé) a été complété avant que le bouton "Générer" soit déclenché.</li>
+ <li>Convertir les unités de poids et de température par défaut (américaines) vers leurs équivalents britanniques si le boutton "radio UK" a été coché avant que le bouton "Générer" soit déclenché.</li>
+ <li>Générer une nouvelle histoire absurde au hasard quand on appuie à nouveau sur le bouton (et encore une, et encore une...)</li>
+</ul>
+
+<p>Les captures d'écran suivantes montrent un exemple de ce que le programme terminé doit afficher :</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/13667/assessment-1.png" style="border-style: solid; border-width: 1px; display: block; margin: 0px auto;"></p>
+
+<p>Pour vous faire une idée un peu plus précise, <a href="http://mdn.github.io/learning-area/javascript/introduction-to-js-1/assessment-finished/">jetez un œil à l'exemple terminé</a> (mais sans regarder le code source !)</p>
+
+<h2 id="Les_étapes">Les étapes</h2>
+
+<p>Les sections suivantes décrivent ce que vous devez faire :</p>
+
+<p>Installation basique :</p>
+
+<ol>
+ <li>Créez un nouveau fichier nommé <code>main.js</code>, dans le même dossier que <code>index.html</code> file.</li>
+ <li>Appliquez le fichier JavaScript externe à votre code HTML en insérant une balise {{htmlelement("script")}} dans votre code HTML en référençant <code>main.js</code>. Mettez-la juste avant de refermer la balise <code>&lt;/body&gt;</code>.</li>
+</ol>
+
+<p>Variables initiales et fonctions :</p>
+
+<ol>
+ <li>Dans le fichier de texte brut, copiez tout le code présent sous le titre "1. COMPLETE VARIABLE AND FUNCTION DEFINITIONS" et collez-le en haut du fichier <code>main</code>. Cela vous donne trois variables qui stockent les références respectivement vers le champ "Enter custom name", vers le bouton "Generate random story" (<code>randomize</code>), et vers la balise {{htmlelement("p")}} en bas du corps HTML dans lequel l'histoire sera copiée (<code>story</code>). Par ailleurs, vous avez une fonction appelée <code>randomValueFromArray() </code>qui prend une table, et qui renvoie au hasard l'un des éléments qu'elle contient.</li>
+ <li>Maintenant regardons la deuxième section du fichier de texte brut : "2. RAW TEXT STRINGS". Cette section contient des chaînes de caractères qui vont se comporter comme des entrées (<em>input</em>) dans notre program. L'idée est que vous intégriez ces variables internes dans <code>main.js</code>:
+ <ol>
+ <li>Stockez la première longue chaîne de caractères (string) dans la variable <code>storyText</code>.</li>
+ <li>Stockez le premier groupe de trois strings dans le tableau <code>insertX</code>.</li>
+ <li>Stockez le deuxième groupe de trois strings dans le tableau <code>insertY</code>.</li>
+ <li>Stockez le troisième groupe de trois strings dans une tableau <code>insertZ</code>.</li>
+ </ol>
+ </li>
+</ol>
+
+<p>Mettre en place le gestionnaire d'événements (<em>event handler</em>) et le squelette de la fonction :</p>
+
+<ol>
+ <li>Retournez au fichier de texte brut.</li>
+ <li>Copiez le code qui se trouve sous le titre "3. EVENT LISTENER AND PARTIAL FUNCTION DEFINITION" et collez-le en bas de votre fichier <code>main.js</code> principal. Cela :
+ <ul>
+ <li>Ajoute un gestionnaire d'événements pour les clics à la variable <code>randomize</code> de telle sorte que quand on clique sur le bouton associé, la fonction <code>result()</code> se lance.</li>
+ <li>Ajoute une définition partiellement complète de la fonction <code>result()</code> à votre code. Pour le reste de l'évaluation, vous compléterez des lignes au sein de cette fonction pour la compléter et la faire fonctionner correctement.</li>
+ </ul>
+ </li>
+</ol>
+
+<p>Compléter la fonction <code>result()</code> :</p>
+
+<ol>
+ <li>Créer une nouvelle variable nommée <code>newStory</code>, et fixer sa valeur pour qu'elle soit égale à <code>storyText</code>. C'est nécessaire pour que soit créée une nouvelle histoire au hasard à chaque fois qu'on appuiera sur le bouton "Generate" et que la fonction sera lancée. Si on apportait des modifications directement à <code>storyText</code>, on ne pourrait générer une nouvelle histoire qu'une seule fois.</li>
+ <li>Créer trois nouvelles variables nommées <code>xItem</code>, <code>yItem</code>, et <code>zItem</code>, et faites en sorte qu'elles soient égales au résultat de l'appel de <code>randomValueFromArray()</code> sur vos trois tables (le résultat dans chaque cas fera apparaître un élément au hasard en provenance de chacune des tables appelées). Par exemple, vous pouvez appeler la fonction et lui faire retourner une chaîne de caractères au hasard depuis <code>insertX</code> en écrivant <code>randomValueFromArray(insertX)</code>.</li>
+ <li>Ensuite nous allons remplacer les trois fichiers temporaires dans la chaîne <code>newStory</code> — <code>:insertx:</code>, <code>:inserty:</code>, et <code>:insertz:</code> — par les chaînes stockées dans <code>xItem</code>, <code>yItem</code>, and <code>zItem</code>. Ici, une méthode particulière de chaînes pourra vous aider : dans chaque cas, faites que l'appel à la méthode soit égal à <code>newStory</code>, de sorte qu'à chaque appel, <code>newStory</code> est égal à lui-même, mais avec les substitutions effectuées. Ainsi, à chaque fois qu'on appuiera sur le bouton, ces fichiers temporaires seront chacun remplacés par une chaîne de caractères absurdes au hasard. Pour information, la méthode en question remplace seulement la première séquence de sous-chaîne qu'elle trouve, donc vous devrez peut-être l'un des appels deux fois.</li>
+ <li>Dans le premier block <code>if</code>, ajoutez une autre méthode de remplacement de chaîne pour remplacer le nom 'Bob' que vous trouverez dans la chaîne <code>newStory</code> en tant que variable <code>name</code>. Dans ce block, on établit que "Si une valeur a été entrée dans le champ <code>customName</code> text input, on remplacera dans l'histoire le mot Bob par ce nom personnalisé".</li>
+ <li>Dans le deuxième block <code>if</code>, on vérifie que le bouton radio <code>uk</code> a été coché. Si c'est le cas, nous voulons convertir les valeurs de poids et de température de l'histoire. Les pounds et les farenheit deviennent des stones et des centigrades. Procédez comme suit :
+ <ol>
+ <li>Cherchez la formule pour convertir les pounds en stones et les fareinheit en centigrades.</li>
+ <li>Dans la ligne qui définit la variable <code>weight</code> (poids), remplacez 300 par un calcul qui convertit 300 pounds en stones. Le tout englobé dans un <code>Math.round()</code> à la fin duquel vous concatenez <code>'stone'</code>.</li>
+ <li>Dans la ligne qui définit la variable <code>temperature</code>, remplacez 94 par un calcul qui convertit 94 fahrenheit en centigrades. Le tout englobé dans un <code>Math.round()</code> à la fin duquel vous concatenez<code> 'centigrade'</code>.</li>
+ <li>Juste sous la définition des deux variables, ajoutez deux lignes de remplacement de chaînes supplémentaires qui remplacent '94 farhenheit' par les contenus de la variable <code>temperature</code>, et '300 pounds' par les contenus de la variable <code>weight</code>.</li>
+ </ol>
+ </li>
+ <li>Enfin, dans l'antépénultième ligne de la fonction, faites en sorte que la propriété <code>textContent</code> de la variable <code>story</code> (qui référence le paragraphe) soit égale à <code>newStory</code>.</li>
+</ol>
+
+<h2 id="Trucs_et_astuces">Trucs et astuces</h2>
+
+<ul>
+ <li>Aucun besoin de modifier le code HTML, à part pour lui appliquer le JavaScript.</li>
+ <li>Si vous n'êtes pas sûr que le JavaScript est correctement appliqué à votre HTML, essayez de supprimer temporairement tout le contenu du fichier JavaScript, et d'y ajouter un morceau très simple de code JavaScript dont vous savez qu'il aura un effet visible, puis sauvegardez et rafraîchissez. Par exemple, le morceau de code suivant fait que l'arrière plan de la balise {{htmlelement("html")}} devient rouge — donc toute la fenêtre du navigateur devrait devenir rouge si le JavaScript est correctement appliqué :</li>
+ <li>
+ <pre class="brush: js">document.querySelector('html').style.backgroundColor = 'red';</pre>
+ </li>
+ <li><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/round">Math.round()</a> est une méthode JavaScript intégrée qui arrondit simplement le résultat d'un calcul à l'entier le plus proche.</li>
+</ul>
+
+<h2 id="Évaluation">Évaluation</h2>
+
+<p>Si vous suivez cette évaluation dans le cadre d'un cours organisé, vous devriez pouvoir soumettre votre travail à votre enseignant/encadrant pour être évalué. Si vous êtes autodidacte, vous pouvez facilement obtenir le guide de notation en vous adressant à la mailing list <a href="https://lists.mozilla.org/listinfo/dev-mdc">dev-mdc</a> ou au canal IRC <a href="irc://irc.mozilla.org/mdn">#mdn</a> sur <a href="https://wiki.mozilla.org/IRC">Mozilla IRC</a>. Essayez de faire l'exercice d'abord — vous ne gagnez rien à tricher !</p>
+
+<p>{{PreviousMenu("Learn/JavaScript/First_steps/Arrays", "Learn/JavaScript/First_steps")}}</p>
+
+<h2 id="Dans_ce_module">Dans ce module</h2>
+
+<ul>
+ <li><a href="https://wiki.developer.mozilla.org/en-US/docs/Learn/JavaScript/First_steps/What_is_JavaScript">What is JavaScript?</a></li>
+ <li><a href="https://wiki.developer.mozilla.org/en-US/docs/Learn/JavaScript/First_steps/A_first_splash">A first splash into JavaScript</a></li>
+ <li><a href="https://wiki.developer.mozilla.org/en-US/docs/Learn/JavaScript/First_steps/What_went_wrong">What went wrong? Troubleshooting JavaScript</a></li>
+ <li><a href="https://wiki.developer.mozilla.org/en-US/docs/Learn/JavaScript/First_steps/Variables">Storing the information you need — Variables</a></li>
+ <li><a href="https://wiki.developer.mozilla.org/en-US/docs/Learn/JavaScript/First_steps/Math">Basic math in JavaScript — numbers and operators</a></li>
+ <li><a href="https://wiki.developer.mozilla.org/en-US/docs/Learn/JavaScript/First_steps/Strings">Handling text — strings in JavaScript</a></li>
+ <li><a href="https://wiki.developer.mozilla.org/en-US/docs/Learn/JavaScript/First_steps/Useful_string_methods">Useful string methods</a></li>
+ <li><a href="https://wiki.developer.mozilla.org/en-US/docs/Learn/JavaScript/First_steps/Arrays">Arrays</a></li>
+ <li><a href="https://wiki.developer.mozilla.org/en-US/docs/Learn/JavaScript/First_steps/Silly_story_generator">Assessment: Silly story generator</a></li>
+</ul>
diff --git a/files/fr/learn/javascript/first_steps/strings/index.html b/files/fr/learn/javascript/first_steps/strings/index.html
new file mode 100644
index 0000000000..16cf1c51ce
--- /dev/null
+++ b/files/fr/learn/javascript/first_steps/strings/index.html
@@ -0,0 +1,278 @@
+---
+title: Gérer du texte — les chaînes de caractères en JavaScript
+slug: Learn/JavaScript/First_steps/Strings
+tags:
+ - Article
+ - Attacher
+ - Codage
+ - Débutant
+ - Guide
+ - Guillemets
+ - JavaScript
+ - chaînes
+ - concatenation
+translation_of: Learn/JavaScript/First_steps/Strings
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/JavaScript/First_steps/Math", "Learn/JavaScript/First_steps/Useful_string_methods", "Learn/JavaScript/First_steps")}}</div>
+
+<p class="summary">Concentrons-nous maintenant sur les chaînes de caractères - c'est le nom donné à un segment de texte en programmation. Dans cet article, nous aborderons les aspects les plus communs des chaînes de caractères que vous devez vraiment connaître quand vous apprenez JavaScript, comme créer une chaîne de caractères, échapper des guillemets dans une chaîne ou encore concaténer des chaînes.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Prérequis :</th>
+ <td>Connaissance de base en informatique, une compréhension basique de HTML et CSS et savoir ce qu'est JavaScript.</td>
+ </tr>
+ <tr>
+ <th scope="row">Objectif :</th>
+ <td>Devenir familier avec les fondamentaux pour manipuler les chaînes de caractères en JavaScript.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Le_pouvoir_des_mots">Le pouvoir des mots</h2>
+
+<p>Les mots ont beaucoup d'importance pour les humains — ils occupent une large part dans nos façons de communiquer. Comme le Web est un medium essentiellement fondé sur du texte conçu pour permettre aux hommes de communiquer et partager de l'information, il est utile de contrôler les mots qui y sont publiés. {{glossary("HTML")}} donne structure et sens au texte, {{glossary("CSS")}} en gère le style et JavaScript comporte une série de fonctionnalités pour manipuler les chaînes de caractères, créer des messages d'accueil personnalisés, afficher la bonne étiquette quand nécessaire, trier des termes dans l'ordre voulu, et bien d'autres choses encore.</p>
+
+<p>À peu près tous les programmes que nous vous avons montrés jusqu'ici ont impliqué des manipulations de chaînes de caractères.</p>
+
+<h2 id="Chaînes_de_caractères_—_les_bases">Chaînes de caractères — les bases</h2>
+
+<p>À première vue, les chaînes se traitent de la même manière que les nombres ; mais si vous approfondissez la chose, vous commencerez à percevoir des différences notables. Entrons sur la console quelques lignes simples pour nous familiariser avec la chose. À propos de la console, nous en avons placé une ci‑dessous (vous pouvez  <a href="https://mdn.github.io/learning-area/javascript/introduction-to-js-1/variables/index.html">l'ouvrir</a> dans un onglet ou une fenêtre séparée, ou bien utiliser celle de <a href="/en-US/docs/Learn/Common_questions/What_are_browser_developer_tools">l'explorateur, </a>comme vous préférez).</p>
+
+<div class="hidden">
+<h6 id="Hidden_code">Hidden code</h6>
+
+<pre class="brush: html">&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+ &lt;head&gt;
+ &lt;meta charset="utf-8"&gt;
+ &lt;title&gt;JavaScript console&lt;/title&gt;
+ &lt;style&gt;
+ * {
+ box-sizing: border-box;
+ }
+
+ html {
+ background-color: #0C323D;
+ color: #809089;
+ font-family: monospace;
+ }
+
+ body {
+ max-width: 700px;
+ }
+
+ p {
+ margin: 0;
+ width: 1%;
+ padding: 0 1%;
+ font-size: 16px;
+ line-height: 1.5;
+ float: left;
+ }
+
+ .input p {
+ margin-right: 1%;
+ }
+
+ .output p {
+ width: 100%;
+ }
+
+ .input input {
+ width: 96%;
+ float: left;
+ border: none;
+ font-size: 16px;
+ line-height: 1.5;
+ font-family: monospace;
+ padding: 0;
+ background: #0C323D;
+ color: #809089;
+ }
+
+ div {
+ clear: both;
+ }
+
+ &lt;/style&gt;
+ &lt;/head&gt;
+ &lt;body&gt;
+
+
+ &lt;/body&gt;
+
+ &lt;script&gt;
+ let geval = eval;
+ function createInput() {
+ let inputDiv = document.createElement('div');
+ let inputPara = document.createElement('p');
+ let inputForm = document.createElement('input');
+
+ inputDiv.setAttribute('class','input');
+ inputPara.textContent = '&gt;';
+ inputDiv.appendChild(inputPara);
+ inputDiv.appendChild(inputForm);
+ document.body.appendChild(inputDiv);
+
+ if(document.querySelectorAll('div').length &gt; 1) {
+        inputForm.focus();
+      }
+
+ inputForm.addEventListener('change', executeCode);
+ }
+
+ function executeCode(e) {
+ try {
+ let result = geval(e.target.value);
+ } catch(e) {
+ let result = 'error — ' + e.message;
+ }
+
+ let outputDiv = document.createElement('div');
+ let outputPara = document.createElement('p');
+
+ outputDiv.setAttribute('class','output');
+ outputPara.textContent = 'Result: ' + result;
+ outputDiv.appendChild(outputPara);
+ document.body.appendChild(outputDiv);
+
+ e.target.disabled = true;
+ e.target.parentNode.style.opacity = '0.5';
+
+ createInput()
+ }
+
+ createInput();
+
+ &lt;/script&gt;
+&lt;/html&gt;</pre>
+</div>
+
+<p>{{ EmbedLiveSample('Hidden_code', '100%', 300) }}</p>
+
+<h3 id="Créer_une_chaîne_de_texte">Créer une chaîne de texte</h3>
+
+<ol>
+ <li>Pour débuter, entrez les lignes suivantes :
+ <pre class="brush: js">let string = 'La révolution ne sera pas télévisée.';
+string;</pre>
+ Comme nous l'avons fait avec les nombres, nous déclarons une variable, l'initialisons avec une valeur de chaîne, puis renvoyons la valeur. La seule différence ici est que lorsque nous écrivons une chaîne, nous la mettons entre guillemets.</li>
+ <li>Si vous ne le faites pas, ou si vous oubliez un des guillemets, vous déclenchez une erreur. Essayez d'entrer une de ces lignes :
+ <pre class="brush: js example-bad">let badString = Voici un test;
+let badString = 'Voici un test;
+let badString = Voici un test';</pre>
+ Ces lignes de code ne fonctionnent pas parce que toute chaîne de texte qui n'est pas écrite entre guillemets est considérée comme un nom de variable, un nom de propriété, un mot réservé ou quelque chose de semblable. Quand l'interpréteur ne parvient pas à trouver la déclaration de ladite variable, une erreur est déclenchée (par ex. « missing ; before statement »). Si l'interpréteur voit le début d'une chaîne  mais ne trouve pas sa fin, comme dans la ligne 2, il se plaint en émettant une erreur (avec « <em>unterminated string literal</em> »). Si votre programme produit de telles erreurs, revoyez‑le et vérifiez qu'aucun guillemet ne manque.</li>
+ <li>L'assertion suivante fonctionne si la variable <code>string</code> a été préalablement définie — essayez maintenant :
+ <pre class="brush: js">let badString = string;
+badString;</pre>
+ <code>badString</code> est maintenant défini avec la même valeur que <code>string</code>.</li>
+</ol>
+
+<h3 id="Guillemets_simples_vs_guillemets_doubles">Guillemets simples vs guillemets doubles</h3>
+
+<ol>
+ <li>En JavaScript, vous pouvez envelopper vos chaînes entre des guillemets simples ou doubles. Les deux expressions suivantes sont correctes :
+ <pre class="brush: js">let sgl = 'Guillemet simple.';
+let dbl = "Guillemets doubles.";
+sgl;
+dbl;</pre>
+ </li>
+ <li>Il y a une toute petite différence entre les deux, et celle que vous retenez relève de la préférence personnelle. Prenez-en une, et tenez‑vous y toutefois : du code avec des mises entre guillemets diversifiées peut amener des confusions, en particulier si vous utilisez les deux sortes dans la même chaîne ! Ce qui suit renvoie une erreur :
+ <pre class="brush: js example-bad">let badQuotes = 'Quoi sur Terre ?";</pre>
+ </li>
+ <li>L'interpréteur pensera que la chaîne n'a pas été fermée, car le type de guillemet autre ne servant pas à délimiter les chaînes peut y être employé. Par exemple, ces deux assertions sont valables :
+ <pre class="brush: js">let sglDbl = 'Mangeriez‑vous un "souper de poisson"?';
+let dblSgl = "J'ai le blues.";
+sglDbl;
+dblSgl;</pre>
+ </li>
+ <li>Bien entendu, vous ne pouvez pas inclure dans la chaîne le même type de guillemet que celui qui est utilisé pour la délimiter. Ce qui suit conduit à une erreur, car l'explorateur ne peut pas déterminer là où se termine la chaîne :
+ <pre class="brush: js example-bad">let bigmouth = 'Je n'ai pas eu droit à prendre place...';</pre>
+ Voilà qui nous amène naturellement au prochain sujet.</li>
+</ol>
+
+<h3 id="Échappement_de_caractères_dans_une_chaîne">Échappement de caractères dans une chaîne</h3>
+
+<p>Pour corriger l'erreur dans notre ligne de code précédente, il nous suffit d'échapper au problème que pose le guillemet. « Échapper des caractères » signifie que nous les marquons de manière à ce qu'ils soient reconnus comme partie intégrante du texte, et non pas comme symbole de code. Dans JavaScript, nous le faisons en mettant une barre oblique inverse juste avant le caractère. Essayons :</p>
+
+<pre class="brush: js">let bigmouth = 'Je n\'ai pas eu droit à prendre place...';
+bigmouth;</pre>
+
+<p>Cela fonctionne à la perfection. Vous pouvez échapper d'autres caractères de la même manière, par ex. <code>\"</code>,  et il y a certains codes spéciaux à côté. Voyez  <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/String#Escape_notation">Notations d'échappement</a> pour plus de détails.</p>
+
+<h2 id="Concaténation_de_chaînes">Concaténation de chaînes</h2>
+
+<ol>
+ <li>Concaténer est un terme de programmation du genre chic qui signifie « attacher ensemble ». Pour attacher des chaînes en JavaScript, on utilise l'opérateur plus (+) , le même que l'on utilise pour ajouter deux nombres, mais dans ce contexte il fait quelque chose de différent. Voyons un exemple dans la console.
+ <pre class="brush: js">let one = 'Hello, ';
+let two = 'comment allez‑vous ?';
+let joined = one + two;
+joined;</pre>
+ Il en résulte que la variable nommée <code>joined</code> contient la valeur "Hello, comment allez‑vous ?".</li>
+ <li>Dans le dernier exemple, nous avons juste attaché deux chaînes ensemble, mais vous pouvez en attacher autant que vous voulez, pour autant que vous mettiez un signe  <code>+</code>  entre chacune. Essayez ceci :
+ <pre class="brush: js">let multiple = one + one + one + one + two;
+multiple;</pre>
+ </li>
+ <li>Vous pouvez aussi mélanger des variables avec des vraies chaînes. Regardez :
+ <pre class="brush: js">let response = one + 'Je vais bien — et vous ' + two;
+response;</pre>
+ </li>
+</ol>
+
+<div class="note">
+<p><strong>Note </strong>: Quand vous entrez une chaîne dans votre code, entre guillemets simples ou doubles, on l'appelle <strong>chaîne littérale</strong>.</p>
+</div>
+
+<h3 id="Concaténation_dans_un_contexte">Concaténation dans un contexte</h3>
+
+<p>Examinons une concaténation dans une action — voici un exemple tiré en amont de ce cours :</p>
+
+<pre class="brush: html">&lt;button&gt;Pressez‑moi&lt;/button&gt;</pre>
+
+<pre class="brush: js">let button = document.querySelector('button');
+
+button.onclick = function() {
+ let name = prompt('Quel est votre nom ?');
+ alert('Hello ' + name + ', sympa de vous voir !');
+}</pre>
+
+<p>{{ EmbedLiveSample('Concatenation_in_context', '100%', 50) }}</p>
+
+<p>Ici nous utilisons en ligne 4 la fonction {{domxref("Window.prompt()", "Window.prompt()")}}, qui demande à l'utilisateur de répondre à une question par l'intermédiaire d'une boîte de dialogue, puis qui stocke le texte entré dans une variable donnée — dans ce cas <code>name</code>. En ligne 5, nous nous servons de la fonction {{domxref("Window.alert()", "Window.alert()")}} pour afficher un dialogue contenant une chaîne assemblée à partir de deux chaînes littérales et de la variable <code>name</code>, par concaténation.</p>
+
+<h3 id="Nombres_vs_chaînes">Nombres vs chaînes</h3>
+
+<ol>
+ <li>Que se passe-t-il quand nous essayons d'additionner (ou concaténer) une chaîne et un nombre ? Essayons dans la console :
+ <pre class="brush: js">'Front ' + 242;
+</pre>
+ Vous vous attendriez à déclencher une erreur, mais cela fonctionne parfaitement. Essayer de représenter une chaîne comme un nombre n'a vraiment aucun sens, mais représenter un nombre par une chaîne en a, donc le navigateur convertit adroitement le nombre en chaîne et concatène les deux chaînes.</li>
+ <li>Vous pouvez même faire cela avec deux nombres — vous forcez un nombre à devenir une chaîne en le mettant entre guillemets. Essayez ce qui suit (nous nous servons de l'opérateur <code>typeof</code> pour vérifier si la variable est un nombre ou une chaîne):
+ <pre class="brush: js">let myDate = '19' + '67';
+typeof myDate;</pre>
+ </li>
+ <li>Si vous avez une variable numérique que vous souhaitez convertir en chaîne sans autre modification, ou une variable numérique que vous voulez convertir en chaîne sans autre modification, vous pouvez utiliser les constructions suivantes :
+ <ul>
+ <li>L'objet {{jsxref("Number")}} convertit tout ce qui lui est passé en nombre, si c'est possible. Essayez :
+ <pre class="brush: js">let myString = '123';
+let myNum = Number(myString);
+typeof myNum;</pre>
+ </li>
+ <li>D'autre part, tout nombre possède une méthode nommée <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toString">toString()</a></code> qui le convertit en chaîne équivalente. Essayez :
+ <pre class="brush: js">let myNum = 123;
+let myString = myNum.toString();
+typeof myString;</pre>
+ </li>
+ </ul>
+ Ces constructions peuvent être vraiment utiles en certaines circonstances. Par exemple, si un utilisateur entre un nombre dans un champ texte d'un formulaire, c'est une chaîne. Mais si vous voulez ajouter ce nombre à autre chose, il est nécessaire qu'il soit du type <code>number</code>, donc vous pouvez le faire passer par la méthode <code>Number()</code> pour gérer cela. C'est exactement ce que nous avons fait dans le jeu <a href="https://github.com/mdn/learning-area/blob/master/javascript/introduction-to-js-1/first-splash/number-guessing-game.html#L63">Devinez un nombre, à la ligne 63</a>.</li>
+</ol>
+
+<h2 id="Conclusion">Conclusion</h2>
+
+<p>Voilà donc les bases de la manipulation des chaînes de caractères en JavaScript. Dans le prochain article, nous allons bâtir sur ces éléments en examinant certaines méthodes intégrées disponibles pour les chaînes de caractères dans JavaScript et en les utilisant pour mettre les chaînes de caractères dans la forme voulue.</p>
+
+<p>{{PreviousMenuNext("Learn/JavaScript/First_steps/Math", "Learn/JavaScript/First_steps/Useful_string_methods", "Learn/JavaScript/First_steps")}}</p>
diff --git a/files/fr/learn/javascript/first_steps/tableaux/index.html b/files/fr/learn/javascript/first_steps/tableaux/index.html
new file mode 100644
index 0000000000..4fc38abf8d
--- /dev/null
+++ b/files/fr/learn/javascript/first_steps/tableaux/index.html
@@ -0,0 +1,528 @@
+---
+title: Les tableaux
+slug: Learn/JavaScript/First_steps/tableaux
+tags:
+ - Apprendre
+ - Article
+ - Codage
+ - Débutants
+ - JavaScript
+ - Lier
+ - Pop
+ - Push
+ - Tableaux
+ - décalage
+ - séparer
+translation_of: Learn/JavaScript/First_steps/Arrays
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/JavaScript/First_steps/Useful_string_methods", "Learn/JavaScript/First_steps/Silly_story_generator", "Learn/JavaScript/First_steps")}}</div>
+
+<p class="summary">Dans le dernier article de ce module, nous examinerons les tableaux — une façon de stocker proprement une liste d'éléments de données sous un seul nom de variable. Ici nous verrons pourquoi c'est utile, puis nous apprendrons comment créer un tableau, y retrouver, y ajouter ou en enlever les éléments dedans, et quelques à‑côtés en bonus.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Prérequis :</th>
+ <td>Vocabulaire courant de l'informatique, bases de HTML et CSS, compréhension de ce que fait JavaScript.</td>
+ </tr>
+ <tr>
+ <th scope="row">Objectif :</th>
+ <td>Comprendre ce que sont les tableaux et savoir comment les manipuler en JavaScript.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Quest‑ce_quun_tableau">Qu'est‑ce qu'un tableau ?</h2>
+
+<p>Les tableaux sont généralement décrits comme des "objets de type liste" ; un tableau est un objet contenant plusieurs valeurs. Les objets tableau peuvent être stockés dans des variables et traités de la même manière que tout autre type de valeur, la différence étant que nous pouvons accéder à chaque valeur du tableau individuellement, et faire des choses super utiles et efficaces avec la liste des valeurs, comme boucler et faire la même chose pour chaque valeur. Peut-être que nous avons une série d'articles et leurs prix stockés dans un tableau, et nous voulons les parcourir tous et les imprimer sur une facture, tout en totalisant tous les prix ensemble et en imprimant le prix total en bas.</p>
+
+<p>Sans tableaux, nous devrions stocker chaque valeur dans une variable séparée, puis appeler le code qui effectue l'affichage ou l'impression, puis ajouter séparément chaque élément. Ce serait plus long à écrire, moins efficace et cela comporterait plus de risques d'erreurs. Si nous avions 10 articles à ajouter à la facture, ce serait déjà assez mauvais, mais qu'en serait-il de 100 articles ou de 1000 ? Nous reviendrons sur cet exemple plus loin dans l'article.</p>
+
+<p>Comme précédemment, initions‑nous aux bases pratiques des tableaux en entrant quelques exemples dans une console JavaScript. En voici une plus bas (vous pouvez aussi <a href="https://mdn.github.io/learning-area/javascript/introduction-to-js-1/variables/index.html">ouvrir cette console</a> dans un onglet ou une fenêtre séparés ou utiliser la <a href="/en-US/docs/Learn/Common_questions/What_are_browser_developer_tools">console développeur de l'explorateur</a> si vous préférez).</p>
+
+<div class="hidden">
+<h6 id="Hidden_code">Hidden code</h6>
+
+<pre class="brush: html">&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+ &lt;head&gt;
+ &lt;meta charset="utf-8"&gt;
+ &lt;title&gt;JavaScript console&lt;/title&gt;
+ &lt;style&gt;
+ * {
+ box-sizing: border-box;
+ }
+
+ html {
+ background-color: #0C323D;
+ color: #809089;
+ font-family: monospace;
+ }
+
+ body {
+ max-width: 700px;
+ }
+
+ p {
+ margin: 0;
+ width: 1%;
+ padding: 0 1%;
+ font-size: 16px;
+ line-height: 1.5;
+ float: left;
+ }
+
+ .input p {
+ margin-right: 1%;
+ }
+
+ .output p {
+ width: 100%;
+ }
+
+ .input input {
+ width: 96%;
+ float: left;
+ border: none;
+ font-size: 16px;
+ line-height: 1.5;
+ font-family: monospace;
+ padding: 0;
+ background: #0C323D;
+ color: #809089;
+ }
+
+ div {
+ clear: both;
+ }
+
+ &lt;/style&gt;
+ &lt;/head&gt;
+ &lt;body&gt;
+
+
+ &lt;/body&gt;
+
+ &lt;script&gt;
+ var geval = eval;
+ function createInput() {
+ var inputDiv = document.createElement('div');
+ var inputPara = document.createElement('p');
+ var inputForm = document.createElement('input');
+
+ inputDiv.setAttribute('class','input');
+ inputPara.textContent = '&gt;';
+ inputDiv.appendChild(inputPara);
+ inputDiv.appendChild(inputForm);
+ document.body.appendChild(inputDiv);
+
+ if(document.querySelectorAll('div').length &gt; 1) {
+        inputForm.focus();
+      }
+
+ inputForm.addEventListener('change', executeCode);
+ }
+
+ function executeCode(e) {
+ try {
+ var result = geval(e.target.value);
+ } catch(e) {
+ var result = 'error — ' + e.message;
+ }
+
+ var outputDiv = document.createElement('div');
+ var outputPara = document.createElement('p');
+
+ outputDiv.setAttribute('class','output');
+ outputPara.textContent = 'Result: ' + result;
+ outputDiv.appendChild(outputPara);
+ document.body.appendChild(outputDiv);
+
+ e.target.disabled = true;
+ e.target.parentNode.style.opacity = '0.5';
+
+ createInput()
+ }
+
+ createInput();
+
+ &lt;/script&gt;
+&lt;/html&gt;</pre>
+</div>
+
+<p>{{ EmbedLiveSample('Hidden_code', '100%', 300) }}</p>
+
+<h3 id="Créer_un_tableau">Créer un tableau</h3>
+
+<p>On définit les valeurs d'un tableau par une liste d'éléments entre crochets droits, séparés par des virgules.</p>
+
+<ol>
+ <li>Disons que nous voulons mettre une liste d'achats dans un tableau — nous devons opérer comme suit. Entrez les lignes ci‑après dans la console :
+ <pre class="brush: js">let shopping = ['pain', 'lait', 'fromage', 'houmous', 'nouilles'];
+shopping;</pre>
+ </li>
+ <li>Dans ce cas, chaque élément du tableau est une chaîne, mais gardez en tête que vous pouvez stocker n'importe quel élément dans un tableau — chaîne, nombre, objet, autre variable et même d'autres tableaux. Vous pouvez également mélanger et assortir les types d'articles — il n'est pas obligatoire que ce soient tous des nombres, des chaînes, etc. Essayez ceci :</li>
+ <li>
+ <pre class="brush: js">let sequence = [1, 1, 2, 3, 5, 8, 13];
+let random = ['arbre', 795, [0, 1, 2]];</pre>
+ </li>
+ <li>Créez donc quelques tableaux de votre cru avant de continuer.</li>
+</ol>
+
+<h3 id="Accès_aux_éléments_de_tableau_et_modification_de_ceux‑ci">Accès aux éléments de tableau et modification de ceux‑ci</h3>
+
+<p>Vous pouvez avoir accès isolément aux éléments dans un tableau en utilisant la notation crochet, de la même façon que nous avons eu <a href="/en-US/Learn/JavaScript/First_steps/Useful_string_methods#Retrieving_a_specific_string_character">accès aux lettres dans une chaîne</a>.</p>
+
+<ol>
+ <li>Entrez ceci dans la console :
+ <pre class="brush: js">shopping[0];
+// renvoie "pain"</pre>
+ </li>
+ <li>Vous pouvez aussi modifier un élément dans un tableau en donnant simplement une nouvelle valeur à l'élément. Essayez ceci :
+ <pre class="brush: js">shopping[0] = 'crème de sésame';
+shopping;
+// shopping renvoie maintenant [ "crème de sésame", "lait", "fromage", "houmous", "nouilles" ]</pre>
+
+ <div class="note"><strong>Note </strong>: Nous l'avons déjà dit, mais enseigner c'est répéter — les ordinateurs commencent les décomptes à partir de 0 !</div>
+ </li>
+ <li>Notez qu'un tableau à l'intérieur d'un tableau est appelé un tableau multidimensionnel. Vous accédez à un des éléments de ce tableau interne en chaînant deux paires de crochets. Par exemple, pour avoir accès à l'un des éléments (le troisième) du tableau élément du tableau <code>random</code> (voir la section précédente), vous pouvez écrire quelque chose comme :</li>
+ <li>
+ <pre class="brush: js">random[2][2];</pre>
+ </li>
+ <li>Poursuivez et faites quelques autres modifications dans les exemples de tableaux avant de poursuivre.</li>
+</ol>
+
+<h3 id="Trouver_la_taille_dun_tableau">Trouver la taille d'un tableau</h3>
+
+<p>Vous pouvez trouver la taille d'un tableau (le nombre d'éléments qu'il comporte) de la même façon que vous obtenez la taille (en caractères) d'un chaîne — avec la propriété {{jsxref("Array.prototype.length","length")}}. Essayez :</p>
+
+<pre class="brush: js">sequence.length;
+// renvoie 7</pre>
+
+<p>Il y a d'autres usages, mais le plus courant permet de dire à une boucle de poursuivre jusqu'à ce que tous les éléments du tableau aient été passés en revue. Ainsi, par exemple :</p>
+
+<pre class="brush: js">let sequence = [1, 1, 2, 3, 5, 8, 13];
+for (var i = 0; i &lt; sequence.length; i++) {
+ console.log(sequence[i]);
+}</pre>
+
+<p>Vous en apprendrez plus sur les boucles dans un prochain article, mais, en résumé, ce code dit :</p>
+
+<ol>
+ <li>Commencer la boucle à l'élément 0 du tableau.</li>
+ <li>Arrêter de tourner quand le dernier élément du tableau sera atteint. Cela fonctionne pour n'importe quelle dimension de tableau ; dans notre cas, on sortira de la boucle à l'élément  7 (c'est bon, car le dernier élément — que nous souhaitons que la boucle traite — est le 6).</li>
+ <li>Afficher chaque élément sur la console de l'explorateur avec<code> <a href="/en-US/docs/Web/API/Console/log">console.log()</a></code>.</li>
+</ol>
+
+<h2 id="Quelques_méthodes_utiles_pour_les_tableaux">Quelques méthodes utiles pour les tableaux</h2>
+
+<p>Dans ce paragraphe nous examinerons quelques méthodes de tableaux à connaître. Elles permettent de scinder des chaînes en éléments de tableau et inversement, et d'ajouter de nouveaux éléments dans des tableaux.</p>
+
+<h3 id="Conversions_entre_chaînes_et_tableaux">Conversions entre chaînes et tableaux</h3>
+
+<p>Souvent, vous serez confronté à des données brutes contenues dans une longue chaîne de caractères, et vous voudrez peut-être en extraire les éléments utiles sous une forme plus pratique pour en faire quelque chose, comme les afficher dans un tableau de données. Pour ce faire, nous pouvons utiliser la méthode {{jsxref ("String. prototype. prototype. split ()","split ()")}}. Dans sa formulation la plus simple, elle prend un seul paramètre, le caractère servant de séparateur ; elle renverra les sous-chaînes entre séparateurs en tant qu'éléments d'un tableau.</p>
+
+<div class="note">
+<p><strong>Note </strong>: D'accord, techniquement parlant c'est une méthode de chaîne, et non une méthode de tableau, mais nous la mettons dans le chapitre des tableaux car elle est bien à sa place ici.</p>
+</div>
+
+<ol>
+ <li>Servons‑nous en et voyons comment elle fonctionne. D'abord créons une chaîne dans la console :
+ <pre class="brush: js">let myData = 'Manchester,London,Liverpool,Birmingham,Leeds,Carlisle';</pre>
+ </li>
+ <li>Scindons‑la à chaque virgule :
+ <pre class="brush: js">let myArray = myData.split(',');
+myArray;</pre>
+ </li>
+ <li>Pour terminer, trouvons la taille du nouveau tableau et retrouvons quelques‑uns de ses éléments :
+ <pre class="brush: js">myArray.length;
+myArray[0]; // le premier élément du tableau
+myArray[1]; // le deuxième élément du tableau
+myArray[myArray.length-1]; // le dernier élément du tableau</pre>
+ </li>
+ <li>Vous pouvez également faire le contraire avec la méthode {{jsxref("Array.prototype.join()","join()")}}. Essayons :
+ <pre class="brush: js">let myNewString = myArray.join(',');
+myNewString;</pre>
+ </li>
+ <li>Une autre façon de convertir un tableau en chaîne consiste à se servir de la méthode {{jsxref("Array.prototype.toString()","toString()")}}. <code>toString()</code> est plus simple au plan des arguments que <code>join()</code>, car elle ne prend pas de paramètre, mais elle est plus limitée. Avec <code>join()</code> vous pouvez diversifier les séparateurs (essayez de lancer la commande du point 4 avec un caractère autre que la virgule).
+ <pre class="brush: js">let dogNames = ["Rocket","Flash","Bella","Slugger"];
+dogNames.toString(); //Rocket,Flash,Bella,Slugger</pre>
+ </li>
+</ol>
+
+<h3 id="Ajout_et_suppression_déléments_de_tableau">Ajout et suppression d'éléments de tableau</h3>
+
+<p>Nous n'avons pas encore parlé d'ajout et de suppression d'éléments de tableau — allons‑y. Nous utiliserons le tableau <code>myArray</code> dont nous nous sommes servis à la fin de la dernière section. Si vous n'avez pas entré les commandes de cette section dans la console, il est nécessaire de créer d'abord le tableau :</p>
+
+<pre class="brush: js">let myArray = ['Manchester', 'London', 'Liverpool', 'Birmingham', 'Leeds', 'Carlisle'];</pre>
+
+<p>Premièrement, pour ajouter ou supprimer un élément à la fin du tableau, vous pouvez respectivement utiliser {{jsxref("Array.prototype.push()","push()")}} et {{jsxref("Array.prototype.pop()","pop()")}}.</p>
+
+<ol>
+ <li>Voyons <code>push()</code> d'abord — notez que vous devez mettre en paramètre les éléments que vous souhaitez ajouter à la fin du tableau. Essayez ceci :
+
+ <pre class="brush: js">myArray.push('Cardiff');
+myArray;
+myArray.push('Bradford', 'Brighton');
+myArray;
+</pre>
+ </li>
+ <li>La taille du tableau modifié est renvoyée quand l'appel de la méthode est terminé. Si vous voulez enregistrer la taille du nouveau tableau dans une variable, vous pouvez écrire quelque chose comme ceci :
+ <pre class="brush: js">let newLength = myArray.push('Bristol');
+myArray;
+newLength;</pre>
+ </li>
+ <li>Supprimer le dernier élément de la liste est très simple : il suffit de lancer <code>pop()</code> sur celle‑ci. Essayez :
+ <pre class="brush: js">myArray.pop();</pre>
+ </li>
+ <li>L'élément supprimé est renvoyé à la fin de l'appel de la méthode. Également :
+ <pre class="brush: js">let removedItem = myArray.pop();
+myArray;
+removedItem;</pre>
+ </li>
+</ol>
+
+<p>{{jsxref("Array.prototype.unshift()","unshift()")}} et {{jsxref("Array.prototype.shift()","shift()")}} fonctionnent exactement de la même manière, excepté qu'il travaillent sur la tête du tableau au lieu de la queue.</p>
+
+<ol>
+ <li>D'abord <code>unshift()</code> — essayez :
+
+ <pre class="brush: js">myArray.unshift('Edinburgh');
+myArray;</pre>
+ </li>
+ <li>Maintenant <code>shift()</code> — essayez !
+ <pre class="brush: js">let removedItem = myArray.shift();
+myArray;
+removedItem;</pre>
+ </li>
+</ol>
+
+<h2 id="Activité_affichons_les_produits_!">Activité : affichons les produits !</h2>
+
+<p>Revenons à l'exemple que nous avons décrit plus haut — afficher les noms des produits et leurs prix pour un envoi, puis faire le total des prix et l'afficher à la fin de la liste. Dans l'exemple modifiable ci‑dessous, il y a des commentaires numérotés — chacun d'entre eux marque l'emplacement où vous devez ajouter quelque chose au code. Voici :</p>
+
+<ol>
+ <li>Sous le commentaire <code>// number 1</code> il y a un certain nombre de chaînes de caractères, chacune précise le nom d'un produit et son prix séparé par deux‑points. Placez‑les dans un tableau ; enregistrez‑le sous le nom <code>products</code>.</li>
+ <li>Sur la même ligne que le commentaire <code>// number 2</code> se trouve le début d'une boucle. Dans cette ligne nous avons actuellement <code>i &lt;= 0</code>, test conditionnel qui fait que la <a href="/en-US/Learn/JavaScript/First_steps/A_first_splash#Loops"> boucle</a> stoppe immédiatement, car ce test dit « stopper dès que <code>i</code> est inférieur ou égal à 0 » et <code>i</code> part de 0. Remplacez ce test par un qui  n'arrêtera pas la boucle tant que <code>i</code> sera inférieur à la taille du tableau <code>products</code>.</li>
+ <li>Au dessous du commentaire <code>// number 3</code> nous voudrions que vous écriviez une ligne de code qui scinde l'élément courant du tableau (<code>nom:prix</code>) en deux éléments distincts, un contenant uniquement le nom, l'autre uniquement le prix. Si vous nous ne savez pas trop comment faire, revoyez l'article relatif aux <a href="/fr/docs/Learn/JavaScript/First_steps/methode_chaine_utile">Méthodes utiles pour les chaînes de caractères</a> pour vous aider, ou même mieux, regardez la section {{anch("Converting between strings and arrays")}} de cet article.</li>
+ <li>En plus des lignes de code ci‑dessus, vous aurez aussi à convertir les prix de chaîne de caractères en chiffres. Si vous ne vous souvenez pas comment faire, revoyez le <a href="/fr/docs/Learn/JavaScript/First_steps/Strings#Numbers_versus_strings">premier article à propos des chaînes</a>.</li>
+ <li>Il y a une variable nommée <code>total</code> créée et initialisée à la valeur de 0 en tête du code. Dans la boucle (sous <code>// number 4</code>) ajoutez une ligne qui ajoute à ce total le prix de l'article courant  à chaque itération de la boucle, de sorte que à la fin du code le prix total soit correctement inscrit sur l'envoi. Vous pourriez avoir besoin d'un <a href="/en-US/Learn/JavaScript/First_steps/Math#Assignment_operators">opérateur d'assignation</a> pour faire cela ;-).</li>
+ <li>Nous souhaitons que vous modifiez la ligne au‑dessous de  <code>// number 5</code> de sorte que la variable <code>itemText</code> soit égale à « nom actuel de l'élément — $prix actuel de l'élément », par exemple « Shoes — $23.99 » dans chaque cas, de façon à ce qu'une information correcte soit affichée sur l'envoi. Il s'agit d'une simple concaténation de chaînes de caractères, chose qui doit vous être familière.</li>
+</ol>
+
+<div class="hidden">
+<h6 id="Playable_code">Playable code</h6>
+
+<pre class="brush: html">&lt;div class="output" style="min-height: 150px;"&gt;
+
+&lt;ul&gt;
+
+&lt;/ul&gt;
+
+&lt;p&gt;&lt;/p&gt;
+
+&lt;/div&gt;
+
+&lt;textarea id="code" class="playable-code" style="height: 370px;"&gt;
+var list = document.querySelector('.output ul');
+var totalBox = document.querySelector('.output p');
+var total = 0;
+list.innerHTML = '';
+totalBox.textContent = '';
+// number 1
+ 'Caleçons:6.99'
+ 'Chaussettes:5.99'
+ 'T-shirt:14.99'
+ 'Pantalons:31.99'
+ 'Chaussures:23.99';
+
+for (var i = 0; i &lt;= 0; i++) { // number 2
+ // number 3
+
+ // number 4
+
+ // number 5
+ itemText = 0;
+
+ var listItem = document.createElement('li');
+ listItem.textContent = itemText;
+ list.appendChild(listItem);
+}
+
+totalBox.textContent = 'Total: $' + total.toFixed(2);
+&lt;/textarea&gt;
+
+&lt;div class="playable-buttons"&gt;
+ &lt;input id="reset" type="button" value="Reset"&gt;
+ &lt;input id="solution" type="button" value="Show solution"&gt;
+&lt;/div&gt;
+</pre>
+
+<pre class="brush: js">var textarea = document.getElementById('code');
+var reset = document.getElementById('reset');
+var solution = document.getElementById('solution');
+var code = textarea.value;
+
+function updateCode() {
+ eval(textarea.value);
+}
+
+reset.addEventListener('click', function() {
+ textarea.value = code;
+ updateCode();
+});
+
+solution.addEventListener('click', function() {
+ textarea.value = jsSolution;
+ updateCode();
+});
+
+var jsSolution = 'var list = document.querySelector(\'.output ul\');\nvar totalBox = document.querySelector(\'.output p\');\nvar total = 0;\nlist.innerHTML = \'\';\ntotalBox.textContent = \'\';\n\nvar products = [\'Underpants:6.99\',\n \'Socks:5.99\',\n \'T-shirt:14.99\',\n \'Trousers:31.99\',\n \'Shoes:23.99\'];\n\nfor(var i = 0; i &lt; products.length; i++) {\n var subArray = products[i].split(\':\');\n var name = subArray[0];\n var price = Number(subArray[1]);\n total += price;\n itemText = name + \' — $\' + price;\n\n var listItem = document.createElement(\'li\');\n listItem.textContent = itemText;\n list.appendChild(listItem);\n}\n\ntotalBox.textContent = \'Total: $\' + total.toFixed(2);';
+
+textarea.addEventListener('input', updateCode);
+window.addEventListener('load', updateCode);
+</pre>
+</div>
+
+<p>{{ EmbedLiveSample('Playable_code', '100%', 600) }}</p>
+
+<h2 id="Activité_Top_5_des_recherches">Activité : Top 5 des recherches</h2>
+
+<p>Une bonne utilisation des méthodes de tableaux comme {{jsxref("Array.prototype.push()","push()")}} et {{jsxref("Array.prototype.pop()","pop()")}} permet de conserver un enregistrement des éléments actuellement actifs dans une application web. Dans une scène animée, par exemple, vous pouvez avoir un tableau d'objets représentant les graphiques d'arrière-plan actuellement affichés, et vous pouvez n'en vouloir que 50 à la fois, pour des raisons de performance ou d'encombrement. Chaque fois que de nouveaux objets sont créés et ajoutés au tableau, les plus anciens peuvent être supprimés du tableau pour n'en conserver que le nombre voulu.</p>
+
+<p>Dans cet exemple nous allons montrer une utilisation beaucoup plus simple — ici, nous allons vous fournir un site de recherche fictif, avec une boîte de recherche. Voici l'idée : quand un terme est entré dans la boîte de recherche, les 5 précédents termes entrés sont affichés dans la liste. Quand le nombre de termes dépasse 5, le dernier terme est supprimé chaque fois qu'un nouveau terme est ajouté ; ainsi, le 5 termes précédents sont toujours affichés.</p>
+
+<div class="note">
+<p><strong>Note</strong> : Dans une application réelle avec boîte de recherche, vous pourriez vraisemblablement cliquer sur un des termes de la liste pour revenir à la recherche précédente, et l'application afficherait les vrais résultats ! Mais pour le moment nous en resterons à quelque chose de simple.</p>
+</div>
+
+<p>Pour terminer l'application, il vous faut :</p>
+
+<ol>
+ <li>Ajouter une ligne sous le commentaire <code>// number 1</code> pour ajouter la valeur qui vient d'être saisie dans la boîte au début du tableau. Cette valeur est récupérée avec <code>searchInput.value</code>.</li>
+ <li>Ajouter une ligne sous le commentaire <code>// number 2</code>  pour supprimer la valeur en fin de liste du tableau.</li>
+</ol>
+
+<div class="hidden">
+<h6 id="Playable_code_2">Playable code 2</h6>
+
+<pre class="brush: html">&lt;div class="output" style="min-height: 150px;"&gt;
+
+&lt;input type="text"&gt;&lt;button&gt;Search&lt;/button&gt;
+
+&lt;ul&gt;
+
+&lt;/ul&gt;
+
+&lt;/div&gt;
+
+&lt;textarea id="code" class="playable-code" style="height: 370px;"&gt;
+var list = document.querySelector('.output ul');
+var searchInput = document.querySelector('.output input');
+var searchBtn = document.querySelector('.output button');
+
+list.innerHTML = '';
+
+var myHistory = [];
+
+searchBtn.onclick = function() {
+ // we will only allow a term to be entered if the search input isn't empty
+ if (searchInput.value !== '') {
+ // number 1
+
+ // empty the list so that we don't display duplicate entries
+ // the display is regenerated every time a search term is entered.
+ list.innerHTML = '';
+
+ // loop through the array, and display all the search terms in the list
+ for (var i = 0; i &lt; myHistory.length; i++) {
+ itemText = myHistory[i];
+ var listItem = document.createElement('li');
+ listItem.textContent = itemText;
+ list.appendChild(listItem);
+ }
+
+ // If the array length is 5 or more, remove the oldest search term
+ if (myHistory.length &gt;= 5) {
+ // number 2
+
+ }
+
+ // empty the search input and focus it, ready for the next term to be entered
+ searchInput.value = '';
+ searchInput.focus();
+ }
+}
+&lt;/textarea&gt;
+
+&lt;div class="playable-buttons"&gt;
+ &lt;input id="reset" type="button" value="Reset"&gt;
+ &lt;input id="solution" type="button" value="Show solution"&gt;
+&lt;/div&gt;
+</pre>
+
+<pre class="brush: js">var textarea = document.getElementById('code');
+var reset = document.getElementById('reset');
+var solution = document.getElementById('solution');
+var code = textarea.value;
+
+function updateCode() {
+ eval(textarea.value);
+}
+
+reset.addEventListener('click', function() {
+ textarea.value = code;
+ updateCode();
+});
+
+solution.addEventListener('click', function() {
+ textarea.value = jsSolution;
+ updateCode();
+});
+
+var jsSolution = 'var list = document.querySelector(\'.output ul\');\nvar searchInput = document.querySelector(\'.output input\');\nvar searchBtn = document.querySelector(\'.output button\');\n\nlist.innerHTML = \'\';\n\nvar myHistory= [];\n\nsearchBtn.onclick = function() {\n if(searchInput.value !== \'\') {\n myHistory.unshift(searchInput.value);\n\n list.innerHTML = \'\';\n\n for(var i = 0; i &lt; myHistory.length; i++) {\n itemText = myHistory[i];\n var listItem = document.createElement(\'li\');\n listItem.textContent = itemText;\n list.appendChild(listItem);\n }\n\n if(myHistory.length &gt;= 5) {\n myHistory.pop();\n }\n\n searchInput.value = \'\';\n searchInput.focus();\n }\n}';
+
+textarea.addEventListener('input', updateCode);
+window.addEventListener('load', updateCode);
+</pre>
+</div>
+
+<p>{{ EmbedLiveSample('Playable_code_2', '100%', 600) }}</p>
+
+<h2 id="Testez_vos_compétences_!">Testez vos compétences !</h2>
+
+<p><br>
+ Vous avez atteint la fin de cet article, mais vous souvenez-vous des informations les plus importantes ? Vous pouvez trouver d'autres tests pour vérifier que vous avez bien fixé ces connaissances avant de continuer — voir <a href="https://wiki.developer.mozilla.org/en-US/docs/Learn/JavaScript/First_steps/Test_your_skills:_Arrays">Test de compétences : les tableaux</a>.</p>
+
+<h2 id="Conclusion">Conclusion</h2>
+
+<p>Après la lecture de cet article, vous conviendrez que les tableaux semblent fichtrement utiles ; vous les verrez un peu partout en JavaScript, souvent associés à des boucles pour appliquer la même action à chaque élément du tableau. Nous vous indiquerons toutes les bases utiles à savoir à propos des boucles dans le prochain module, mais pour l'instant, félicitations : prenez une pause bien méritée ; vous avez étudié tous les articles du module !</p>
+
+<p>La seule chose restant à faire est de procéder à l'évaluation de ce module pour tester votre compréhension de son contenu.</p>
+
+<h2 id="Voir_aussi">Voir aussi</h2>
+
+
+
+<ul>
+ <li><a href="/en-US/docs/Web/JavaScript/Guide/Indexed_collections">Collections indexées</a> — un guide de niveau avancé à propos des tableaux et de leurs cousins, les tableaux typés.</li>
+ <li>{{jsxref("Array")}} — la page de référence de l'objet <code>Array</code> — pour un guide de référence détaillé à propos des fonctionnalités discutées dans cette page, et plus encore.</li>
+</ul>
+
+<p>{{PreviousMenuNext("Learn/JavaScript/First_steps/Useful_string_methods", "Learn/JavaScript/First_steps/Silly_story_generator", "Learn/JavaScript/First_steps")}}</p>
+
+<h2 id="Dans_ce_module">Dans ce module</h2>
+
+<ul>
+ <li><a href="https://wiki.developer.mozilla.org/en-US/docs/Learn/JavaScript/First_steps/What_is_JavaScript">What is JavaScript?</a></li>
+ <li><a href="https://wiki.developer.mozilla.org/en-US/docs/Learn/JavaScript/First_steps/A_first_splash">A first splash into JavaScript</a></li>
+ <li><a href="https://wiki.developer.mozilla.org/en-US/docs/Learn/JavaScript/First_steps/What_went_wrong">What went wrong? Troubleshooting JavaScript</a></li>
+ <li><a href="https://wiki.developer.mozilla.org/en-US/docs/Learn/JavaScript/First_steps/Variables">Storing the information you need — Variables</a></li>
+ <li><a href="https://wiki.developer.mozilla.org/en-US/docs/Learn/JavaScript/First_steps/Math">Basic math in JavaScript — numbers and operators</a></li>
+ <li><a href="https://wiki.developer.mozilla.org/en-US/docs/Learn/JavaScript/First_steps/Strings">Handling text — strings in JavaScript</a></li>
+ <li><a href="https://wiki.developer.mozilla.org/en-US/docs/Learn/JavaScript/First_steps/Useful_string_methods">Useful string methods</a></li>
+ <li><a href="https://wiki.developer.mozilla.org/en-US/docs/Learn/JavaScript/First_steps/Arrays">Arrays</a></li>
+ <li><a href="https://wiki.developer.mozilla.org/en-US/docs/Learn/JavaScript/First_steps/Silly_story_generator">Assessment: Silly story generator</a></li>
+</ul>
diff --git a/files/fr/learn/javascript/first_steps/testes_vos_competence_colon__tableaux/index.html b/files/fr/learn/javascript/first_steps/testes_vos_competence_colon__tableaux/index.html
new file mode 100644
index 0000000000..240e934831
--- /dev/null
+++ b/files/fr/learn/javascript/first_steps/testes_vos_competence_colon__tableaux/index.html
@@ -0,0 +1,87 @@
+---
+title: 'Testez vos compétences: Tableaux'
+slug: 'Learn/JavaScript/First_steps/Testes_vos_competence:_Tableaux'
+translation_of: 'Learn/JavaScript/First_steps/Test_your_skills:_Arrays'
+---
+<div>{{learnsidebar}}</div>
+
+<p>This aim of this skill test is to assess whether you've understood our <a href="/en-US/docs/Learn/JavaScript/First_steps/Arrays">Arrays</a> article.</p>
+
+<div class="blockIndicator note">
+<p><strong>Note</strong>: You can try out solutions in the interactive editors below, however it may be helpful to download the code and use an online tool such as <a href="https://codepen.io/">CodePen</a>, <a href="https://jsfiddle.net/">jsFiddle</a>, or <a href="https://glitch.com/">Glitch</a> to work on the tasks.<br>
+ <br>
+ If you get stuck, then ask us for help — see the {{anch("Assessment or further help")}} section at the bottom of this page.</p>
+</div>
+
+<div class="blockIndicator note">
+<p><strong>Note</strong>: In the examples below, if there is an error in your code it will be outputted into the results panel on the page, to help you try to figure out the answer (or into the browser's JavaScript console, in the case of the downloadable version).</p>
+</div>
+
+<h2 id="Arrays_1">Arrays 1</h2>
+
+<p>Let's start off with some basic array practice. In this task we'd like you to create an array of three items, stored inside a variable called <code>myArray</code>. The items can be anything you want — how about your favourite foods or bands?</p>
+
+<p>Next, modify the first two items in the array using simple bracket notation and assignment. Then add a new item to the beginning of the array.</p>
+
+<p>Try updating the live code below to recreate the finished example:</p>
+
+<p>{{EmbedGHLiveSample("learning-area/javascript/introduction-to-js-1/tasks/arrays/arrays1.html", '100%', 400)}}</p>
+
+<div class="blockIndicator note">
+<p><a href="https://github.com/mdn/learning-area/blob/master/javascript/introduction-to-js-1/tasks/arrays/arrays1-download.html">Download the starting point for this task</a> to work in your own editor or in an online editor.</p>
+</div>
+
+<h2 id="Arrays_2">Arrays 2</h2>
+
+<p>Now let's move on to another task. Here you are provided with a string to work with. We'd like you to:</p>
+
+<ol>
+ <li>Convert the string into an array, removing the <code>+</code> characters in the process. Save the result in a variable called <code>myArray</code>.</li>
+ <li>Store the length of the array in a variable called <code>arrayLength</code>.</li>
+ <li>Store the last item in the array in a variable called <code>lastItem</code>.</li>
+</ol>
+
+<p>Try updating the live code below to recreate the finished example:</p>
+
+<p>{{EmbedGHLiveSample("learning-area/javascript/introduction-to-js-1/tasks/arrays/arrays2.html", '100%', 400)}}</p>
+
+<div class="blockIndicator note">
+<p><a href="https://github.com/mdn/learning-area/blob/master/javascript/introduction-to-js-1/tasks/arrays/arrays2-download.html">Download the starting point for this task</a> to work in your own editor or in an online editor.</p>
+</div>
+
+<h2 id="Arrays_3">Arrays 3</h2>
+
+<p>For this final array task, we provide you with a starting array, and you will work in somewhat the opposite direction. You need to:</p>
+
+<ol>
+ <li>Remove the last item in the array.</li>
+ <li>Add two new names to the end of the array.</li>
+ <li>Go over each item in the array and add its index number after the name inside parentheses, for example <code>Ryu (0)</code>. Note that we don't teach how to do this in the Arrays article, so you'll have to do some research.</li>
+ <li>Finally, join the array items together in a single string called <code>myString</code>, with a separator of "<code> - </code>".</li>
+</ol>
+
+<p>Try updating the live code below to recreate the finished example:</p>
+
+<p>{{EmbedGHLiveSample("learning-area/javascript/introduction-to-js-1/tasks/arrays/arrays3.html", '100%', 400)}}</p>
+
+<div class="blockIndicator note">
+<p><a href="https://github.com/mdn/learning-area/blob/master/javascript/introduction-to-js-1/tasks/arrays/arrays3-download.html">Download the starting point for this task</a> to work in your own editor or in an online editor.</p>
+</div>
+
+<h2 id="Assessment_or_further_help">Assessment or further help</h2>
+
+<p>You can practice these examples in the Interactive Editors above.</p>
+
+<p>If you would like your work assessed, or are stuck and want to ask for help:</p>
+
+<ol>
+ <li>Put your work into an online shareable editor such as <a href="https://codepen.io/">CodePen</a>, <a href="https://jsfiddle.net/">jsFiddle</a>, or <a href="https://glitch.com/">Glitch</a>. You can write the code yourself, or use the starting point files linked to in the above sections.</li>
+ <li>Write a post asking for assessment and/or help at the <a href="https://discourse.mozilla.org/c/mdn/learn">MDN Discourse forum Learning category</a>. Your post should include:
+ <ul>
+ <li>A descriptive title such as "Assessment wanted for Variables 1 skill test".</li>
+ <li>Details of what you have already tried, and what you would like us to do, e.g. if you are stuck and need help, or want an assessment.</li>
+ <li>A link to the example you want assessed or need help with, in an online shareable editor (as mentioned in step 1 above). This is a good practice to get into — it's very hard to help someone with a coding problem if you can't see their code.</li>
+ <li>A link to the actual task or assessment page, so we can find the question you want help with.</li>
+ </ul>
+ </li>
+</ol>
diff --git a/files/fr/learn/javascript/first_steps/variables/index.html b/files/fr/learn/javascript/first_steps/variables/index.html
new file mode 100644
index 0000000000..35104fcaeb
--- /dev/null
+++ b/files/fr/learn/javascript/first_steps/variables/index.html
@@ -0,0 +1,434 @@
+---
+title: Stocker les informations nécessaires — les variables
+slug: Learn/JavaScript/First_steps/Variables
+tags:
+ - Booléens
+ - Declaration
+ - Initialisation
+ - JavaScript
+ - Mise à jour
+ - Nombres
+ - Objets
+ - Tableaux
+ - Typage faible
+ - Variables
+ - chaînes
+translation_of: Learn/JavaScript/First_steps/Variables
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/JavaScript/First_steps/What_went_wrong", "Learn/JavaScript/First_steps/Math", "Learn/JavaScript/First_steps")}}</div>
+
+<p class="summary">Après lecture des deux articles précédents, vous savez maintenant ce qu'est JavaScript, ce qu'il peut vous apporter, comment l'utiliser aux côtés d'autres technologies web et l'aspect de ses principales fonctionnalités vues de haut. Dans cet article, nous revenons aux fondements réels en examinant comment travailler avec le bloc de construction le plus basique du JavaScript — les variables.</p>
+
+<table class="learn-box">
+ <tbody>
+ <tr>
+ <th scope="row">Prérequis :</th>
+ <td>Vocabulaire courant de l'informatique, bases de HTML et CSS, compréhension de ce que fait JavaScript.</td>
+ </tr>
+ <tr>
+ <th scope="row">Objectif :</th>
+ <td>Se familiariser avec l'usage élémentaire des variables en JavaScript.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Outils_nécessaires">Outils nécessaires</h2>
+
+<p>Tout au long de cet article, on vous demandera de saisir des lignes de code pour tester votre compréhension. Si vous vous servez du navigateur avec un ordinateur de bureau, l'endroit le plus approprié pour saisir les exemples de code est la console JavaScript du navigateur (voyez <a href="/en-US/docs/Learn/Common_questions/What_are_browser_developer_tools">Les outils de développement du navigateur</a> pour plus d'informations sur la manière d'accéder à ces outils).</p>
+
+<p>Toutefois, nous avons aussi incorporé une console JavaScript dans cette page pour vous permettre d'y écrire le code au cas où vous n'utiliseriez pas un navigateur avec une console JavaScript facilement accessible, ou si vous estimez qu'une console incorporée est plus confortable.</p>
+
+<h2 id="Quest_ce_quune_variable">Qu'est ce qu'une variable ?</h2>
+
+<p>Une variable est un conteneur pour une valeur, tel un nombre à utiliser pour une addition, ou une chaîne devant faire partie d'une phrase. Mais un aspect spécial des variables est que les valeurs contenues peuvent changer. Voyons un exemple simple :</p>
+
+<pre class="brush: html">&lt;button&gt;Pressez moi&lt;/button&gt;</pre>
+
+<pre class="brush: js">const button = document.querySelector('button');
+
+button.onclick = function() {
+ let name = prompt('Quel est votre nom ?');
+ alert('Salut ' + name + ', sympa de vous voir !');
+}</pre>
+
+<p>{{ EmbedLiveSample('What_is_a_variable', '100%', 50) }}</p>
+
+<p>Dans cet exemple, presser le bouton déclenche l'exécution de quelques lignes de code. La première ligne affiche à l'écran une boîte priant l'utilisateur de saisir son nom et stocke la valeur entrée dans une variable. La deuxième affiche un message de bienvenue avec la valeur de la variable.</p>
+
+<p>Pour comprendre le pratique de la chose, imaginons comment nous aurions du coder cet exemple sans utiliser de variable. Serait-ce comme cela ?</p>
+
+<pre class="example-bad">let name = prompt('Quel est votre nom ?');
+
+if (name === 'Adam') {
+ alert('Salut Adam, sympa de vous voir !');
+} else if (name === 'Alan') {
+ alert('Salut Alan, sympa de vous voir !');
+} else if (name === 'Bella') {
+ alert('Salut Bella, sympa de vous voir !');
+} else if (name === 'Bianca') {
+ alert('Salut Bianca, sympa de vous voir !');
+} else if (name === 'Chris') {
+ alert('Salut Chris, sympa de vous voir !');
+}
+
+// ... etc.</pre>
+
+<p>Peut-être ne comprenez‑vous pas (encore !) la syntaxe utilisée, mais vous l'imaginerez sans peine  — si nous n'avions pas de variables à disposition, nous devrions implémenter un bloc de code géant qui vérifierait quel était le nom saisi, puis afficherait un message approprié à ce nom. Cela est évidemment inefficace (le code est déjà plus volumineux avec seulement quatre possibilités) et il ne fonctionnerait certainement pas — il n'est pas possible de stocker tous les choix possibles.</p>
+
+<p>Les variables sont essentielles et à mesure que vous en apprendrez plus sur JavaScript, elles deviendront une seconde nature pour vous.</p>
+
+<p>Une autre particularité des variables : elle peuvent contenir pratiquement de tout — pas uniquement des chaînes ou des nombres. Elles peuvent aussi contenir des données complexes et même des fonctions, ce qui permet de réaliser des choses étonnantes. Vous en apprendrez plus à ce propos au long de ce parcours.</p>
+
+<div class="blockIndicator note">
+<p><strong>Note :</strong> Nous disons que les variables contiennent des valeurs. C'est un distingo important. Les variables ne sont pas les valeurs elles‑mêmes : ce sont des conteneurs pour ces valeurs. Vous pouvez vous les représenter comme une boîte en carton dans laquelle il est possible de ranger des choses.</p>
+</div>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/13506/boxes.png" style="display: block; height: 436px; margin: 0px auto; width: 1052px;"></p>
+
+<h2 id="Déclarer_une_variable">Déclarer une variable</h2>
+
+<p>Avant de se servir d'une variable, il faut d'abord la créer — plus précisément, nous disons <em>déclarer la variable</em>. Pour ce faire, nous saisissons le mot‑clé <code>var</code> ou <code>let</code> suivi du nom que vous voulez donner à la variable :</p>
+
+<pre class="brush: js">let myName;
+let myAge;</pre>
+
+<p>Dans ces lignes, nous venons de créer deux variables nommées respectivement <code>myName</code> et <code>myAge</code>. Saisissez les maintenant dans la console de votre navigateur, ou dans la console au bas de la page (Vous <a href="https://mdn.github.io/learning-area/javascript/introduction-to-js-1/variables/index.html">ouvrez cette console</a> soit dans un onglet séparé, soit dans une fenêtre selon votre préférence). Après cela, essayez de créer une variable (ou deux) en choisissant vous même le nom.</p>
+
+<div class="hidden">
+<h6 id="Hidden_code">Hidden code</h6>
+
+<pre class="brush: html">&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+ &lt;head&gt;
+ &lt;meta charset="utf-8"&gt;
+ &lt;title&gt;JavaScript console&lt;/title&gt;
+ &lt;style&gt;
+ * {
+ box-sizing: border-box;
+ }
+
+ html {
+ background-color: #0C323D;
+ color: #809089;
+ font-family: monospace;
+ }
+
+ body {
+ max-width: 700px;
+ }
+
+ p {
+ margin: 0;
+ width: 1%;
+ padding: 0 1%;
+ font-size: 16px;
+ line-height: 1.5;
+ float: left;
+ }
+
+ .input p {
+ margin-right: 1%;
+ }
+
+ .output p {
+ width: 100%;
+ }
+
+ .input input {
+ width: 96%;
+ float: left;
+ border: none;
+ font-size: 16px;
+ line-height: 1.5;
+ font-family: monospace;
+ padding: 0;
+ background: #0C323D;
+ color: #809089;
+ }
+
+ div {
+ clear: both;
+ }
+
+ &lt;/style&gt;
+ &lt;/head&gt;
+ &lt;body&gt;
+
+
+ &lt;/body&gt;
+
+ &lt;script&gt;
+ var geval = eval;
+ function createInput() {
+ var inputDiv = document.createElement('div');
+ var inputPara = document.createElement('p');
+ var inputForm = document.createElement('input');
+
+ inputDiv.setAttribute('class','input');
+ inputPara.textContent = '&gt;';
+ inputDiv.appendChild(inputPara);
+ inputDiv.appendChild(inputForm);
+ document.body.appendChild(inputDiv);
+
+ if(document.querySelectorAll('div').length &gt; 1) {
+        inputForm.focus();
+      }
+
+ inputForm.addEventListener('change', executeCode);
+ }
+
+ function executeCode(e) {
+ try {
+ var result = geval(e.target.value);
+ } catch(e) {
+ var result = 'error — ' + e.message;
+ }
+
+ var outputDiv = document.createElement('div');
+ var outputPara = document.createElement('p');
+
+ outputDiv.setAttribute('class','output');
+ outputPara.textContent = 'Result: ' + result;
+ outputDiv.appendChild(outputPara);
+ document.body.appendChild(outputDiv);
+
+ e.target.disabled = true;
+ e.target.parentNode.style.opacity = '0.5';
+
+ createInput()
+ }
+
+ createInput();
+
+ &lt;/script&gt;
+&lt;/html&gt;</pre>
+</div>
+
+<p>{{ EmbedLiveSample('Hidden_code', '100%', 300) }}</p>
+
+<div class="note">
+<p><strong>Note </strong>: En JavaScript, le code de toute instruction doit se terminer par un point‑virgule (<code>;</code>) — il peut fonctionner correctement sans ce point‑virgule pour des lignes isolées, mais ce ne sera probablement pas le cas si vous écrivez plusieurs lignes de code ensemble. Prenez l'habitude de mettre ce point‑virgule.</p>
+</div>
+
+<p>Vous pouvez maintenant tester si ces valeurs existent dans l'environnement d'exécution en saisissant simplement le nom de ces variables, par exemple</p>
+
+<pre class="brush: js">myName;
+myAge;</pre>
+
+<p>Actuellement elles ne contiennent aucune valeur ; ce sont des conteneurs vides. Quand vous entrez les noms des variables, vous obtiendrez la valeur <code>undefined</code> en retour. Si elles n'existent pas, vous aurez un message d'erreur — essayez en saisissant</p>
+
+<pre class="brush: js">scoobyDoo;</pre>
+
+<div class="note">
+<p><strong>Note </strong>: Ne confondez pas une variable qui existe mais sans valeur définie avec une variable qui n'existe pas du tout — ce sont deux choses tout à fait différentes. Dans l'analogie des boîtes, <em>ne pas exister</em> correspond à l'absence de boîte ; <em>valeur indéfinie</em> correspond à une boîte vide.</p>
+</div>
+
+<h2 id="Initialisation_dune_variable">Initialisation d'une variable</h2>
+
+<p>Une fois la variable déclarée, vous pouvez l'initialiser avec une valeur. On réalise cela en saisissant le nom de la variable, suivi d'un signe égale (<code>=</code>), lui-même suivi de la valeur souhaitée pour la variable. Par exemple :</p>
+
+<pre class="brush: js">myName = 'Chris';
+myAge = 37;</pre>
+
+<p>Revenez à la console maintenant et saisissez‑y ces deux lignes. Constatez que la console renvoie en confirmation la  valeur assignée à la variable dans chaque cas. Vous pouvez, à nouveau, faire renvoyer par la console les valeurs de variable en saisissant simplement son nom dans la console — essayez encore :</p>
+
+<pre class="brush: js">myName;
+myAge;</pre>
+
+<p>Il est possible de déclarer et initialiser une variable en même temps, comme ceci :</p>
+
+<pre class="brush: js">let myDog = 'Rover';</pre>
+
+<p>C'est probablement ce que vous ferez la plupart du temps, c'est plus rapide que d'effectuer ces deux actions sur deux lignes distinctes.</p>
+
+<h2 id="La_différence_entre_var_et_let">La différence entre <code>var</code> et <code>let</code></h2>
+
+<p>A ce moment de votre apprentissage, vous vous demandez sans doute : mais quel besoin de deux mot-clé pour définir une variable ? Pourquoi <code>var</code> et <code>let</code> ?</p>
+
+<p>Les raisons sont d'ordre historique. A l'origine, quand Javascript fut créé, il n'y avait que <code>var</code>. Cela fonctionnait plutôt bien dans la plupart des cas, avec parfois quelques surprises -- l'implémentation étonnante du <code>var</code> peut amener à une mauvaise interprétation, voire à des soucis. Ainsi, <code>let</code> a été ajouté dans les versions plus récentes de Javascript, un nouveau mot-clé pour créer des variables, avec un fonctionnement différent de celui du <code>var</code>, réglant ainsi les difficultés évoquées ci-dessus.</p>
+
+<p>Nous évoquons ci-dessous quelques unes de ces différences, sans pouvoir faire ici le tour complet de la question. Vous comprendrez mieux la différence entre ces deux constructions au fur et à mesure de votre progression en JavaScript (si vous ne pouvez pas attendre, consultez la page de référence du <code>let</code>). </p>
+
+<p>Pour commencer, si vous écrivez un programme JavaScript multi-lignes qui déclare et initialise une variable, vous pouvez déclarez une variable avec le mot-clé <code>var</code> après l'avoir initialisée. Cela fonctionnera. Par exemple :</p>
+
+<pre class="brush: js">myName = 'Chris';
+
+function logName(){
+ console.log(myName);
+}
+
+logName();
+
+var myName;
+</pre>
+
+<div class="blockIndicator note">
+<p>Note : l'exemple ci-dessus ne fonctionnera pas si on tape des lignes une à une dans la console, mais seulement quand on exécute un script JavaScript multi-lignes dans un document web.</p>
+</div>
+
+<p>Ce processus se nomme <strong>«</strong> <strong>hoisting »</strong> <span class="st">(en français, "hissage") </span>— lisez <a href="/en-US/docs/Web/JavaScript/Reference/Statements/var#var_hoisting">var hoisting</a> pour plus de précisions sur ce sujet.</p>
+
+<p>Le hissage ne fonctionne plus avec <code>let</code>. Si on remplaçait var par let dans l'exemple ci-dessus, l'exécution du script planterait sur une erreur. C'est une bonne chose — déclarer une variable après l'avoir initialisé produit un code obscur, difficile à lire.</p>
+
+<p>Deuxièmement, quand vous utilisez <code>var</code>, vous pouvez déclarer la même variable autant de fois que vous le désirez, avec <code>let</code> c'est impossible. Le code suivant s'exécute sans erreur :</p>
+
+<pre class="brush: js">var myName = 'Chris';
+var myName = 'Bob';
+</pre>
+
+<p> Celui là produit une erreur sur la seconde ligne :</p>
+
+<pre class="brush: js">let myName = 'Chris';
+let myName = 'Bob';
+</pre>
+
+<p>Le code correct serait :</p>
+
+<pre class="brush: js">let myName = 'Chris' ;
+
+myName = 'Bob' ;</pre>
+
+<p>Encore une fois, c'est une décision sensée des concepteurs du langage. Il n'y a aucune bonne raison de redéclarer une variable —  cela rend les choses obscures.</p>
+
+<p>Pour ces raisons, et d'autres, nous recommandons d'utiliser <code>let</code> plutôt que <code>var</code>. Il n'y a pas de bonne raison d'utiliser <code>var</code>, sauf à rechercher la compatibilité avec de vieilles versions d'Internet Explorer (pas de support du <code>let</code> avant la version 11 ; le support de <code>let</code> par le navigateur Edge ne pose pas de problème).</p>
+
+<h2 id="Mise_à_jour_dune_variable">Mise à jour d'une variable</h2>
+
+<p>Une fois la variable initialisée avec une valeur, vous pouvez simplement modifier (ou mettre à jour) cette valeur en lui assignant une nouvelle valeur. Entrez ces deux lignes dans la console :</p>
+
+<pre class="brush: js">myName = 'Bob';
+myAge = 40;</pre>
+
+<h3 id="Aparté_concernant_les_règles_de_nommage_des_variables">Aparté concernant les règles de nommage des variables</h3>
+
+<p>Vous pouvez nommer une variable comme vous l'entendez, mais il y a des restrictions. Généralement, il convient de se limiter à l'emploi des caractères latins (0-9, a-z, A-Z)  et du underscore ( _ ).</p>
+
+<ul>
+ <li>N'utilisez pas d'autres caractères ; ils pourraient entraîner des erreurs ou être difficiles à comprendre pour un auditoire international.</li>
+ <li>N'utilisez pas le underscore comme premier caractère d'un nom de variable — cette façon d'opérer est utilisée dans certaines constructions JavaScript pour signer certaines spécificités ; il pourrait y avoir confusion.</li>
+ <li>Ne mettez pas un chiffre en début de nom de variable. Ce n'est pas permis et provoque une erreur.</li>
+ <li>Une convention sûre, nommée <a href="https://en.wikipedia.org/wiki/CamelCase#Variations_and_synonyms">"lower camel case"</a> (dos de chameau), consiste à accoler plusieurs mots en mettant le premier en minuscules les suivants commençant par une majuscule. Dans cet article, nous avons adopté cette convention pour les noms de variables.</li>
+ <li>Prenez des noms de variable intuitifs, décrivant les données que la variable contient. Évitez les noms se limitant à un caractère ou à l'inverse des noms trop longs, trop verbeux.</li>
+ <li>Les variables sont sensibles à la casse — donc <code>myage</code> et <code>myAge</code> correspondent à deux variables différentes.</li>
+ <li>Enfin les <em>mots réservés</em> du langage JavaScript ne peuvent pas être choisis comme nom pour une variable — les mots réservés sont les mots qui font effectivement partie de la syntaxe du JavaScript. Donc, vous ne pouvez pas utiliser des mots comme <code>var</code>, <code>function</code>, <code>let</code> ou <code>for</code> comme noms de variable. Les navigateurs les reconnaîtront en tant qu'éléments de code, et cela déclenchera des erreurs.</li>
+</ul>
+
+<div class="note">
+<p><strong>Note </strong>: Une liste exhaustive des mots réservés est proposée dans la page <a href="/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#Keywords">Lexical grammar — keywords</a>.</p>
+</div>
+
+<p>Exemples de noms corrects :</p>
+
+<pre class="example-good">age
+myAge
+init
+initialColor
+finalOutputValue
+audio1
+audio2</pre>
+
+<p>Exemples de noms incorrects (soit illégal, soit non conforme aux recommandations) :</p>
+
+<pre class="example-bad">1
+a
+_12
+myage
+MYAGE
+var
+document
+skjfndskjfnbdskjfb
+thisisareallylongstupidvariablenameman </pre>
+
+<p>Parmi ces noms, les suivants déclenchent une <code>SyntaxError</code>  :</p>
+
+<pre class="example-invalid">1 //la variable commence par un chiffre
+var //mot réservé
+document //mot réservé
+</pre>
+
+<p>Essayez maintenant de créer quelques variables supplémentaires en tenant compte de ce qui précède.</p>
+
+<h2 id="Types_de_variables">Types de variables</h2>
+
+<p>Plusieurs types de données peuvent être stockés dans des variables. Dans cette section, nous allons les décrire brièvement, puis dans les prochains articles, nous vous en dirons plus.</p>
+
+<p>Jusqu'à présent, nous avons vu les deux types suivants, mais il y en a d'autres.</p>
+
+<h3 id="Nombres">Nombres</h3>
+
+<p>Vous pouvez stocker des nombres dans des variables, soit des nombres entiers comme 30 ou des nombres décimaux comme 2.456 (appelés aussi nombres à virgule flottante). Il n'est pas nécessaire de déclarer le type de la variable dans JavaScript, contrairement à d'autres langages de programmation. Lorsque vous donnez une valeur numérique à une variable, ne la mettez pas entre guillemets.</p>
+
+<pre class="brush: js">var myAge = 17;</pre>
+
+<h3 id="Chaînes">Chaînes</h3>
+
+<p>Les chaînes sont des mots ou des suites de mots. Quand vous stockez dans une variable une valeur chaîne, vous devez la mettre entre guillemets simples ou doubles, sinon JavaScript va tenter de l'interpréter en tant qu'un autre nom de variable.</p>
+
+<pre class="brush: js">var dolphinGoodbye = 'So long and thanks for all the fish';</pre>
+
+<h3 id="Booléens">Booléens</h3>
+
+<p>Les booléens sont des valeurs true/false (vrai/faux) — elles ne peuvent prendre que deux valeurs: <code>true</code> ou <code>false</code>. Elles sont généralement utilisées pour tester une condition, à la suite de laquelle le code est exécuté de manière appropriée. Ainsi, par exemple, un cas simple pourrait être :</p>
+
+<pre class="brush: js">var iAmAlive = true;</pre>
+
+<p>Toutefois, en réalité, un booléen sera plutôt utilisé ainsi :</p>
+
+<pre class="brush: js">var test = 6 &lt; 3;</pre>
+
+<p>Cette expression utilise l'opérateur  « inférieur à » (<code>&lt;</code>) pour tester si 6 est plus petit que 3. Comme vous pouvez vous y attendre, cette expression renverra <code>false</code>, car 6 n'est pas plus petit que 3 ! Vous en apprendrez bien plus à propos de ces opérateurs plus loin dans ce cours.</p>
+
+<h3 id="Tableaux">Tableaux</h3>
+
+<p>Une tableau est un objet unique contenant plusieurs valeurs entre crochets séparées par des virgules. Saisissez les lignes suivantes dans la console :</p>
+
+<pre class="brush: js">var myNameArray = ['Chris', 'Bob', 'Jim'];
+var myNumberArray = [10,15,40];</pre>
+
+<p>Un fois ces tableaux définis, vous pouvez avoir accès à chaque valeur en fonction de leur emplacement dans le tableau. Voyez ces lignes :</p>
+
+<pre class="brush: js">myNameArray[0]; // renverra 'Chris'
+myNumberArray[2]; // renverra 40</pre>
+
+<p>La valeur entre crochets précise l'index correspondant à la position de la valeur que vous souhaitez voir renvoyée. Vous remarquerez que les tableaux en JavaScript sont indexés à partir de zéro : le premier élément a l'index 0.</p>
+
+<p>Vous en apprendrez beaucoup plus au sujet des tableaux dans un article suivant.</p>
+
+<h3 id="Objets">Objets</h3>
+
+<p>En programmation, un objet est une structure de code qui modélise un objet du réel. Vous pouvez avoir un objet simple représentant une place de parking avec sa largeur et sa profondeur ou bien un objet représentant une personne avec comme données son nom, sa taille, son poids, son vernaculaire, comment le contacter, et plus encore.</p>
+
+<p>Entrez la ligne suivant dans la console de votre explorateur :</p>
+
+<pre class="brush: js">var dog = { name : 'Spot', breed : 'Dalmatian' };</pre>
+
+<p>Pour récupérer une information stockée dans un objet, vous pouvez utiliser la syntaxe suivante :</p>
+
+<pre class="brush: js">dog.name</pre>
+
+<p>Nous en resterons là avec les objets pour le moment — vous en saurez plus à leur propos dans un module ultérieur.</p>
+
+<h2 id="Typage_faible">Typage faible</h2>
+
+<p>JavaScript est un « langage faiblement typé », ce qui veut dire que, contrairement à d'autres langages, vous n'êtes pas obligé de préciser quel est le type de donnée que doit contenir une variable (par ex. nombres, chaînes, tableaux, etc).</p>
+
+<p>Par exemple, si vous déclarez une variable et si vous y placez une valeur entre guillemets, le navigateur la traitera comme étant une chaîne :</p>
+
+<pre class="brush: js">var myString = 'Hello';</pre>
+
+<p>Ce sera toujours une chaîne, même si ce sont des nombres, donc soyez prudents :</p>
+
+<pre class="brush: js">var myNumber = '500'; // oops, c'est toujours une chaîne
+typeof(myNumber);
+myNumber = 500; // mieux — maintenant c'est un nombre
+typeof(myNumber);</pre>
+
+<p>Entrez ces quatre lignes dans la console les unes à la suite des autres, et voyez les résultats. Notez l'emploi de la fonction spéciale <code>typeof()</code> — elle renvoie le type de donnée placé dans la variable. À son premier appel, elle renverra <code>string</code>, car à ce stade la variable <code>myNumber</code> contient la chaîne <code>'500'</code>. Observez bien et voyez ce que la fonction renvoie au second appel.</p>
+
+<h2 id="Résumé">Résumé</h2>
+
+<p>Maintenant, nous en savons un peu plus à propos des variables JavaScript, en particulier comment les créer. Dans le prochain article, nous verrons en détail les nombres et comment effectuer les opérations mathématiques élémentaires.</p>
+
+<p>{{PreviousMenuNext("Learn/JavaScript/First_steps/What_went_wrong", "Learn/JavaScript/First_steps/Math", "Learn/JavaScript/First_steps")}}</p>
diff --git a/files/fr/learn/javascript/first_steps/what_is_javascript/index.html b/files/fr/learn/javascript/first_steps/what_is_javascript/index.html
new file mode 100644
index 0000000000..9579a1dec0
--- /dev/null
+++ b/files/fr/learn/javascript/first_steps/what_is_javascript/index.html
@@ -0,0 +1,397 @@
+---
+title: Qu’est-ce que le JavaScript ?
+slug: Learn/JavaScript/First_steps/What_is_JavaScript
+tags:
+ - API
+ - Apprendre
+ - Article
+ - Commentaires
+ - Defer
+ - Débutant
+ - JavaScript
+ - Navigateur
+ - Script
+ - async
+ - inline
+translation_of: Learn/JavaScript/First_steps/What_is_JavaScript
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{NextMenu("Learn/JavaScript/First_steps/A_first_splash", "Learn/JavaScript/First_steps")}}</div>
+
+<p class="summary">Bienvenue dans le cours <em>JavaScript pour débutants</em> sur le MDN. Dans ce premier article nous donnons une description générale de Javascript en présentant le « pourquoi » et le « comment » du JavaScript. L'objectif est que vous compreniez bien son but.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Prérequis :</th>
+ <td>
+ <p>Une culture informatique basique et une compréhension élémentaire de HTML et CSS.</p>
+ </td>
+ </tr>
+ <tr>
+ <th scope="row">Objectif :</th>
+ <td>Se familiariser avec JavaScript, ce qu’il peut faire et comment il s’intègre dans un site web.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Une_définition_générale">Une définition générale</h2>
+
+<p>JavaScript est un langage de programmation qui permet d’implémenter des mécanismes complexes sur une page web. À chaque fois qu’une page web fait plus que simplement afficher du contenu statique — afficher du contenu mis à jour à des temps déterminés, des cartes interactives, des animations 2D/3D, des menus vidéo défilants, etc... — JavaScript a de bonnes chances d’être impliqué. C’est la troisième couche des technologies standards du web, les deux premières (<a href="/en-US/docs/Learn/HTML">HTML</a> et <a href="/en-US/docs/Learn/CSS">CSS</a>) étant couvertes bien plus en détail dans d’autres tutoriels sur MDN.</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/13502/cake.png" style="display: block; margin: 0 auto;"></p>
+
+<ul>
+ <li>{{glossary("HTML")}} est un langage de balises utilisé pour structurer et donner du sens au contenu web. Par exemple : définir des paragraphes, titres et tables de données ou encore intégrer des images ou des vidéos dans une page.</li>
+ <li>{{glossary("CSS")}} est un langage de règles de style utilisé pour mettre en forme le contenu HTML. Par exemple : en modifiant la couleur d’arrière-plan ou les polices, ou en disposant le contenu en plusieurs colonnes.</li>
+ <li>{{glossary("JavaScript")}} est un langage de programmation qui permet de créer du contenu mis à jour de façon dynamique, de contrôler le contenu multimédia, d’animer des images, et tout ce à quoi on peut penser. Bon, peut-être pas tout, mais vous pouvez faire bien des choses avec quelques lignes de JavaScript.</li>
+</ul>
+
+<p>Les trois couches se superposent naturellement. Prenons pour exemple une simple étiquette texte. Les balises HTML lui donnent une structure et un but :</p>
+
+<pre class="brush: html">&lt;p&gt;Player 1: Chris&lt;/p&gt;</pre>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/13422/just-html.png" style="height: 28px; width: 108px;"></p>
+
+<p>Nous pouvons ensuite ajouter du CSS pour rendre cela plus joli :</p>
+
+<pre class="brush: css">p {
+ font-family: 'helvetica neue', helvetica, sans-serif;
+ letter-spacing: 1px;
+ text-transform: uppercase;
+ text-align: center;
+ border: 2px solid rgba(0,0,200,0.6);
+ background: rgba(0,0,200,0.3);
+ color: rgba(0,0,200,0.6);
+ box-shadow: 1px 1px 2px rgba(0,0,200,0.4);
+ border-radius: 10px;
+ padding: 3px 10px;
+ display: inline-block;
+ cursor:pointer;
+}</pre>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/13424/html-and-css.png" style="height: 48px; width: 187px;"></p>
+
+<p>Et enfin utiliser JavaScript pour ajouter un comportement dynamique :</p>
+
+<pre class="brush: js">let para = document.querySelector('p');
+
+para.addEventListener('click', updateName);
+
+function updateName() {
+ let name = prompt('Enter a new name');
+ para.textContent = 'Player 1: ' + name;
+}
+</pre>
+
+<p>{{ EmbedLiveSample('Une_définition_générale', '100%', 80) }}</p>
+
+<p>Essayez de cliquer sur l’étiquette texte pour voir ce qui se passe. Notez que vous pouvez également retrouver cet exemple sur Github — voir le <a href="https://github.com/mdn/learning-area/blob/master/javascript/introduction-to-js-1/what-is-js/javascript-label.html">code source</a>, ou l’<a href="http://mdn.github.io/learning-area/javascript/introduction-to-js-1/what-is-js/javascript-label.html">exécuter</a>.</p>
+
+<p>JavaScript peut faire bien plus. Voyons cela plus en détail.</p>
+
+<h2 id="Que_peut-il_vraiment_faire">Que peut-il <em>vraiment</em> faire ?</h2>
+
+<p>Le cœur de JavaScript est constitué de fonctionnalités communes de programmation permettant de :</p>
+
+<ul>
+ <li>stocker des valeurs utiles dans des variables. Dans l’exemple plus haut, nous demandons un nouveau nom à l’utilisateur puis le stockons dans une variable appelée <code>name</code>.</li>
+ <li>faire des opérations sur des morceaux de texte (appelés en programmation « chaînes de caractères » ou « strings » en anglais). Dans l’exemple plus haut, nous prenons la chaîne de caractères "Player 1: " et lui adjoignons la variable <code>name</code> pour créer l’étiquette ''Player 1: Chris".</li>
+ <li>exécuter du code en réponse à certains événements se produisant sur une page web. Dans l’exemple, nous avons utilisé un événement (« event ») {{Event("click")}} pour détecter quand l’utilisateur clique sur le bouton ; on exécute alors le code qui met à jour l’étiquette.</li>
+ <li>Et bien plus encore !</li>
+</ul>
+
+<p>Là où ça devient excitant, c’est que de nombreuses fonctionnalités sont basées sur ce cœur de JavaScript. Les « interfaces de programmation applicatives » (APIs pour « Application Programming Interfaces ») donnent accès à des quasi-superpouvoirs dans votre code JavaScript.</p>
+
+<p>Les API sont des blocs de code déjà prêts qui permettent à un développeur d'implémenter des programmes qui seraient difficiles voire impossibles à implémenter sans elles. C'est comme du code "en kit" pour la programmation, très pratiques à assembler et à combiner. Les API sont au code ce que les meubles en kits sont aux fournitures de maison — il est beaucoup plus facile de prendre des panneaux prêts à l'emploi et de les visser ensemble pour faire une étagère que de travailler vous-même sur le design, d'aller chercher le bon bois, de couper tous les panneaux à la bonne taille et la bonne forme, de trouver les vis de la bonne taille, puis les assembler pour faire une étagère.</p>
+
+<p>Elles se divisent généralement en deux catégories :</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/13508/browser.png" style="display: block; height: 511px; margin: 0px auto; width: 815px;"></p>
+
+<p><strong>Les APIs de navigateur</strong> font partie intégrante de votre navigateur web, et peuvent accéder à des données de l’environnement informatique (l’ordinateur), ou faire d'autres choses complexes. Par exemple :</p>
+
+<ul>
+ <li>l’<a href="https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model">API DOM (Document Object Model)</a> permet de manipuler du HTML et du CSS (créer, supprimer et modifier du HTML, appliquer de nouveaux styles à la page de façon dynamique, etc...). Chaque fois que vous voyez une fenêtre popup sur une page ou du nouveau contenu apparaître (comme dans notre démonstration plus haut), il s’agit d'une action du DOM.</li>
+ <li>l’<a href="https://developer.mozilla.org/en-US/docs/Web/API/Geolocation">API de géolocalisation</a> récupère des informations géographiques. C’est ainsi que <a href="https://www.google.com/maps">Google Maps</a> peut trouver votre position et la situer sur une carte.</li>
+ <li>les APIs <a href="https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API">Canvas</a> et <a href="https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API">WebGL</a> permettent de créer des animations 2D et 3D. On fait des choses incroyables avec ces technologies, voyez <a href="https://www.chromeexperiments.com/webgl">Chrome Experiments</a> et <a href="http://webglsamples.org/">webglsamples</a>.</li>
+ <li><a href="https://developer.mozilla.org/en-US/Apps/Fundamentals/Audio_and_video_delivery">les APIs Audio et Video</a>, comme {{domxref("HTMLMediaElement")}} et <a href="/en-US/docs/Web/API/WebRTC_API">WebRTC</a> permettent des actions intéressantes sur le multimédia, telles que jouer de l’audio ou de la vidéo directement dans une page web, ou récupérer le flux vidéo de votre webcam et l’afficher sur l’ordinateur de quelqu’un d’autre (essayez la <a href="http://chrisdavidmills.github.io/snapshot/">Snapshot demo </a>pour vous faire une idée).</li>
+</ul>
+
+<div class="note">
+<p><strong>Note</strong> : beaucoup des exemples ci-dessus ne fonctionneront pas dans un ancien navigateur. Il vaut mieux utiliser un navigateur moderne comme Firefox, Chrome, Edge ou Opera pour exécuter votre code et faire vos tests. Si vous êtes amené à écrire du code de production (c’est-à-dire destiné à de véritables utilisateurs), il vous faudra prendre en compte la compatibilité pour différents navigateurs.</p>
+</div>
+
+<p>Les<strong> APIs tierces</strong> ne font par défaut pas partie de votre navigateur, et vous devrez en général récupérer le code et les informations les concernant quelque part sur le web. Par exemple :</p>
+
+<ul>
+ <li>l’<a href="https://dev.twitter.com/overview/documentation">API Twitter</a> vous permet par exemple d'afficher vos derniers tweets sur votre site.</li>
+ <li>l’<a href="https://developers.google.com/maps/">API Google Maps</a> permet d’intégrer à votre site des cartes personnalisées et d’autres fonctionnalités de ce type.</li>
+</ul>
+
+<div class="note">
+<p><strong>Note</strong> : ces APIs sont d’un niveau avancé et nous ne couvrerons aucune d’entre elles dans ce cours, mais les liens ci-dessus fournissent une large documentation si vous voulez en savoir davantage.</p>
+</div>
+
+<p>Et il y a bien plus encore ! Pas de précipitation cependant. Vous ne serez pas en mesure de créer le nouveau Facebook, Google Maps ou Instagram après une journée de travail sur JavaScript, il y a d’abord beaucoup de bases à assimiler. Et c’est pourquoi vous êtes ici. Allons-y !</p>
+
+<h2 id="Que_fait_JavaScript_sur_votre_page">Que fait JavaScript sur votre page ?</h2>
+
+<p>Ici nous allons commencer à réellement nous intéresser au code, et, ce faisant, à explorer ce qui se passe quand vous exécutez du JavaScript dans votre page.</p>
+
+<p>Commençons par un bref récapitulatif de ce qui se passe lorqu'une page web se charge dans le navigateur (voir <a href="/fr/docs/Apprendre/CSS/Introduction_%C3%A0_CSS/Le_fonctionnement_de_CSS#Comment_fonctionnent_vraiment_les_CSS">Comment fonctionnent vraiment les CSS</a>). Quand la page se charge, les codes HTML, CSS et JavaScript s'exécutent dans un environnement (l’onglet du navigateur). C’est un peu comme une usine qui prend des matières premières (le code) et sort un produit (la page web).</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/13504/execution.png" style="display: block; margin: 0 auto;"></p>
+
+<p>Le JavaScript est exécuté par le moteur JavaScript du navigateur, après que le HTML et le CSS ont été assemblés et combinés en une page web. Cet enchaînement est nécessaire pour être sûr que la structure et le style de la page sont déjà en place quand le JavaScript commence son exécution.</p>
+
+<p>C’est une bonne chose, étant donné qu’un usage fréquent de JavaScript est de modifier dynamiquement le HTML et le CSS pour mettre à jour l’interface utilisateur, via l’API DOM comme évoqué plus tôt. Charger le JavaScript et essayer de l’exécuter avant que le HTML et le CSS ne soient en place mènerait à des erreurs.</p>
+
+<h3 id="Sécurité_du_navigateur">Sécurité du navigateur</h3>
+
+<p>Chaque onglet du navigateur constitue un périmètre séparé dans lequel s’exécute le code (en termes techniques ces périmètres sont des « environnements d’exécution ») ce qui signifie que, dans la plupart des cas, le code de chaque onglet est exécuté complètement séparément, et le code d’un onglet ne peut affecter directement le code d’un autre onglet ou d’un autre site. C’est une bonne mesure de sécurité. Si ce n’était pas le cas, des pirates pourraient par exemple écrire du code pour voler des informations sur d’autres sites web.</p>
+
+<div class="note">
+<p><strong>Note</strong> : il existe des moyens d’envoyer du code et des données entre différents sites/onglets de façon sécurisée, mais ce sont des techniques avancées que ne nous couvrirons pas dans ce cours.</p>
+</div>
+
+<h3 id="Ordre_d’exécution_du_JavaScript">Ordre d’exécution du JavaScript</h3>
+
+<p>Quand le navigateur rencontre un bloc de JavaScript, il l’exécute généralement dans l’ordre, de haut en bas. Vous devrez donc faire attention à l’ordre dans lequel vous écrivez les choses. Reprenons le bloc de JavaScript vu dans notre premier exemple :</p>
+
+<pre class="brush: js">let para = document.querySelector('p');
+
+para.addEventListener('click', updateName);
+
+function updateName() {
+ let name = prompt('Enter a new name');
+ para.textContent = 'Player 1: ' + name;
+}</pre>
+
+<p>Nous sélectionnons ici un paragraphe de texte (ligne 1), puis lui attachons un «écouteur d'évènement»  (event listener)  ligne 3, pour qu'ensuite, lors d’un clic sur le paragraphe, le bloc de code <code>updateName()</code> (lignes 5-8) s’exécute. Le bloc de code <code>updateName()</code> (ces blocs de code réutilisables sont appelés « fonctions ») demande à l’utilisateur un nouveau nom, et l’insère dans le paragraphe pour mettre à jour l’affichage.</p>
+
+<p>Si vous échangiez les deux premières lignes de code, rien ne fonctionnerait plus, vous obtiendriez une erreur dans la console développeur du navigateur : <code>TypeError: para is undefined</code>. Cela signifie que l’objet <code>para</code> n’existe pas encore, donc nous ne pouvons pas y ajouter d’écouteur d'évènement.</p>
+
+<div class="note">
+<p><strong>Note </strong>: c’est une erreur très fréquente. Il faut veiller à ce que les objets référencés dans votre code existent avant d'essayer de les utiliser.</p>
+</div>
+
+<h3 id="Code_interprété_contre_code_compilé">Code interprété contre code compilé</h3>
+
+<p>En informatique, on parle de code <strong>interprété</strong> ou <strong>compilé</strong>. JavaScript est un langage interprété : le code est exécuté de haut en bas et le résultat du code exécuté est envoyé immédiatement. Vous n’avez pas à transformer le code en une autre forme avant que le navigateur ne l’exécute.</p>
+
+<p>Les langages compilés quant à eux sont transformés (compilés) en une autre forme avant d’être exécutés par l’ordinateur. Par exemple le C et le C++ sont compilés en langage assembleur qui est ensuite exécuté par l’ordinateur.</p>
+
+<p>Chaque approche a ses avantages, ce que nous ne développerons pas pour l’instant.</p>
+
+<h3 id="Code_côté_client_contre_côté_serveur">Code côté client contre côté serveur</h3>
+
+<p>Vous pouvez aussi rencontrer les termes de code <strong>côté serveur</strong> et <strong>côté client</strong>, notamment dans le contexte du développement web. Le code <strong>côté client</strong> est du code exécuté sur l’ordinateur de l’utilisateur : quand une page web est vue, le code côté client de la page est téléchargé, puis exécuté et affiché par le navigateur. Dans ce module JavaScript, nous parlons explicitement de <strong>JavaScript côté client</strong>.</p>
+
+<p>Le code <strong>côté serveur</strong> quant à lui est exécuté sur le serveur, puis ses résultats sont téléchargés et affichés par le navigateur. Citons comme langages web côté serveur populaires le PHP, Python, Ruby, et ASP.NET. Et JavaScript ! JavaScript peut aussi s’utiliser comme un langage <strong>côté serveur</strong>, par exemple dans le populaire environnement Node.js — vous pouvez en apprendre plus sur le JavaScript côté serveur dans notre article<a href="/fr/docs/Learn/Server-side"> Programmation de Sites Web côté serveur</a>.</p>
+
+<h3 id="Code_dynamique_contre_code_statique">Code dynamique contre code statique</h3>
+
+<p>Le mot <strong>dynamique</strong> est utilisé tant pour qualifier le JavaScript côté client que les langages côté serveur. Il se réfère à la capacité de mettre à jour l’affichage d’une page/application web pour montrer des choses différentes en des circonstances différentes, en générant un nouveau contenu quand nécessaire. Le code côté serveur génère dynamiquement du nouveau contenu sur le serveur, par exemple en lisant une base de données, tandis que le JavaScript côté client peut générer dynamiquement un contenu nouveau dans le navigateur, par exemple en créant une nouvelle table HTML, en y insérant les données demandées au serveur, puis en affichant la table dans une page web. Selon le contexte, le terme <em>dynamique</em> prend un sens un peu différent, mais les deux sont très liés, et les deux approches (côté serveur et client) vont souvent de pair.</p>
+
+<p>Une page web sans contenu mis à jour dynamiquement est appelé <strong>statique</strong> : elle montre simplement toujours le même contenu.</p>
+
+<h2 id="Comment_ajouter_du_JavaScript_à_votre_page">Comment ajouter du JavaScript à votre page ?</h2>
+
+<p>Le JavaScript est appliqué à votre page HTML un peu comme le CSS. Les éléments {{htmlelement("link")}} permettent d'appliquer des feuilles de style externes au HTML, les feuilles de styles internes utilisent les éléments {{htmlelement("link")}}. Pour ajouter du JavaScript à un document HTML il y a une seule façon, avec l’élément {{htmlelement("script")}}. Voyons cela sur un exemple.</p>
+
+<h3 id="JavaScript_interne">JavaScript interne</h3>
+
+<ol>
+ <li>Faites d’abord une copie locale de notre fichier d’exemple <a href="https://github.com/mdn/learning-area/blob/master/javascript/introduction-to-js-1/what-is-js/apply-javascript.html">apply-javascript.html</a>. Enregistrez-le dans un répertoire approprié.</li>
+ <li>Ouvrez le fichier dans votre navigateur web et dans un éditeur de texte. Vous verrez que le HTML crée une page web simple contenant un bouton cliquable.</li>
+ <li>Ensuite, allez dans votre éditeur de texte et ajoutez ce qui suit juste avant la balise fermante <code>&lt;/head&gt;</code> :
+ <pre class="brush: html">&lt;script&gt;
+
+ // JavaScript goes here
+
+&lt;/script&gt;</pre>
+ </li>
+ <li>Ajoutons maintenant du JavaScript dans notre élément {{htmlelement("script")}} pour rendre la page plus dynamique. Ajoutez le code suivant juste en-dessous de la ligne "// JavaScript goes here" :
+ <pre class="brush: js"> document.addEventListener("DOMContentLoaded", function() {
+ function createParagraph() {
+ let para = document.createElement('p');
+ para.textContent = 'Vous avez cliqué sur le bouton!';
+ document.body.appendChild(para);
+ }
+
+ const buttons = document.querySelectorAll('button');
+
+ for(let i = 0; i &lt; buttons.length ; i++) {
+ buttons[i].addEventListener('click', createParagraph);
+ }
+});</pre>
+ </li>
+ <li>Enregistrez le fichier et actualisez le navigateur. Vous pouvez maintenant voir que, lorsque vous cliquez sur le bouton, un nouveau paragraphe est généré et placé en-dessous.</li>
+</ol>
+
+<div class="note">
+<p><strong>Note</strong> : si l’exemple ne semble pas marcher, reprenez pas à pas chaque étape. Avez-vous bien enregistré le code de départ comme un fichier <code>.html</code> ? Avez-vous bien ajouté l’élément {{htmlelement("script")}} juste après la balise <code>&lt;/head&gt;</code> ? Avez-vous collé le bon code JavaScript au bon endroit ? <strong>JavaScript est sensible à la casse, et assez tatillon, il faut donc respecter scrupuleusement la syntaxe indiquée, sans quoi il peut ne pas fonctionner.</strong></p>
+</div>
+
+<div class="note">
+<p><strong>Note </strong>: vous pouvez voir cette version sur GitHub avec <a href="https://github.com/mdn/learning-area/blob/master/javascript/introduction-to-js-1/what-is-js/apply-javascript-internal.html">apply-javascript-internal.html</a> (<a href="http://mdn.github.io/learning-area/javascript/introduction-to-js-1/what-is-js/apply-javascript-internal.html">et aussi en live</a>).</p>
+</div>
+
+<h3 id="JavaScript_externe">JavaScript externe</h3>
+
+<p>Ça marche très bien, mais si nous voulons mettre notre JavaScript dans un fichier externe ? Voyons cela.</p>
+
+<ol>
+ <li>Créez d’abord un nouveau fichier dans le même répertoire que votre fichier HTML. Nommez-le <code>script.js</code> (vérifiez qu’il a bien l’extension de fichier .js, c’est ainsi qu’il est identifié comme fichier JavaScript).</li>
+ <li>Ensuite, copiez-collez tout le script contenu dans l’élément {{htmlelement("script")}} vers le fichier .js, et enregistrez le fichier.</li>
+ <li>À présent remplacez l’élément {{htmlelement("script")}} par :
+ <pre class="brush: html">&lt;script src="script.js" defer&gt;&lt;/script&gt;</pre>
+ </li>
+ <li>Enregistrez et rechargez la page dans votre navigateur, et vous devriez voir la même chose qu’avant. C’est la même chose mais nous avons maintenant le JavaScript dans un fichier externe. C’est une bonne chose en général pour organiser le code et le rendre réutilisable pour plusieurs fichiers HTML. Cela rend aussi le code HTML plus lisible en évitant d’y inclure de gros blocs de Javascript.</li>
+</ol>
+
+<p><strong>Note</strong> : vous pouvez voir cette version sur GitHub avec <a href="https://github.com/mdn/learning-area/blob/master/javascript/introduction-to-js-1/what-is-js/apply-javascript-external.html">apply-javascript-external.html</a> et <a href="https://github.com/mdn/learning-area/blob/master/javascript/introduction-to-js-1/what-is-js/script.js">script.js</a> (<a href="http://mdn.github.io/learning-area/javascript/introduction-to-js-1/what-is-js/apply-javascript-external.html">ainsi qu’en live</a>).</p>
+
+<h3 id="Handlers_JavaScript_en_ligne">Handlers JavaScript en ligne</h3>
+
+<p>Notez que parfois vous tomberez sur des morceaux de JavaScript directement dans le HTML. Ce qui peut ressembler à ça :</p>
+
+<div id="inline_js_example">
+<pre class="brush: js example-bad">function createParagraph() {
+ let para = document.createElement('p');
+ para.textContent = 'Vous avez cliqué !';
+ document.body.appendChild(para);
+}</pre>
+
+<pre class="brush: html example-bad">&lt;button onclick="createParagraph()"&gt;Cliquez-moi!&lt;/button&gt;</pre>
+</div>
+
+<p>Vous pouvez essayer cette version dans la démonstration ci-dessous.</p>
+
+<p>{{ EmbedLiveSample('inline_js_example', '100%', 150) }}</p>
+
+<p>Cet exemple a exactement le même comportement que ceux des deux sections précédentes, sauf que l’élément {{htmlelement("button")}} a un handler <code>onclick</code> en ligne pour déclencher l’exécution de la fonction à la pression du bouton.</p>
+
+<p><strong>Évitez cependant de faire cela.</strong> C’est une mauvaise habitude de polluer le HTML avec du JavaScript, en plus d’être inefficace. Dans cette méthode, on doit inclure l’attribut <code>onclick="createParagraph()"</code> sur chaque bouton où le JavaScript doit s’appliquer.</p>
+
+<p>Une construction en JavaScript pur permet de sélectionner tous les boutons avec une instruction. Dans l'exemple précédent c'est cette partie qui s'en charge :</p>
+
+<pre class="brush: js">let buttons = document.querySelectorAll('button');
+
+for(let i = 0; i &lt; buttons.length ; i++) {
+ buttons[i].addEventListener('click', createParagraph);
+}</pre>
+
+<p>Cela peut sembler un peu plus long que l’attribut <code>onclick</code>, mais cela fonctionnera pour tous les boutons peu importe leur nombre sur la page, et peu importe si des boutons sont ajoutés ou retirés, le code JavaScript n’aura pas besoin d’être modifié.</p>
+
+<div class="note">
+<p><strong>Note  </strong>: essayez de modifier votre version de <code>apply-javascript.html</code> et d’y ajouter quelques boutons dans le fichier. En actualisant la page, tous les boutons devraient créer un paragraphe quand ils sont cliqués. Pas mal, non ?</p>
+</div>
+
+<h3 id="Stratégies_de_chargement_de_script">Stratégies de chargement de script</h3>
+
+<p>Le chargement des scripts au bon moment pose un certain nombre de problèmes. Rien n'est aussi simple qu'il y paraît ! Un problème courant est que le code HTML d’une page se charge en suivant l’ordre d'apparition dans le code source. Si vous utilisez JavaScript pour manipuler des éléments sur la page (plus précisément, le <a href="https://developer.mozilla.org/fr/docs/Web/API/Document_Object_Model">DOM</a>), votre code ne fonctionnera pas si le JavaScript est chargé et analysé avant le code HTML sur lequel vous voulez opérer.</p>
+
+<p>Dans les exemples de code interne et externe ci-dessus, le JavaScript est chargé et exécuté dans l'en-tête du document, avant que le corps soit analysé. Cela peut causer une erreur, donc nous avons utilisé des structures pour le contourner.</p>
+
+<p>Dans l'exemple interne, vous pouvez voir cette structure autour du code :</p>
+
+<pre class="brush: js line-numbers language-js"> document.addEventListener("DOMContentLoaded", function() {
+ ...
+ });</pre>
+
+<p>Il s'agit d'un écouteur associé à l'événement <code>DOMContentLoaded</code> du navigateur, cet événement est déclenché quand le <code>body</code> HTML est complètement chargé et analysé. Le code JavaScript à l'intérieur du bloc est exécuté après le déclenchement de <code>DOMContentLoaded</code>. Par conséquent, l'erreur est évitée (vous en apprendrez plus sur les <a href="https://developer.mozilla.org/fr/docs/Apprendre/JavaScript/Building_blocks/Ev%C3%A8nements">événements</a> plus tard dans le cours).</p>
+
+<p>Dans l'exemple externe, nous utilisons une fonctionnalité JavaScript plus moderne pour résoudre le problème, l'attribut <code>async</code>, qui indique au navigateur de continuer à télécharger le contenu HTML une fois que l'élément de balise {{htmlelement("script")}} a été atteint.</p>
+
+<pre class="brush: html">&lt; script src = "script.js" async &gt; &lt; / script &gt;</pre>
+
+<p>Dans ce cas, le script et le code HTML se chargeront simultanément et le code fonctionnera.</p>
+
+<div class="note">
+<p><strong>Note </strong>: Dans le cas externe, nous n'avions pas besoin d'utiliser l'événement <code>DOMContentLoaded</code> car l'attribut <code>async</code> a résolu le problème pour nous. Nous n'avons pas utilisé la solution <code>async</code> pour l'exemple JavaScript interne, car elle ne fonctionne que pour les scripts externes.</p>
+</div>
+
+<p>Auparavant, une solution à ce problème consistait à placer votre élément de script juste au bas du corps (par exemple, juste avant la balise), afin qu'il soit chargé après que tout le code HTML a été analysé. Le problème de cette solution (et de la solution <code>DOMContentLoaded</code> vue ci-dessus) est que le chargement et l'analyse du script sont complètements bloqués jusqu'à ce que le DOM HTML soit chargé. Sur des sites plus importants avec beaucoup de JavaScript, cela peut entraîner un problème de performances majeur, ce qui ralentit votre site. C'est pourquoi <code>async</code> a été ajouté aux navigateurs !</p>
+
+<h4 id="async_et_defer">async et defer</h4>
+
+<p>En fait, il existe deux façons de contourner le problème du script de blocage : <code>async</code> et <code>defer</code>. Regardons la différence entre les deux.</p>
+
+<p>Les scripts asynchrones téléchargeront le script sans bloquer le rendu de la page et l'exécuteront dès que le téléchargement du script sera terminé. Vous n'obtenez aucune garantie que les scripts s'exécutent dans un ordre spécifique, mais seulement qu'ils n'empêcheront pas le reste de la page de s'afficher. Il est préférable d'utiliser <code>async</code> lorsque les scripts de la page s'exécutent indépendamment les uns des autres et ne dépendent d'aucun autre script de la page.</p>
+
+<p>Par exemple, si vous avez les éléments de script suivants :</p>
+
+<pre class="brush: html line-numbers language-html"><code class="language-html"> &lt; script async src = " js/vendor/jquery.js " &gt; &lt;/ script &gt;
+
+ &lt; script async src = " js/script2.js " &gt; &lt;/ script &gt;
+
+ &lt; script async src = " js/script3.js " &gt; &lt;/ script &gt; </code></pre>
+
+<p>Vous ne pouvez pas compter sur l'ordre dans lequel les scripts seront chargés. <code>Jquery.js</code> peut être chargé avant ou après <code>script2.js</code> et <code>script3.js</code>. Si tel est le cas, toute fonction de ces scripts dépendant de <code>jquery</code> générera une erreur, car <code>jquery</code> ne sera pas défini au moment de l'exécution du script.</p>
+
+<p><code>defer</code> exécute les scripts dans l'ordre dans lequel ils apparaissent dans la page et les exécute dès que le script et le contenu sont téléchargés :</p>
+
+<pre class="brush: html line-numbers language-html"><code class="language-html"> &lt; script defer src = " js/vendor/jquery.js " &gt; &lt;/ script &gt;
+
+ &lt; script defer src = " js/script2.js " &gt; &lt;/ script &gt;
+
+ &lt; script defer src = " js/script3.js " &gt; &lt;/ script &gt; </code></pre>
+
+<p>Tous les scripts dotés de l'attribut de <code>defer</code> seront chargés dans l'ordre dans lequel ils apparaissent sur la page. Ainsi, dans le deuxième exemple, nous pouvons être sûrs que <code>jquery.js</code> se chargera avant <code>script2.js</code> et <code>script3.js</code> et que <code>script2.js</code> se chargera avant <code>script3.js</code>.</p>
+
+<p>Pour résumer :</p>
+
+<ul>
+ <li>Si vos scripts n'ont pas besoin d'attendre l'analyse et peuvent s'exécuter indépendamment sans dépendances, utilisez <code>async</code>.</li>
+ <li>Si vos scripts doivent attendre l'analyse et dépendent d'autres scripts, chargez-les à l'aide de <code>defer</code> et placez leurs éléments {{htmlelement("script")}} correspondants dans l'ordre dans lequel vous souhaitez que le navigateur les exécute.</li>
+</ul>
+
+<h2 id="Commentaires">Commentaires</h2>
+
+<p>Comme pour le HTML et le CSS, il est possible d’écrire des commentaires dans le code JavaScript qui seront ignorés par le navigateur. Ils ne sont là que pour apporter des précisions aux autres développeurs sur le fonctionnement du code (et vous-même, si vous reprenez votre code après six mois sans pouvoir vous rappeler ce que vous avez fait). Les commentaires sont très utiles, et vous devriez les utiliser fréquemment, surtout pour des applications de grande taille. Il y en a deux types :</p>
+
+<ul>
+ <li>Un commentaire sur une ligne s’écrit après un double slash, par exemple :
+ <pre class="brush: js">// Ceci est un commentaire</pre>
+ </li>
+ <li>Un commentaire sur plusieurs lignes s’écrit entre deux balises /* et */, par exemple :
+ <pre class="brush: js">/*
+ Ceci est un commentaire
+ sur deux lignes
+*/</pre>
+ </li>
+</ul>
+
+<p>Ainsi, vous pourriez par exemple annoter notre dernière démonstration de JavaScript de cette manière :</p>
+
+<pre class="brush: js">// Fonction: créer un nouveau paragraphe et l'ajouter en bas du HTML
+
+function createParagraph() {
+ let para = document.createElement('p');
+ para.textContent = 'You clicked the button!';
+ document.body.appendChild(para);
+}
+
+/*
+ 1. Regrouper les coordonnées de tous les boutons de la page et les organiser en tableau
+ 2. Faire une boucle dans ce tableau et ajouter un "click event listener" à chaque bouton
+
+ Quand le bouton est cliqué, la fonction "createParagraph()" sera exécutée
+*/
+
+let buttons = document.querySelectorAll('button');
+
+for(let i = 0; i &lt; buttons.length ; i++) {
+ buttons[i].addEventListener('click', createParagraph);
+}</pre>
+
+<h2 id="Résumé">Résumé</h2>
+
+<p>Et voilà votre premier pas dans le monde du JavaScript. Nous avons commencé par la théorie seule, pour vous habituer aux raisons d’utiliser JavaScript, et à ses possibilités. Vous avez pu voir quelques exemples de code et appris comment JavaScript s’intègre avec le reste du code sur votre site web, entre autres choses.</p>
+
+<p>Le JavaScript peut sembler un peu impressionnant pour l’instant, mais pas d’inquiétude, ce cours progressera pas à pas. Dans le prochain article <a href="/fr/docs/Learn/JavaScript/First_steps/A_first_splash">Notre premier code Javascript,</a> nous entrons au cœur du sujet et vous réaliserez vos propres exemples de JavaScript.</p>
+
+<p>{{NextMenu("Learn/JavaScript/First_steps/A_first_splash", "Learn/JavaScript/First_steps")}}</p>
diff --git a/files/fr/learn/javascript/first_steps/what_went_wrong/index.html b/files/fr/learn/javascript/first_steps/what_went_wrong/index.html
new file mode 100644
index 0000000000..004d4a67a7
--- /dev/null
+++ b/files/fr/learn/javascript/first_steps/what_went_wrong/index.html
@@ -0,0 +1,254 @@
+---
+title: Qu'est-ce qui n'a pas fonctionné ? Déboguer du code JavaScript
+slug: Learn/JavaScript/First_steps/What_went_wrong
+tags:
+ - Apprentissage
+ - Article
+ - Codage
+ - Débutant
+ - Erreur
+ - JavaScript
+ - Tutoriel
+ - console.log
+ - débogage
+ - outils de développement
+translation_of: Learn/JavaScript/First_steps/What_went_wrong
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/JavaScript/First_steps/A_first_splash", "Learn/JavaScript/First_steps/Variables", "Learn/JavaScript/First_steps")}}</div>
+
+<p class="summary">Après avoir créé le jeu "Devinez le nombre" de l'article précédent, vous avez peut-être constaté qu'il ne fonctionnait pas. Pas de panique — cet article vise à ce que vous ne vous arrachiez pas les cheveux sur ces problèmes en donnant quelques conseils simples sur la façon de trouver et corriger les erreurs dans les programmes JavaScript.</p>
+
+<table class="learn-box standard-table" style="height: 148px; width: 672px;">
+ <tbody>
+ <tr>
+ <th scope="row">Prérequis :</th>
+ <td>
+ <p>Vocabulaire courant de l'informatique, bases de HTML et CSS, compréhension de ce que fait JavaScript.</p>
+ </td>
+ </tr>
+ <tr>
+ <th scope="row">Objectif :</th>
+ <td>Acquérir la capacité et la confiance pour commencer à résoudre des problèmes simples dans votre propre code.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Types_d_erreurs">Types d' erreurs</h2>
+
+<p>En règle générale, les erreurs dans un code sont à ranger dans deux catégories :</p>
+
+<ul>
+ <li><strong>Erreurs de syntaxe : </strong>Ce sont les fautes d'orthographe. Elles empêchent réellement le programme de fonctionner ou l'arrêtent en cours de chemin — elles sont accompagnées de messages d'erreur. Ces erreurs sont généralement simple à corriger, pour autant que vous connaissiez les bons outils et sachiez ce que signifient les messages !</li>
+ <li>
+ <p><strong>Erreurs logiques : </strong>La syntaxe est correcte, mais le code n'est pas ce que vous attendiez : le programme tourne sans planter mais donne des résultats inattendus. Ces erreurs sont souvent plus difficiles à corriger que les erreurs de syntaxe, car il n'y a pas, en général, de message d'erreur pour vous diriger vers la source de l'erreur.</p>
+ </li>
+</ul>
+
+<p>Bon, mais ce n'est pas si simple que cela — il y a d'autres facteurs de différenciation lorsque vous approfondissez. Mais la classification ci-dessus suffiira pour commencer. Nous examinerons ces deux catégories d'erreur un peu plus loin.</p>
+
+<h2 id="Un_exemple_erroné">Un exemple erroné</h2>
+
+<p>Pour commencer, revenons à notre jeu de devinettes numériques — sauf que cette fois-ci, nous explorerons une version qui comporte des erreurs délibérées. Allez sur Github et fabriquez vous-même une copie locale de <a href="https://github.com/mdn/learning-area/blob/master/javascript/introduction-to-js-1/troubleshooting/number-game-errors.html">number-game-errors.html</a> (<a href="https://mdn.github.io/learning-area/javascript/introduction-to-js-1/troubleshooting/number-game-errors.html">voyez-la ici</a> en direct).</p>
+
+<ol>
+ <li>Pour commencer, ouvrez la copie locale avec votre éditeur de texte favoris.</li>
+ <li>Essayez de lancer le jeu — vous remarquerez que quand vous pressez le bouton <kbd>Submit guess</kbd>, cela ne fonctionne pas!</li>
+</ol>
+
+<div class="note">
+<p><strong>Note </strong>: Votre propre version de l'exemple de jeu ne fonctionne pas, vous pourriez vouloir la corriger ! Il nous semble plus efficace que vous travailliez sur notre version boguée, afin que vous puissiez apprendre les techniques que nous enseignons ici. Ensuite, vous pouvez revenir en arrière et essayer de réparer votre exemple.</p>
+</div>
+
+<p>À ce stade, consultons la <a href="/fr/docs/Apprendre/Découvrir_outils_développement_navigateurs">console du développeur</a> pour voir si nous pouvons voir des erreurs de syntaxe, puis essayez de les corriger. Vous apprendrez comment ci-dessous.</p>
+
+<h2 id="Réparer_les_erreurs_de_syntaxe">Réparer les erreurs de syntaxe</h2>
+
+<p>Antérieurement dans le cours, nous vous avons demandé de taper quelques commandes JavaScript simples dans la <a href="/fr/docs/Apprendre/Découvrir_outils_développement_navigateurs">console JavaScript</a> <a href="/fr/docs/Apprendre/Découvrir_outils_développement_navigateurs">des outils de développement</a> (si vous ne pouvez pas vous rappeler comment l'ouvrir dans votre navigateur, suivez le lien précédent pour savoir comment). Ce qui est encore plus utile, c'est que la console vous donne des messages d'erreur chaque fois qu'une erreur de syntaxe existe dans le JavaScript qui est introduit dans le moteur JavaScript du navigateur. Maintenant partons en chasse !</p>
+
+<ol>
+ <li>Allez à l'onglet dans lequel est affiché <code>number-game-errors.html</code>, et ouvrez la console  JavaScript. Vous devriez voir un message d'erreur dans les lignes qui suivent : <img alt="" src="https://mdn.mozillademos.org/files/13496/not-a-function.png" style="display: block; margin: 0 auto;"></li>
+ <li>C'est une erreur très facile à trouver, et le navigateur vous fournit quelques indices pour vous en sortir (la copie d'écran ci‑dessus provient de Firefox, mais les autres navigateurs donnent des indications semblables). De gauche à droite, nous avons :
+ <ul>
+ <li>Une croix rouge indiquant que c'est une erreur.</li>
+ <li>Un message d'erreur précisant ce qui ne va pas : "TypeError: guessSubmit.addeventListener is not a function" ("Type d'erreur : guessSubmit.addeventListener n'est pas une fonction")</li>
+ <li>Un lien "Learn More" ("En savoir plus") pointant sur une page MDN explicitant ce que l'erreur signifie avec pléthore de détails.</li>
+ <li>Le nom du fichier JavaScript, lié à l'onglet Debugger de l'outil de développement. Si vous suivez le lien, vous verrez exactement la ligne dans laquelle l'erreur est mise en évidence.</li>
+ <li>Le numéro de la ligne où se situe l'erreur, et le rang du caractère dans cette ligne où l'erreur a été repérée pour la première fois. Dans notre cas, il s'agit de la ligne 86, caractère 3.</li>
+ </ul>
+ </li>
+ <li>En examinant la ligne 86 dans l'éditeur de code, nous voyons :
+ <pre class="brush: js">guessSubmit.addeventListener('click', checkGuess);</pre>
+ </li>
+ <li>Le message d'erreur dit "guessSubmit.addeventListener n'est pas une fonction", donc nous avons probablement mal orthographié quelque chose. Si vous n'êtes pas sûr de la bonne orthographe d'un élément syntaxique, il est fréquemment opportun de regarder dans MDN. Actuellement, la meilleure façon d'opérer consiste à faire une recherche pour  "mdn <em>nom-de-fonctionnalité</em>" avec votre moteur de recherche préféré. Voici un raccourci pour gagner un peu de temps dans le cas présent : <code><a href="/en-US/docs/Web/API/EventTarget/addEventListener">addEventListener()</a></code>.</li>
+ <li>Donc, en regardant cette page, il apparaît que nous avions mal orthographié le nom de la fonction ! Souvenez-vous que JavaScript est sensible à la casse, et que la moindre différence dans l'orthographe ou la casse déclenchera une erreur. Remplacer <code>addeventListener</code> par <code>addEventListener</code> corrigera cela. Faisons‑le maintenant.</li>
+</ol>
+
+<div class="note">
+<p><strong>Note</strong> : Voyez la page relative à <a href="/en-US/docs/Web/JavaScript/Reference/Errors/Not_a_function">TypeError: "x" is not a function</a> pour plus de précisions à propos de cette erreur.</p>
+</div>
+
+<h3 id="Erreurs_de_syntaxe_deuxième_tour">Erreurs de syntaxe : deuxième tour</h3>
+
+<ol>
+ <li>Enregistrez la page et actualisez‑la, vous constaterez que l'erreur a disparu.</li>
+ <li>Maintenant si vous entrez une supposition et pressez le bouton de soumission, vous constaterez ... une autre erreur ! <img alt="" src="https://mdn.mozillademos.org/files/13498/variable-is-null.png" style="display: block; margin: 0 auto;"></li>
+ <li>Cette fois‑ci, l'erreur rapportée est "TypeError: lowOrHi is null", à la ligne 78.
+ <div class="note"><strong>Note</strong> : <code><a href="/en-US/docs/Glossary/Null">Null</a></code> est une valeur spéciale signifiant "rien" ou "aucune valeur". Or <code>lowOrHi</code> a été déclaré et initialisé, mais sans valeur signifiante — il n'a ni type ni valeur.</div>
+
+ <div class="note"><strong>Note </strong>: Cette erreur n'apparaît pas au moment du chargement de la page car elle survient à l'intérieur d'une fonction (dans <code>checkGuess() { ... }</code>). Comme vous l'apprendrez de manière plus précise plus loin dans l'article à propos des fonctions, le code dans les fonctions s'exécute dans une instance séparée du code en dehors des fonctions. Dans notre cas, le code n'avait pas été exécuté et l'erreur ne pouvait pas survenir avant que la fonction <code>checkGuess()</code> soit lancée à la ligne 86.</div>
+ </li>
+ <li>Regardez à la ligne 78, vous verrez ce code :
+ <pre class="brush: js">lowOrHi.textContent = 'Last guess was too high!';</pre>
+ </li>
+ <li>La commande dans cette ligne essaie de définir la propriété <code>textContent</code> de la variable <code>lowOrHi</code> à l'aide d'une chaîne textuelle ; mais cela ne fonctionne pas car <code>lowOrHi</code> ne contient pas ce qui est attendu. Voyons voir — recherchons d'autres occurrences de <code>lowOrHi</code> dans le code. La plus proche que vous trouverez dans le JavaScript se situe à la ligne 48 :
+ <pre class="brush: js">let lowOrHi = document.querySelector('lowOrHi');</pre>
+ </li>
+ <li>Là, nous essayons de faire en sorte que la variable contienne une référence à un élément dans le HTML du document. Vérifions si sa valeur est <code>null</code> après que cette ligne ait été exécutée. Ajoutez le code suivant à la ligne 49 :
+ <pre class="brush: js">console.log(lowOrHi);</pre>
+
+ <div class="note">
+ <p><strong>Note </strong>: <code><a href="/en-US/docs/Web/API/Console/log">console.log()</a></code> est vraiment utile pour déboguer une fonction en affichant sa valeur sur la console. Donc, elle affichera sur cette dernière la valeur de <code>lowOrHi</code> que nous avons essayé de définir à la ligne 48.</p>
+ </div>
+ </li>
+ <li>Enregistrez et actualisez la page, et vous verrez le résultat de <code>console.log()</code> sur la console. <img alt="" src="https://mdn.mozillademos.org/files/13494/console-log-output.png" style="display: block; margin: 0 auto;"> C'est sûr, la valeur de <code>lowOrHi</code> est <code>null</code> à ce niveau ; il y a bien un problème à la ligne 48.</li>
+ <li>Quel est ce problème ? Réfléchissons. À la ligne 48, nous avons utilisé la méthode <code><a href="/en-US/docs/Web/API/Document/querySelector">document.querySelector()</a></code> pour obtenir une référence sur un élément avec un sélecteur CSS. En regardant plus en amont dans notre fichier, nous pouvons trouver le paragraphe en question :
+ <pre class="brush: js">&lt;p class="lowOrHi"&gt;&lt;/p&gt;</pre>
+ </li>
+ <li>Donc, il nous faut un sélecteur de classe ici, précédé d'un point (.), alors que le sélecteur passé à la méthode <code>querySelector()</code> en ligne 48 n'en a pas. Ce pourrait être le problème ! Changeons <code>lowOrHi</code> en <code>.lowOrHi</code> à la ligne 48.</li>
+ <li>Enregistrons et actualisons à nouveau, et la directive <code>console.log()</code> renvoie bien l'élément  <code>&lt;p&gt;</code> attendu. Pfff ! Une autre erreur corrigée ! On peut enlever la ligne <code>console.log()</code> maintenant, ou bien la garder pour s'y reporter plus tard — comme vous l'entendez.</li>
+</ol>
+
+<div class="note">
+<p><strong>Note</strong> : Voyez la page relative à <a href="/en-US/docs/Web/JavaScript/Reference/Errors/Unexpected_type">TypeError: "x" is (not) "y"</a> pour plus de précisions à propos de cette erreur.</p>
+</div>
+
+<h3 id="Erreurs_de_syntaxe_troisième_tour">Erreurs de syntaxe : troisième tour</h3>
+
+<ol>
+ <li>Maintenant si vous essayez de jouer, cela ira mieux — tout se déroule correctement, jusqu'à ce que vous arriviez à la fin, soit en devinant le bon chiffre, soit en épuisant le nombre de tentatives permises.</li>
+ <li>Arrivé là, le jeu échoue à nouveau et vous rencontrez la même erreur qu'au début — "TypeError: resetButton.addeventListener is not a function" ! Mais cette fois‑ci, elle vient de la ligne  94.</li>
+ <li>En regardant cette ligne, il est facile de voir que nous avons fait ici la même erreur que précédemment. Il nous suffit de changer <code>addeventListener</code> en <code>addEventListener</code>. Faites‑le.</li>
+</ol>
+
+<h2 id="Une_erreur_de_logique">Une erreur de logique</h2>
+
+<p>À ce stade, le jeu se déroule correctement, mais après avoir fait quelques parties, vous noterez sans doute que le nombre « aléatoire » à deviner est toujours 0 ou 1. Franchement, de quoi vous dégoûter de jouer !</p>
+
+<p>Il y a sûrement un problème dans la logique du jeu quelque part — le jeu ne renvoie pas d'erreur ; il ne fonctionne pas correctement.</p>
+
+<ol>
+ <li>Recherchons les lignes où la variable <code>randomNumber</code> est définie. L'instance qui stocke en début de jeu le nombre aléatoire à deviner se situe autour de la ligne 44 :
+
+ <pre class="brush: js">let randomNumber = Math.floor(Math.random()) + 1;</pre>
+ Et celle qui génére le nombre aléatoire pour une succession de jeux se situe autour de la ligne 113 :
+
+ <pre class="brush: js">randomNumber = Math.floor(Math.random()) + 1;</pre>
+ </li>
+ <li>Pour vérifier si ces lignes sont vraiment à l'origine du problème, faisons appel à nouveau à notre ami <code>console.log()</code> — insérons la ligne suivante directement en dessous des deux lignes indiquées plus haut :
+ <pre class="brush: js">console.log(randomNumber);</pre>
+ </li>
+ <li>Enregistrons, actualisons et jouons quelques parties — on constate que <code>randomNumber</code> est égal à 1 quel que soit le point où il est raccordé à la console.</li>
+</ol>
+
+<h3 id="Travaillons_la_logique">Travaillons la logique</h3>
+
+<p>Pour corriger cela, examinons d'abord le fonctionnement de cette ligne. Premièrement, appelons <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random">Math.random()</a></code>, qui génére un nombre décimal aléatoire compris entre 0 et 1, par exemple 0.5675493843.</p>
+
+<pre class="brush: js">Math.random()</pre>
+
+<p>Puis, nous passons le résultat de l'appel de <code>Math.random()</code> à <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/floor">Math.floor()</a></code>, qui arrondit le nombre passé à l'entier inférieur le plus proche. Puis, on ajoute 1 au résultat :</p>
+
+<pre>Math.floor(Math.random()) + 1</pre>
+
+<p>Garder la partie entière d'un nombre décimal compris entre 0 et 1 renvoie toujours 0, y ajouter 1 donne toujours  1. Il faut multiplier le nombre aléatoire par 100 avant de l'arrondir par défaut. La ligne suivante nous donne un entier aléatoire entre 0 et  99 :</p>
+
+<pre class="brush: js">Math.floor(Math.random()*100);</pre>
+
+<p>Maintenant ajoutons 1 pour obtenir un nombre aléatoire entre 1 et 100 :</p>
+
+<pre class="brush: js">Math.floor(Math.random()*100) + 1;</pre>
+
+<p>Modifiez ces deux lignes comme indiqué, enregistrez, actualisez — le jeu devrait maintenant fonctionner comme il faut !</p>
+
+<h2 id="Autres_erreurs_courantes">Autres erreurs courantes</h2>
+
+<p>D'autres erreurs courantes peuvent être commises en écrivant du code. Ce paragraphe attire votre attention sur la plupart d'entre elles.</p>
+
+<h3 id="SyntaxError_missing_before_statement">SyntaxError: missing ; before statement</h3>
+
+<p>Cette erreur signale généralement l'oubli du point‑virgule à la fin d'une ligne de code ; mais elle peut se révéler parfois plus énigmatique. Par exemple, si, dans la fonction  <code>checkGuess(),</code>nous modifions cette ligne :</p>
+
+<pre class="brush: js">let userGuess = Number(guessField.value);</pre>
+
+<p>en</p>
+
+<pre class="brush: js">let userGuess === Number(guessField.value);</pre>
+
+<p>cela déclenchera cette même erreur car le logiciel pense que vous êtes en train de faire quelque chose d'autre. Vous devez vous assurer que vous n'avez pas confondu l'opérateur d'assignation  (<code>=</code>) — qui fixe une valeur donnée à une variable — avec l'opérateur (<code>===</code>) qui teste la stricte égalité de deux valeurs, et renvoie un résultat  <code>true</code>/<code>false</code> (vrai/faux).</p>
+
+<div class="note">
+<p><strong>Note</strong> : Voyez la page relative à <a href="/en-US/docs/Web/JavaScript/Reference/Errors/Missing_semicolon_before_statement">SyntaxError: missing ; before statement</a> pour plus de précisions à propos de cette erreur.</p>
+</div>
+
+<h3 id="Le_programme_dit_que_vous_avez_gagné_quelle_que_soit_votre_suggestion.">Le programme dit que vous avez gagné quelle que soit votre suggestion.</h3>
+
+<p>Voilà un autre symptome de la confusion entre opérateur d'assignation et opérateur de test d'égalité. Ainsi, dans <code>checkGuess()</code>, si vous modifiez cette ligne :</p>
+
+<pre class="brush: js">if (userGuess === randomNumber) {</pre>
+
+<p>en</p>
+
+<pre class="brush: js">if (userGuess = randomNumber) {</pre>
+
+<p>le test renverra toujours <code>true</code> (vrai) et le programme indiquera que vous avez gagné à tout coup. Soyez attentif !</p>
+
+<h3 id="SyntaxError_missing_after_argument_list">SyntaxError: missing ) after argument list</h3>
+
+<p>Cette erreur est triviale — elle indique en général que vous avez oublié une parenthèse fermante à la fin de l'appel d'une fonction ou d'une méthode.</p>
+
+<div class="note">
+<p><strong>Note</strong>: Voyez la page relative à <a href="/en-US/docs/Web/JavaScript/Reference/Errors/Missing_parenthesis_after_argument_list">SyntaxError: missing ) after argument list</a> pour plus de précisions à ce propos.</p>
+</div>
+
+<h3 id="SyntaxError_missing_after_property_id">SyntaxError: missing : after property id</h3>
+
+<p>Cette erreur concerne généralement un objet JavaScript mal construit, mais dans ce cas nous l'avons déclenchée en modifiant</p>
+
+<pre class="brush: js">function checkGuess() {</pre>
+
+<p>en</p>
+
+<pre class="brush: js">function checkGuess( {</pre>
+
+<p>Le navigateur pense que vous essayez de passer le contenu d'un fonction comme argument pour l'autre fonction. Soyez attentifs avec les parenthèses !</p>
+
+<h3 id="SyntaxError_missing_after_function_body">SyntaxError: missing } after function body</h3>
+
+<p>Facile — elle signifie généralement que vous avez omis une accolade dans une fonction ou dans une structure conditionnelle. Vous l'obtiendrez en effaçant une des accolades voisines de la terminaison de la fonction <code>checkGuess()</code>.</p>
+
+<h3 id="SyntaxError_expected_expression_got_string_ou_SyntaxError_unterminated_string_literal">SyntaxError: expected expression, got '<em>string</em>' ou SyntaxError: unterminated string literal</h3>
+
+<p>Ces erreurs signalent généralement l'oubli de guillemets ouvrants ou fermants dans une chaîne littérale. Dans la première erreur du titre, <em>string</em> doit être remplacé par l'un ou les caractères inattendus que l'explorateur a trouvé à la place du guillemet en début de chaîne. La deuxième erreur indique que la chaîne n'a pas été clôturée avec un guillement fermant.</p>
+
+<p>Pour toutes ces erreurs, revoyez comment nous avons opéré dans les exemples de ce parcours. Quand une erreur survient, regardez le numéro de ligne indiqué, allez à cette ligne et voyez si vous remarquez ce qui ne va pas. N'oubliez pas que l'erreur n'est pas forcément sur la ligne indiquée, et qu'elle ne provient pas forcément d'un des problèmes évoqués plus haut !</p>
+
+<div class="note">
+<p><strong>Note </strong>: Voyez les pages relatives à  <a href="/en-US/docs/Web/JavaScript/Reference/Errors/Unexpected_token">SyntaxError: Unexpected token</a> et <a href="/en-US/docs/Web/JavaScript/Reference/Errors/Unterminated_string_literal">SyntaxError: unterminated string literal</a> pour plus de précisions à ce propos.</p>
+</div>
+
+<h2 id="Résumé">Résumé</h2>
+
+<p>Voilà ce que nous pouvons dire à propos des erreurs basiques pour de simples programmes JavaScript. Il n'est pas toujours aussi simple de détecter ce qui ne va pas dans du code, mais au moins vous économiserez ainsi quelques heures de veille et vous progresserez plus rapidement si les choses ne déraillent pas dès le début de votre parcours d'apprentissage.</p>
+
+<h2 id="Voir_aussi">Voir aussi</h2>
+
+<div>
+<ul>
+ <li>Il y a nombre d'autres erreurs qui n'ont pas été listées ici ; nous les avons récolées dans un référencement qui les explique en détail — voyez <a href="/en-US/docs/Web/JavaScript/Reference/Errors">JavaScript error reference</a>.</li>
+ <li>Si dans votre code vous rencontrez une erreur, et même après avoir lu cet article, vous ne parvenez pas à la corriger, vous pouvez obtenir de l'aide ! Demandez‑la sur le fil de discussion <a class="external external-icon" href="https://discourse.mozilla-community.org/t/learning-web-development-marking-guides-and-questions/16294">Learning Area Discourse thread</a> ou par le canal IRC de <a href="irc://irc.mozilla.org/mdn">#mdn</a> sur  <a class="external external-icon" href="https://wiki.mozilla.org/IRC">Mozilla IRC</a>. Dites‑nous quelle est cette erreur, et nous essayerons de vous aider. Un listing de votre code sera aussi utile.</li>
+</ul>
+</div>
+
+<p>{{PreviousMenuNext("Learn/JavaScript/First_steps/A_first_splash", "Learn/JavaScript/First_steps/Variables", "Learn/JavaScript/First_steps")}}</p>
diff --git a/files/fr/learn/javascript/objects/ajouter_des_fonctionnalités_à_notre_démo_de_balles_rebondissantes/index.html b/files/fr/learn/javascript/objects/ajouter_des_fonctionnalités_à_notre_démo_de_balles_rebondissantes/index.html
new file mode 100644
index 0000000000..36232925ec
--- /dev/null
+++ b/files/fr/learn/javascript/objects/ajouter_des_fonctionnalités_à_notre_démo_de_balles_rebondissantes/index.html
@@ -0,0 +1,208 @@
+---
+title: Ajouter des fonctionnalités à notre exercice des balles rebondissantes
+slug: >-
+ Learn/JavaScript/Objects/Ajouter_des_fonctionnalités_à_notre_démo_de_balles_rebondissantes
+tags:
+ - Apprentissage
+ - CodingScripting
+ - Débutant
+ - Evaluation
+ - JavaScript
+ - OOJS
+ - Objet
+ - Orienté objet
+translation_of: Learn/JavaScript/Objects/Adding_bouncing_balls_features
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/JavaScript/Objects/Object_building_practice", "", "Learn/JavaScript/Objects")}}</div>
+
+<p class="summary">Dans cet exercice, vous devrez utiliser le jeu des balles rebondissantes de l'article précédent comme base, pour y ajouter de nouvelles fonctionnalitées intéressantes.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Prérequis:</th>
+ <td>Avant de vous lancer dans cet exercice, il est fortement conseillé d'avoir vus et compris tous les précédents articles de ce module.</td>
+ </tr>
+ <tr>
+ <th scope="row">Objectifs:</th>
+ <td>Tester votre connaissance du Javascript orienté objet en conception et en pratique.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Pour_commencer">Pour commencer</h2>
+
+<p>Pour commencer, faite une copie locale de <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/bouncing-balls/index-finished.html">index-finished.html</a>, <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/bouncing-balls/style.css">style.css</a>, et <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/bouncing-balls/main-finished.js">main-finished.js</a> de l'article précédent, dans un nouveau dossier.</p>
+
+<div class="note">
+<p><strong>Note</strong>: Vous pouvez utiliser un site comme <a class="external external-icon" href="http://jsbin.com/">JSBin</a> ou <a class="external external-icon" href="https://thimble.mozilla.org/">Thimble</a>. Vous pouvez copier vos codes HTML, CSS et JavaScript dans l'un d'entre eux. Si celui que vous utilisez ne possède pas de fenêtres séparées pour les différents langages, ajoutez les dans des balises <code>&lt;script&gt;</code>/<code>&lt;style&gt;</code> dans votre code HTML.</p>
+</div>
+
+<h2 id="Le_projet_en_bref">Le projet en bref</h2>
+
+<p>Notre jeu des balles est assez sympa, mais maintenant il s'agit de le rendre plus interactif en y ajoutant un viseur controlé par l'utilisateur, qui va détruire une balle si il l'a touche. Nous voulons aussi testé votre capacité en programmation orienté objet en créant un object <code>Shape()</code> dont le viseur et les balles peuvent hériter. Pour terminer nous voulons créer un compteur qui permet d'afficher combien de balle il nous reste encore à détruire.</p>
+
+<p>Ce screenshot vous donne une idée du résultat final:</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/13875/bouncing-evil-circle.png" style="display: block; margin: 0 auto;"></p>
+
+<ul>
+</ul>
+
+<p>Si vous voulez en savoir plus regardez l'exemple finit <a href="http://mdn.github.io/learning-area/javascript/oojs/assessment/">finished example</a> (N'en profitez pas pour récupérer le code source !)</p>
+
+<h2 id="Vos_objectifs">Vos objectifs</h2>
+
+<p>Cette section décrit ce que vous aurez à faire.</p>
+
+<h3 id="Créons_nos_nouveaux_objets">Créons nos nouveaux objets</h3>
+
+<p>Pour commencer, modifions le constructeur de l'objet <code>Ball()</code> pour qu'il devienne le constructeur de <code>Shape()</code> puis créons en un nouveau pour <code>Ball()</code> :</p>
+
+<ol>
+ <li>Le constructeur <code>Shape()</code> devra définir les propriétés <code>x</code>, <code>y</code>, <code>velX</code>, et <code>velY</code> de la même manière que le constructeur <code>Ball()</code> auparavent, mais sans les propriétés <code>color</code> et <code>size</code>.</li>
+ <li><code>Shape()</code> doit aussi définir une nouvelle propriété <code>exists</code>, qui servira à identifier les balles qu'il reste à détruire dans la fenêtre (celles qui n'on pas encore été détruites). Elle doit retourner un booléen (<code>true</code>/<code>false</code>).</li>
+ <li>Le constructeur <code>Ball()</code> doit hériter des propriétés <code>x</code>, <code>y</code>, <code>velX</code>, <code>velY</code>, et <code>exists</code> du constructeur <code>Shape()</code>.</li>
+ <li><code>Ball()</code> doit aussi définir les propriétés <code>color</code> et <code>size</code>, comme à l'origine.</li>
+ <li>N'oubliez pas de définir le prototype de <code>Ball()</code> et son constructeur de manière approprié.</li>
+</ol>
+
+<p>Les méthodes <code>draw()</code>, <code>update()</code>, et <code>collisionDetect()</code> doivent fonctionnées comme avant, sans être modifiées.</p>
+
+<p>Vous devrez ajouter un nouveau paramètre au constructeur <code>new Ball() ( ... )</code> — le paramètre <code>exists</code> doit être le 5ème et être égal à  <code>true</code>.</p>
+
+<p>Vous pouvez recharger la page — Tout doit fonctionner comme avant même après les modifications que vous avez effectuées sur les objets.</p>
+
+<h3 id="Définition_du_EvilCircle()_(viseur)">Définition du EvilCircle() (viseur)</h3>
+
+<p>Il est temps de vous équipez ! — le <code>EvilCircle()</code>! Dans notre jeu nous allons créer un viseur, mais nous allons nous servir de l'objet <code>Shape()</code> pour le définir. Vous voudrez certainement en ajouter un (plusieurs) autre plus tard, qu'un autre joueur ou l'ordinateur pourra contrôler. Vous n'irez probablement pas bien loin avec un seul viseur, mais ce sera suffisant pour le moment !</p>
+
+<p>Le constructeur du <code>EvilCircle()</code> doit hériter des propriétés <code>x</code>, <code>y</code>, <code>velX</code>, <code>velY</code>, et <code>exists</code> de <code>Shape()</code>, mais <code>velX</code> et <code>velY</code> doivent toujours être égales à 20.</p>
+
+<p>Vous devriez utiliser quelque chose comme <code>Shape.call(this, x, y, 20, 20, exists);</code></p>
+
+<p>Le constructeur doit aussi définir ses propres propriétés:</p>
+
+<ul>
+ <li><code>color</code> — <code>'white'</code></li>
+ <li><code>size</code> — <code>10</code></li>
+</ul>
+
+<p>Une fois de plus, souvenez vous de définir vos propriétés héritées en paramètre du constructeur et de définir le prototype et son constructeur de manière appropriée.</p>
+
+<h3 id="Définir_les_méthodes_du_EvilCircle()_(viseur)">Définir les méthodes du EvilCircle() (viseur)</h3>
+
+<p><code>EvilCircle()</code> doit avoir quatre méthodes, comme définie en dessous.</p>
+
+<h4 id="draw()"><code>draw()</code></h4>
+
+<p>Cette méthode doit avoir la même fonction que celle de <code>Ball()</code>: soit dessiner l'objet dans le canvas. Elle fonctionnera quasiment de la même manière, copiez la fonction <code>Ball.prototype.draw</code>. Puis appliquez les modifications suivantes:</p>
+
+<ul>
+ <li>On ne veut pas que le viseur soit plein, mais qu'il ait seulement un contour. Changez <code><a href="/en-US/docs/Web/API/CanvasRenderingContext2D/fillStyle">fillStyle</a></code> et <code><a href="/en-US/docs/Web/API/CanvasRenderingContext2D/fill">fill()</a></code> pour <code><a href="/en-US/docs/Web/API/CanvasRenderingContext2D/strokeStyle">strokeStyle</a></code> et <code><a href="/en-US/docs/Web/API/CanvasRenderingContext2D/stroke">stroke()</a></code>.</li>
+ <li>On voudrait qu'il soit aussi un peu plus épais, pour être plus facile à voir. Pour ça on doit définir un attribut <code><a href="/en-US/docs/Web/API/CanvasRenderingContext2D/lineWidth">lineWidth</a></code> à ctx après l'appel à la fonction <code><a href="/en-US/docs/Web/API/CanvasRenderingContext2D/beginPath">beginPath()</a></code> (avec une valeur de 3).</li>
+</ul>
+
+<h4 id="checkBounds()"><code>checkBounds()</code></h4>
+
+<p>Cette méthode à la même fonction que la première partie de <code>Ball()</code> <code>update()</code> — Savoir si le viseur va hors de l'écran, et l'arrêter si besoin. Une fois encore, copié la méthode <code>Ball.prototype.update</code>, mais en effectuant quelques changements:</p>
+
+<ul>
+ <li>Débarrassez-vous des deux dernières lignes — on a pas besoin de connaître la position du viseur à chaque frame, car nous le déplacerons d'une manière différente comme vous pourrez le voir.</li>
+ <li>Dans les conditions en <code>if()</code> , si la condition retourne true on ne veut pas modifier (update) les propriétés <code>velX</code>/<code>velY</code>; mais plutôt changer les valeurs de <code>x</code>/<code>y</code> de manière à ce que le viseur revienne doucement dans l'écran. Ajouter ou soustraire de manière appropriée la taille (<code>size)</code> du viseur sera suffisant.</li>
+</ul>
+
+<h4 id="setControls()"><code>setControls()</code></h4>
+
+<p>Cette méthode ajoute un écouteur d'évènement <code>onkeydown</code> à l'objet <code>window</code> ce qui permettra en enfonçant certaine touche du clavier de déplacer le viseur dans la fenêtre. Insérez le code suivant dans la méthode:</p>
+
+<pre class="brush: js">var _this = this;
+window.onkeydown = function(e) {
+ if (e.keyCode === 65) {
+ _this.x -= _this.velX;
+ } else if (e.keyCode === 68) {
+ _this.x += _this.velX;
+ } else if (e.keyCode === 87) {
+ _this.y -= _this.velY;
+ } else if (e.keyCode === 83) {
+ _this.y += _this.velY;
+ }
+ }</pre>
+
+<p>Quand une touche est enfoncée, la propriété <a href="/en-US/docs/Web/API/KeyboardEvent/keyCode">keyCode</a> de l'objet event est consultée pour savoir quelle touche est enfoncée. Si c'est une des touches spécifiée, alors le viseur ce déplacera à gauche, à droite, en haut ou en bas.</p>
+
+<ul>
+ <li>Pour un point bonus, faite apparaître à quel touche correspond le code de celle que l'utilisateur a enfoncé.</li>
+ <li>Pour un second point bonus, pouvez vous nous dire pourquoi nous devons définir <code>var _this = this;</code> de cette façon ? Cela à quelque chose à voir avec la portée des fonction.</li>
+</ul>
+
+<h4 id="collisionDetect()"><code>collisionDetect()</code></h4>
+
+<p>Cette méthode fonctionne d'une manière similaire à <code>Ball()</code> <code>collisionDetect()</code>, copier celle-ci pour vous en servir comme base. Il y a deux différences:</p>
+
+<ul>
+ <li>Dans la condition extérieure <code>if</code>, nous n'avons plus besoin de vérifier si la balle actuellement dans la boucle est celle actuellement surveiller — Parce que ce n'est plus une balle, mais notre viseur ! A la place, on doit tester si la balle visée existe (avec quelle propriété pourrez vous faire cela?). Si elle n'existe pas, c'est qu'elle a déjà été détruite, on a donc pas besoin de la vérifier encore une fois.</li>
+ <li>Dans la condition intérieur <code>if</code>, on ne souhaite plus changer un élément de couleur lorsqu'une collision est détéctée — A la place, on veut détruire les balles qui entre en collision avec le viseur (encore une fois, comment pensez-vous faire cela ?).</li>
+</ul>
+
+<h3 id="Insérer_le_viseur_dans_notre_programme">Insérer le viseur dans notre programme</h3>
+
+<p>Maintenant que nous avons définit notre viseur, on a besoin de le faire apparaître à l'écran. Pour ce faire on doit appliquer quelques modifications à la fonction <code>loop()</code>.</p>
+
+<ul>
+ <li>Premièrement, créons une nouvelle instance de l'objet viseur (en spécifiant les paramètres nécessaire), et appelons sa méthode <code>setControls()</code>. On doit seulement effectuer ses deux actions une seule fois, pas à chaque itération.</li>
+ <li>Au moment où l'on boucle à travers toutes les balles et que l'on appelle les méthodes <code>draw()</code>, <code>update()</code>, et <code>collisionDetect()</code> pour chacune d'entre elle, faite de manière à ce que ces fonctions soit appelées seulement si la balle existe.</li>
+ <li>Appellez les méthodes de l'instance du viseur <code>draw()</code>, <code>checkBounds()</code>, et <code>collisionDetect()</code> à chaque itération de la boucle.</li>
+</ul>
+
+<h3 id="Implémenter_le_compteur_de_score">Implémenter le compteur de score</h3>
+
+<p>Pour implémenter le compteur de score, suivez les étapes suivantes:</p>
+
+<ol>
+ <li>Dans votre fichier HTML, ajoutez un élement {{HTMLElement("p")}} qui contiendra le texte suivant "Ball count: ", juste en dessous de l'élément {{HTMLElement("h1")}} .</li>
+ <li>Dans votre fichier CSS, ajouter les règlesz suivantes:
+ <pre class="brush: css">p {
+ position: absolute;
+ margin: 0;
+ top: 35px;
+ right: 5px;
+ color: #aaa;
+}</pre>
+ </li>
+ <li>Dans votre JavaScript, effectuez les modifications suivante:
+ <ul>
+ <li>Créez une variable qui contiendra la référence vers le paragraphe.</li>
+ <li>Stocker et afficher le nombre de balle présentent à l'écran.</li>
+ <li>Incrémentez le compteur de balle à chaque fois qu'une balle apparait à l'écran.</li>
+ <li>Décrementez le compteur à chaque fois qu'une balle est détruite par le viseur.</li>
+ </ul>
+ </li>
+</ol>
+
+<h2 id="Conseils_et_astuces">Conseils et astuces</h2>
+
+<ul>
+ <li>Cet exercice est un bon challenge. Prenez le temps de faire et de comprendre chaque étape.</li>
+ <li>Ce serait une bonne idée de garder une copie de chaque étape lorsque vous arrivez à la faire marcher correctement, pour vous y réferrer si vous n'arrivez plus à progresser ensuite.</li>
+</ul>
+
+<h2 id="Evaluation">Evaluation</h2>
+
+<p>Si vous effectuez cette évalutation dans le cadre d'un cours, vous devriez pouvoir fournir votre travail à votre professeur/mentor pour correction. Si vous apprenez par vous même, vous pouvez obtenir la correction sur <a href="https://discourse.mozilla.org/t/adding-features-to-our-bouncing-balls-demo-assessment/24689">discussion thread for this exercise</a>, ou sur <a href="irc://irc.mozilla.org/mdn">#mdn</a> IRC channel sur <a href="https://wiki.mozilla.org/IRC">Mozilla IRC</a>. Tout d'abord effectuez cet exercice — vous n'obtiendrez jamais rien en trichant !</p>
+
+<p>{{PreviousMenuNext("Learn/JavaScript/Objects/Object_building_practice", "", "Learn/JavaScript/Objects")}}</p>
+
+<h2 id="Dans_ce_Module">Dans ce Module</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/JavaScript/Objects/Basics">Object basics</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object-oriented_JS">Object-oriented JavaScript for beginners</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object_prototypes">Object prototypes</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Objects/Inheritance">Inheritance in JavaScript</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Objects/JSON">Working with JSON data</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object_building_practice">Object building practice</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Objects/Adding_bouncing_balls_features">Adding features to our bouncing balls demo</a></li>
+</ul>
diff --git a/files/fr/learn/javascript/objects/basics/index.html b/files/fr/learn/javascript/objects/basics/index.html
new file mode 100644
index 0000000000..6d7276b7b1
--- /dev/null
+++ b/files/fr/learn/javascript/objects/basics/index.html
@@ -0,0 +1,258 @@
+---
+title: 'Les bases de JavaScript, orienté objet'
+slug: Learn/JavaScript/Objects/Basics
+tags:
+ - API
+ - Apprendre
+ - Débutant
+ - JavaScript
+ - Objet
+ - Syntaxe
+ - this
+translation_of: Learn/JavaScript/Objects/Basics
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{NextMenu("Learn/JavaScript/Objects/Object-oriented_JS", "Learn/JavaScript/Objects")}}</div>
+
+<p class="summary">Dans ce premier article sur les objets JavaScript, nous verrons la syntaxe des objets JavaScript ainsi que quelques fonctionnalités JavaScript déjà aperçues dans les cours précédents, rappelant que beaucoup de fonctionnalités que vous utilisez sont en fait des objets.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Prérequis :</th>
+ <td>Connaissances informatiques de base, connaissances basiques concernant HTML et CSS, bonnes connaissances des bases de JavaScript (cf. <a href="/fr/docs/Learn/JavaScript/First_steps">les premiers pas</a> et <a href="/fr/docs/Learn/JavaScript/Building_blocks">les briques de construction</a>).</td>
+ </tr>
+ <tr>
+ <th scope="row">Objectifs :</th>
+ <td>Comprendre les théories de base derrière la programmation orientée objet, comment l'appliquer à JavaScript, et comment travailler avec des objets JavaScript.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Les_bases_de_lobjet">Les bases de l'objet</h2>
+
+<p>Un objet est une collection de données apparentées et/ou de fonctionnalités (qui, souvent, se composent de plusieurs variables et fonctions, appelées propriétés et méthodes quand elles sont dans des objets). Prenons un exemple pour voir à quoi cela ressemble.</p>
+
+<p>Pour commencer, faites une copie locale de notre fichier <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/introduction/oojs.html">oojs.html</a>. Il contient peu de choses : un élément {{HTMLElement("script")}} pour écrire notre code à l'intérieur. Nous utiliserons ces éléments de base pour explorer les bases de la syntaxe objet. Durant cette exemple, vous devriez avoir <a href="/fr/docs/Apprendre/D%C3%A9couvrir_outils_d%C3%A9veloppement_navigateurs#La_console_JavaScript">la console JavaScript des outils de développement</a> ouverte et prête, pour y saisir des commandes.</p>
+
+<p>Comme souvent dans JavaScript, pour créer un objet, on commence avec la définition et l'initialisation d'une variable. Essayez de mettre le code ci-dessous sous le code déjà écrit de votre fichier JavaScript, puis sauvegardez et rafraichissez la page :</p>
+
+<pre class="brush: js notranslate">var personne = {};</pre>
+
+<p>Désormais ouvrez la <a href="/fr/docs/Outils/Console_JavaScript#Ouvrir_la_Console_du_navigateur">console JavaScript</a> de votre navigateur, saisissez <code>personne</code> à l'intérieur, et appuyez sur <kbd>Entrée</kbd>. Vous devriez obtenir le résultat suivant :</p>
+
+<pre class="brush: js notranslate">[object Object]</pre>
+
+<p>Félicitations, vous avez créé votre premier objet ! Mais c'est un objet vide, on ne peut pas faire grand-chose avec. Modifions notre objet pour qu'il ressemble à ceci :</p>
+
+<pre class="brush: js notranslate">var personne = {
+ nom: ['Jean', 'Martin'],
+ age: 32,
+ sexe: 'masculin',
+ interets: ['musique', 'skier'],
+ bio: function() {
+ alert(this.nom[0] + ' ' + this.nom[1] + ' a ' + this.age + ' ans. Il aime ' + this.interets[0] + ' et ' + this.interets[1] + '.');
+ },
+ salutation: function() {
+ alert('Bonjour ! Je suis ' + this.nom[0] + '.');
+ }
+};
+</pre>
+
+<p>Après avoir sauvegardé et rafraîchit la page, essayez d'entrer les lignes suivantes dans le champ de saisie <code>input</code> :</p>
+
+<pre class="brush: js notranslate">personne.nom
+personne.nom[0]
+personne.age
+personne.interets[1]
+personne.bio()
+personne.salutation()</pre>
+
+<p>Vous avez désormais des données et des fonctionnalités dans votre objet, et vous pouvez y accéder avec une une syntaxe simple et claire !</p>
+
+<div class="note">
+<p><strong>Note :</strong> Si vous avez des difficultés pour le faire fonctionner, comparez votre code avec notre version — voir <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/introduction/oojs-finished.html">oojs-finished.html</a> (ou <a href="https://mdn.github.io/learning-area/javascript/oojs/introduction/oojs-finished.html">voir en action</a>). Une erreur courante, quand on commence avec les objets, est de mettre une virgule après la dernière propriété — ce qui provoque une erreur.</p>
+</div>
+
+<p>Alors, comment ça fonctionne ? Un objet est fait de plusieurs membres, qui ont chacun un nom (par exemple <code>nom</code> et <code>age</code> ci-dessus) et une valeur (par exemple. <code>['Jean', 'Martin']</code> et <code>32</code>).</p>
+
+<p>Chaque paire de nom/valeur doit être séparée par une virgule, et le nom et la valeur de chaque membre sont séparés par deux points. La syntaxe suit ce schéma :</p>
+
+<pre class="brush: js notranslate">var monObjet = {
+ nomDuMembre1: valeurDuMembre1,
+ nomDuMembre2: valeurDuMembre2,
+ nomDuMembre3: valeurDuMembre3
+}</pre>
+
+<p>La valeur d'un membre dans un objet peut être n'importe quoi — dans notre objet <code>personne</code>, nous avons du texte, un nombre, deux tableaux et deux fonctions. Les quatre premières éléments sont des données appelées <strong>propriétés</strong> de l'objet, et les deux derniers éléments sont des fonctions qui utilisent les données de l'objet pour faire quelque chose, et sont appelées des <strong>méthodes</strong> de l'objet.</p>
+
+<p>Dans cet exemple, l'objet est créé grâce à un<strong> objet littéral</strong> : on écrit littéralement le contenu de l'objet pour le créer. On distinguera cette structure des objets instanciés depuis des classes, que nous verrons plus tard.</p>
+
+<p>C'est une pratique très courante de créer un objet en utilisant un objet littéral :  par exemple, quand on envoie une requête au serveur pour transférer des données vers une base de données.</p>
+
+<p>Envoyer un seul objet est bien plus efficace que d'envoyer ses membres de manière individuelle, et c'est bien plus simple de travailler avec un tableau quand on veut identifier des membres par leur nom.</p>
+
+<h2 id="Notation_avec_un_point">Notation avec un point</h2>
+
+<p>Ci-dessus, on accède aux membres de l'objet en utilisant la <strong>notation avec un point</strong>.</p>
+
+<p>Le nom de l'objet (<code>personne</code>) agit comme un <strong>espace de noms</strong> (ou <em>namespace</em> en anglais) — il doit être entré en premier pour accéder aux membres <strong>encapsulés</strong> dans l'objet. Ensuite, on écrit un point, puis le membre auquel on veut accéder — que ce soit le nom d'une propriété, un élément d'un tableau, ou un appel à une méthode de l'objet. Par exemple :</p>
+
+<pre class="brush: js notranslate">personne.age
+personne.interets[1]
+personne.bio()</pre>
+
+<h3 id="Sous-espaces_de_noms">Sous-espaces de noms</h3>
+
+<p>Il est même possible de donner un autre objet comme valeur d'un membre de l'objet. Par exemple, on peut essayer de changer la propriété <code>nom</code> du membre et la faire passer de</p>
+
+<pre class="brush: js notranslate">nom: ['Jean', 'Martin'],</pre>
+
+<p>à</p>
+
+<pre class="brush: js notranslate">nom : {
+ prenom: 'Jean',
+ nomFamille: 'Martin'
+},</pre>
+
+<p>Ici, nous avons bien créé un <strong>sous-espace de noms</strong>. Ça a l'air compliqué, mais ça ne l'est pas. Pour accéder à ces élements, il suffit de chaîner une étape de plus avec un autre point. Essayez ceci :</p>
+
+<pre class="brush: js notranslate">personne.nom.prenom
+personne.nom.nomFamille</pre>
+
+<p><strong>Important </strong>: à partir de maintenant, vous allez aussi devoir reprendre votre code et modifier toutes les occurrences de :</p>
+
+<pre class="brush: js notranslate">nom[0]
+nom[1]</pre>
+
+<p>en</p>
+
+<pre class="brush: js notranslate">nom.prenom
+nom.nomFamille</pre>
+
+<p>sinon vos méthodes ne fonctionneront plus.</p>
+
+<h2 id="Notation_avec_les_crochets">Notation avec les crochets</h2>
+
+<p>Il y a une autre façon d'accéder aux membres de l'objet : la notation avec les crochets. Plutôt que d'utiliser ceci :</p>
+
+<pre class="brush: js notranslate">personne.age
+personne.nom.prenom</pre>
+
+<p>Vous pouvez utiliser :</p>
+
+<pre class="brush: js notranslate">personne['age']
+personne['nom']['prenom']</pre>
+
+<p>Cela ressemble beaucoup à la façon d'accéder aux éléments d'un tableau et c'est bien la même chose  — au lieu d'utiliser un indice numérique pour sélectionner un élément, on utilise le nom associé à chaque valeur d'un membre. Ce n'est pas pour rien que les objets sont parfois appelés tableaux associatifs : ils associent des chaînes de caractères (les noms des membres) à des valeurs, de la même façon que les tableaux associent des nombres à des valeurs.</p>
+
+<h2 id="Définir_les_membres_dun_objet">Définir les membres d'un objet</h2>
+
+<p>Jusqu'ici, nous avons vu comment <strong>accéder</strong> aux membres d'un objet. Vous pouvez aussi <strong>modifier</strong> la valeur d'un membre de l'objet en déclarant simplement le membre que vous souhaitez modifier(en utilisant la notation avec le point ou par crochet), comme ceci :</p>
+
+<pre class="brush: js notranslate">personne.age = 45
+personne['nom']['nomFamille'] = 'Rabuchon'</pre>
+
+<p>Essayez de saisir ces deux lignes précédentes, puis accédez à nouveau aux membres pour voir ce qui a changé :</p>
+
+<pre class="brush: js notranslate">personne.age
+personne['nom']['nomFamille']</pre>
+
+<p>Définir les membres ne s'arrête pas à mettre à jour la valeur de propriétés ou méthodes existantes; <strong>vous pouvez aussi créer de nouveaux membres</strong>. Essayez ceci :</p>
+
+<pre class="brush: js notranslate">personne['yeux'] = 'noisette'
+personne.auRevoir = function() { alert("Bye bye tout le monde !"); }</pre>
+
+<p>Vous pouvez maintenant tester vos nouveaux membres :</p>
+
+<pre class="brush: js notranslate">personne['yeux']
+personne.auRevoir()</pre>
+
+<p>Un des aspects pratiques de la notation par crochet est qu'elle peut être utilisée pour définir dynamiquement les valeurs des membres, mais aussi pour définir les noms. Imaginons que nous voulions que les utilisateurs puissent saisir des types de valeurs personnalisées pour les données des personnes, en entrant le nom du membre et sa valeur dans deux champs <code>input</code>. On pourrait avoir ses valeurs comme ceci :</p>
+
+<pre class="brush: js notranslate">var monNomDeDonnee = nomInput.value
+var maValeurDeDonnee = valeurNom.value</pre>
+
+<p>On peut alors ajouter le nom et la valeur du nouveau membre de l'objet <code>personne</code> comme ceci :</p>
+
+<pre class="brush: js notranslate">personne[monNomDeDonnee] = maValeurDeDonnee</pre>
+
+<p>Pour le tester, essayez d'ajouter les lignes ci-dessous dans votre code, juste après le crochet fermante de l'objet <code>personne</code> :</p>
+
+<pre class="brush: js notranslate">var monNomDeDonnee = 'hauteur'
+var maValeurDeDonnee = '1.75m'
+personne[monNomDeDonnee] = maValeurDeDonnee</pre>
+
+<p>Sauvegardez, rafraîchissez et entrez le texte suivant dans le champ de saisie (l'élément <code>input</code>) :</p>
+
+<pre class="brush: js notranslate">personne.hauteur</pre>
+
+<p>Nous n'aurions pas pu construire ce membre avec la notation avec un point, car celle-ci n'accepte qu'un nom et pas une variable pointant vers un nom.</p>
+
+<h2 id="Quest-ce_que_«_this_»">Qu'est-ce que « <code>this</code> » ?</h2>
+
+<p>Vous avez dû remarquer quelque chose d'un peu étrange dans vos méthodes. Celle-ci, par exemple :</p>
+
+<pre class="brush: js notranslate">salutation: function() {
+ alert('Bonjour! Je suis ' + this.nom.prenom + '.');
+}</pre>
+
+<p>Vous vous demandez probablement ce que signifie « <code>this</code> ». Le mot-clé <code>this</code> se réfère à l'objet courant dans lequel le code est écrit —  dans notre cas, <code>this</code> est l'équivalent de <code>personne</code>.  Alors, pourquoi ne pas écrire <code>personne</code> à la place ? Comme vous le verrez dans l'article <a href="/fr/docs/Learn/JavaScript/Objects/Object-oriented_JS">la programmation JavaScript orientée objet pour les débutants</a>, <code>this</code> est très utile — il permet de s'assurer que les bonnes valeurs sont utilisées quand le contexte d'un membre change (on peut par exemple avoir deux personnes, sous la forme de deux objets, avec des noms différents).</p>
+
+<p>Essayons d'illustrer nos propos par une paire d'objet <code>personne</code> simplifiée :</p>
+
+<pre class="brush: js notranslate">var personne1 = {
+ nom: 'Christophe',
+ salutation: function() {
+ alert('Bonjour ! Je suis ' + this.nom + '.');
+ }
+}
+
+var personne2 = {
+ nom: 'Bruno',
+ salutation: function() {
+ alert('Bonjour ! Je suis ' + this.nom + '.');
+ }
+}</pre>
+
+<p>Dans ce cas,  <code>personne1.salutation()</code> affichera "Bonjour ! Je suis Christophe.", tandis que <code>personne2.salutation()</code> affichera "Bonjour ! Je suis Bruno." alors que le code est le même dans les deux cas. Comme expliqué plus tôt, <code>this</code> est égal à l'objet dans lequel se situe le code. Ce n'est pas très utile quand on écrit des objets littéraux à la main, mais ça prend tout son sens quand on génère des objets dynamiques (avec des constructeurs par exemple).</p>
+
+<h2 id="Vous_utilisiez_des_objets_depuis_le_début_!">Vous utilisiez des objets depuis le début !</h2>
+
+<p>Tout au long de ces exemples, vous vous êtes probablement dit que la notation avec un point vous était très familière. C'est parce que vous l'avez utilisée tout au long du cours ! À chaque fois que vous avez travaillé avec un exemple qui utilise une API ou un objet JavaScript natif, nous avons utilisé des objets. Ces fonctionnalités sont construites exactement comme les objets que nous avons manipulés ici, mais sont parfois plus complexes que dans nos exemples.</p>
+
+<p>Ainsi, quand vous utilisez une méthode comme :</p>
+
+<pre class="brush: js notranslate">maChaineDeCaracteres.split(',');</pre>
+
+<p>Vous utilisez une méthode disponible dans une instance du type {{jsxref("String")}}. Dès que vous créez une chaîne de caractères dans votre code, cette chaîne est automatiquement créée comme une instance de <code>String</code> et possède donc plusieurs méthodes/propriétés communes.</p>
+
+<p>Quand vous accédez au DOM (<em>Document Object Model</em> ou « modèle objet du document ») avec <code>document</code> et des lignes telles que :</p>
+
+<pre class="brush: js notranslate">var monDiv = document.createElement('div');
+var maVideo = document.querySelector('video');</pre>
+
+<p>Vous utilisez une méthode disponible dans l'instance de la classe {{domxref("Document")}}. Pour chaque page web chargée, une instance de <code>Document</code> est créée, appelée <code>document</code> et qui représente la structure entière de la page, son contenu et d'autres caractéristiques telles que son URL. Encore une fois, cela signifie qu'elle possède plusieurs méthodes/propriétés communes.</p>
+
+<p>C'est également vrai pour beaucoup d'autres objets/API natifs que vous avez utilisé  — {{jsxref("Array")}}, {{jsxref("Math")}}, etc.</p>
+
+<p>On notera que les objets/API natifs ne créent pas toujours automatiquement des instances d'objet. Par exemple, <a href="/fr/docs/Web/API/Notifications_API">l'API Notifications</a> — qui permet aux navigateurs modernes de déclencher leurs propres notifications — vous demande d'instancier vous-même une nouvelle instance d'objet en utilisant le constructeur pour chaque notification que vous souhaitez lancer. Essayez d'entrer le code ci-dessous dans la console JavaScript :</p>
+
+<pre class="brush: js notranslate">var maNotification = new Notification('Bonjour !');</pre>
+
+<p>Nous verrons les constructeurs dans un prochain article.</p>
+
+<div class="note">
+<p><strong>Note</strong> : On peut voir le mode de communication des objets comme un <strong>envoi de message</strong>. Quand un objet a besoin d'un autre pour faire une action, souvent il va envoyer un message à un autre objet via l'une de ses méthode et attendre une réponse, qui retournera une valeur.</p>
+</div>
+
+<h2 id="Résumé">Résumé</h2>
+
+<p>Félicitations, vous avez terminé notre premier article sur les objets JavaScript  — vous devriez maintenant mieux comprendre comment on travaille avec des objets en JavaScript. Vous avez pu créer vos propres objets basiques. Vous devriez aussi voir que les objets sont très pratiques pour stocker des données et des fonctionnalités. Si on ne passe pas par un objet et qu'on a une variable différente pour chaque propriété et méthode de notre objet <code>personne</code>, cela sera inefficace et frustrant et vous prendrez le risque de créer des conflits avec d'autres variables et fonctions du même nom.</p>
+
+<p>Les objets permettent de conserver les informations de façon sûre, enfermées dans leur propre « paquet », hors de danger.</p>
+
+<p>Dans le prochain article, nous commencerons à voir la théorie de la programmation orientée objet (POO) et comment utiliser ces techniques en JavaScript.</p>
+
+<p>{{NextMenu("Learn/JavaScript/Objects/Object-oriented_JS", "Learn/JavaScript/Objects")}}</p>
diff --git a/files/fr/learn/javascript/objects/heritage/index.html b/files/fr/learn/javascript/objects/heritage/index.html
new file mode 100644
index 0000000000..9359b6f4ee
--- /dev/null
+++ b/files/fr/learn/javascript/objects/heritage/index.html
@@ -0,0 +1,260 @@
+---
+title: L'héritage au sein de JavaScript
+slug: Learn/JavaScript/Objects/Heritage
+tags:
+ - Apprendre
+ - Article
+ - Débutant
+ - Héritage
+ - JS Orienté Objet
+ - JavaScript
+ - Objet
+ - Programmation orientée objet
+ - Prototype
+translation_of: Learn/JavaScript/Objects/Inheritance
+---
+<div>
+<p>{{LearnSidebar}}</p>
+
+<p>{{PreviousMenuNext("Learn/JavaScript/Objects/Object_prototypes", "Learn/JavaScript/Objects/JSON", "Learn/JavaScript/Objects")}}</p>
+
+<p>Les présentations ayant été faites pour les concepts du JavaScript orienté objet, cet article détaille comment il est possible de créer une classe fille qui hérite des propriétés de sa classe mère. Nous verrons ensuite quelques conseils quant à l'utilisation du JavaScript orienté objet.</p>
+
+<table>
+ <tbody>
+ <tr>
+ <th scope="row">Pré-requis :</th>
+ <td>Une connaissance générale de l'informatique, des notions d'HTML et CSS, une connaissance des bases en JavaScript (voir <a href="/fr/docs/Learn/JavaScript/First_steps">Premiers pas</a> et <a href="/fr/docs/Learn/JavaScript/Building_blocks">Blocs de construction</a>) ainsi que des notions de JavaScript orienté objet (JSOO) (voir <a href="/fr/docs/Learn/JavaScript/Object-oriented/Introduction">Introduction aux objets</a>).</td>
+ </tr>
+ <tr>
+ <th scope="row">Objectif :</th>
+ <td>Comprendre comment implémenter l'héritage en JavaScript.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Héritage_prototypique">Héritage prototypique</h2>
+
+<p>Nous avons déjà vu le concept d'héritage en action, nous avons vu comment la chaîne de prototypage fonctionnait, et comment les propriétés de cette chaîne sont lues de manière ascendante. En revanche,nous n'avons utilisé pratiquement que quelques fonctionnalités déjà intégrées dans le navigateur pour le faire. Comment créer un objet JavaScript qui hérite d'un autre objet ?</p>
+
+<p>Certains pensent que JavaScript n'est pas un véritable langage orienté objet. Dans les langages orientés objets classiques, on définit des classes objet et on peut ensuite définir laquelle hérite d'une autre (voir <a href="http://www.tutorialspoint.com/cplusplus/cpp_inheritance.htm">C++ inheritance</a> en anglais pour des exemples simples). JavasScript utilise une approche différente : les objets héritant d'un autre n'ont pas de fonctionnalités copiées d'un autre objet, au lieu de ça, ils héritent des fonctionnalités via les liens de la chaîne de prototypage (on parle alors d'un <strong>héritage prototypique</strong>).</p>
+
+<p>Voyons comment cela se passe avec un exemple concret.</p>
+
+<h2 id="Pour_commencer">Pour commencer</h2>
+
+<p>Tout d'abord, faites une copie du fichier <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/advanced/oojs-class-inheritance-start.html">oojs-class-inheritance-start.html</a> (voir la <a href="https://mdn.github.io/learning-area/javascript/oojs/advanced/oojs-class-inheritance-start.html">démo</a>). Vous y trouverez le constructeur <code>Personne()</code> que nous avons utilisé jusque là dans l'ensemble des modules, néanmoins il y a un léger changement : nous n'avons défini que les attributs au sein du constructeur.</p>
+
+<pre>function Personne(prenom, nom, age, genre, interets) {
+ this.nom = {
+ prenom,
+ nom
+ };
+ this.age = age;
+ this.genre = genre;
+ this.interets = interets;
+};</pre>
+
+<p>L'ensemble des méthodes est défini dans le prototype :</p>
+
+<pre>Personne.prototype.saluer = function() {
+ alert('Salut! Je suis ' + this.nom.prenom + '.');
+};</pre>
+
+<p>Essayons de créer une classe <code>Professeur</code> similaire à celle que nous avons utilisée jusqu'ici dans les autres modules d'initiations à l'approche objet. Ainsi, cette classe hérite de <code>Personne</code> mais possède aussi :</p>
+
+<ol>
+ <li>Un nouvel attribut <code>matière</code> — qui contiendra la matière que le professeur enseigne.</li>
+ <li>Une méthode <code>saluer</code> un peu plus élaborée, qui sera un peu plus formelle que la méthode de base, cela sera plus approprié, lorsque le professeur s'adrressera à des étudiants, par exemple.</li>
+</ol>
+
+<h2 id="Définissons_le_constructeur_Professeur()">Définissons le constructeur Professeur()</h2>
+
+<p>La première chose à faire est de créer le constructeur <code>Professeur()</code> via l'ajout du code suivant :</p>
+
+<pre>function Professeur(prenom, nom, age, genre, interets, matiere) {
+ Personne.call(this, prenom, nom, age, genre, interets);
+
+ this.matiere = matiere;
+}</pre>
+
+<p>Cela ressemble beaucoup au constructeur <code>Personne</code> mais il y a quelque chose que nous n'avons pas encore vu : la fonction <code><a href="/fr/docs/Web/JavaScript/Reference/Global_Objects/Function/call">call()</a></code>. Cette fonction permet d'appeler une fonction définie ailleurs dans le contexte actuel. Le premier paramètre spécifie la valeur de <code>this</code> que l'on souhaite utiliser lors que l'on utilisera la fonction, les paramètres suivants seront les paramètres qui pourront être passés en arguments lorsqu'elle sera appelée.</p>
+
+<p>Nous voulons que le constructeur <code>Professeur()</code> aie les mêmes attributs que <code>Personne()</code>, nous les spécifions donc dans l'appel fait via la fonction <code>call()</code>.</p>
+
+<p>La dernière ligne au sein du constructeur sert simplement à définir l'attribut <code>matière</code> que les professeurs enseignent, ce qui n'est pas valable pour les personnes génériques.</p>
+
+<p>Notez que nous aurions très bien pu écrire tout simplement ceci :</p>
+
+<pre>function Professeur(prenom, nom, age, genre, interets, matiere) {
+ this.nom_complet = {
+ prenom,
+ nom
+ };
+ this.age = age;
+ this.genre = genre;
+ this.interets = interets;
+ this.matiere = matiere;
+}</pre>
+
+<p>Cependant cela aurait eu pour effet de redéfinir les attributs à nouveau, sans les hériter de <code>Personne()</code>, ce qui n'est pas vraiment le but que nous voulons atteindre lorsque l'on parle de l'héritage, cela rajoute aussi des lignes de code inutiles.</p>
+
+<p> </p>
+
+<h3 id="Hériter_d'un_constructeur_sans_paramètres">Hériter d'un constructeur sans paramètres</h3>
+
+<p>Notez que si les valeurs des propriétés du constructeur dont vous héritez ne proviennent pas de paramètres, vous n'avez nullement besoin de les specifier comme arguments additionnels dans l'appel de la fonction <code>call()</code>. Donc, par exemple, si vous avez quelque chose d'aussi simple que ceci :</p>
+
+<pre><code>function Brick() {
+ this.width = 10;
+ this.height = 20;
+}</code></pre>
+
+<p>Vous pouvez hériter des propriétés <code>width</code> et <code>height</code> en procédant comme ceci (Mais  également en suivant bien sûr les différentes étapes décrites ci dessous) :</p>
+
+<pre><code>function BlueGlassBrick() {
+ Brick.call(this);
+
+ this.opacity = 0.5;
+ this.color = 'blue';
+}</code></pre>
+
+<p>Notez que nous n'avons spécifié que <code>this</code> au sein de <code>call()</code> — Aucun autre paramètre n'est requis puisque nous n'héritons ici d'aucune propriété provenant de la classe parente qui soit spécifiée via paramètres.  </p>
+
+<h2 id="Définir_le_prototype_de_Professeur()_et_son_constructeur_référent.">Définir le prototype de Professeur() et son constructeur référent.</h2>
+
+<p>Pour le moment tout va bien, mais nous avons un petit problème. Nous avons défini un  nouveau constructeur et ce dernier possède une propriété <code>prototype</code>, qui par défaut ne contient qu'une référence à la fonction constructrice elle même. En revanche il ne contient pas les méthodes de la propriété <code>prototype</code> du constructeur <code>Personne()</code>. Pour le constater, vous pouvez par exemple entrer <code>Professeur.prototype.constructor</code> dans la console JavaScript pour voir ce qu'il en est. Le nouveau constructeur n'a en aucun cas hérité de ces méthodes. Pour le constater, comparez les sorties de <code>Personne.prototype.saluer</code> et de <code>Professeur.prototype.saluer</code></p>
+
+<p>Notre classe <code>Professeur()</code> doit hériter des méthodes définies dans le prototype de <code>Personne()</code>. Aussi comment procéder pour obtenir ce résultat ?</p>
+
+<p>Ajoutez la ligne suivante à la suite du bloc de code que nous venons d'ajouter :</p>
+
+<pre>Professeur.prototype = Object.create(Personne.prototype);</pre>
+
+<ol>
+ <li>Ici, notre ami <code><a href="/fr/docs/Web/JavaScript/Reference/Global_Objects/Object/create">create()</a></code> vient nous aider à nouveau. Dans ce cas, on l'utilise afin de créer un nouvel objet que nous assignons à <code>Professeur.prototype</code>. Le nouvel objet possède <code>Personne.prototype</code> désormais comme son prototype et héritera ainsi, si et quand le besoin se fera sentir, de toutes les méthodes disponible sur <code>Personne.prototype</code>. </li>
+ <li>Nous avons également besoin de faire encore une chose avant de continuer. Après avoir ajouté la ligne précédente, le constructeur du prototype de <code>Professeur()</code> est désormais équivalent à celui de <code>Personne()</code>, parce que nous avons défini <code>Professeur.prototype</code> pour référencer un objet qui hérite ses propriétés de  <code>Personne.prototype</code> ! Essayez, après avoir sauvegardé votre code et rechargé la page, d'entrer <code>Professeur.prototype.constructor</code> dans la console pour vérifier.</li>
+ <li>Cela peut devenir problématique, autant le corriger dès maintenant. C'est possible via l'ajout de la ligne de code suivante à la fin :
+ <pre>Professeur.prototype.constructor = Professeur;</pre>
+ </li>
+ <li>
+ <p>A présent, si vous sauvegardez et rafraichissez après avoir écrit <code>Professeur.prototype.constructor</code>, cela devrait retourner <code>Professeur()</code>, et en plus nous héritons maintenant de <code>Personne()</code> !</p>
+ </li>
+</ol>
+
+<h2 id="Donner_au_prototype_de_Professeur()_une_nouvelle_fonction_saluer()">Donner au prototype de Professeur() une nouvelle fonction saluer()</h2>
+
+<p>Pour terminer notre code, nous devons définir une nouvelle fonction <code>saluer()</code> sur le constructeur de <code>Professeur()</code>.</p>
+
+<p>La façon la plus facile d'accomplir cela est de la définir sur le prototype de Professeur() — ajoutez ceci à la suite de votre code :</p>
+
+<pre>Professeur.prototype.saluer = function() {
+ var prefix;
+
+ if (this.genre === 'mâle' || this.genre === 'Mâle' || this.genre === 'm' || this.genre === 'M') {
+ prefix = 'M.';
+ } else if (this.genre === 'femelle' || this.genre === 'Femelle' || this.genre === 'f' || this.genre === 'F') {
+ prefix = 'Mme';
+ } else {
+ prefix = '';
+ }
+
+ alert('Bonjour. Mon nom est ' + prefix + ' ' + this.nom_complet.nom + ', et j\'enseigne ' + this.matiere + '.');
+};</pre>
+
+<p>Ceci affiche la salutation du professeur, qui utilise le titre de civilité approprié à son genre, au moyen d'une instruction conditionnelle.</p>
+
+<p> </p>
+
+<h2 id="Exécuter_l'exemple">Exécuter l'exemple</h2>
+
+<p>Une fois tout le code saisi, essayez de créer une instance d'objet <code>Professeur()</code> en ajoutant à la fin de votre JavaScript (ou à l'endroit de votre choix) :</p>
+
+<pre>var professeur1 = new Professeur('Cédric', 'Villani', 44, 'm', ['football', 'cuisine'], 'les mathématiques');</pre>
+
+<p>Sauvegardez et actualisez, et essayez d'accéder aux propriétés et méthodes de votre nouvel objet <code>professeur1</code>, par exemple :</p>
+
+<pre>professeur1.nom_complet.nom;
+professeur1.interets[0];
+professeur1.bio();
+professeur1.matiere;
+professeur1.saluer();Ffa</pre>
+
+<p>Tout cela devrait parfaitement fonctionner. Les instructions des lignes 1,2,3  et 6 accèdent à des membres hérités de la classe générique <code>Personne()</code> via son constructeur, tandis que la ligne 4 accède de façon plus spécifique à un membre qui n'est disponible que via le constructeur de la classe spécialisée <code>Professeur()</code>.</p>
+
+<p><strong>Note</strong>: Si vous rencontrez un problème afin de faire fonctionner ce code comparez le à notre <a href="http://mdn.github.io/learning-area/javascript/oojs/advanced/oojs-class-inheritance-finished.html">version finalisée</a> (Ou regarder tourner <a href="http://mdn.github.io/learning-area/javascript/oojs/advanced/oojs-class-inheritance-finished.html">notre demo en ligne</a>).</p>
+
+<p>La méthode que nous avons détaillée ici n'est pas la seule permettant de mettre en place l'héritage de classes en JavaScript, mais elle fonctionne parfaitement et elle vous permet d'avoir une bonne idée de comment implémenter l'héritage en JavaScript.</p>
+
+<p>Vous pourriez également être intéressé par certaines des nouvelles fonctionnalités de {{glossary("ECMAScript")}} qui nous permettent de mettre en place l'héritage d'une façon beaucoup plus élégante en JavaScript (Voir <a href="/en-US/docs/Web/JavaScript/Reference/Classes">Classes</a>). Nous ne les avons pas développées ici parce qu'elles ne sont actuellement pas supportées par tous les navigateurs. Toutes les autres constructions dont nous avons discuté dans cette série d'articles sont supportées par IE9 et les versions moins récentes et il existe des méthodes qui prennent plus en  charge les navigateurs moins récents.</p>
+
+<p>Un moyen habituel est d'utiliser les librairies JavaScript — La plupart des options populaires ont une sélection de fonctionnalités disponibles pour réaliser l'héritage plus facilement et plus rapidement.</p>
+
+<p><a href="http://coffeescript.org/#classes">CoffeeScript</a> par exemple fournit les fonctionnalités <code>class</code>, <code>extends</code>, etc.</p>
+
+<h2 id="Un_exercice_plus_complexe.">Un exercice plus complexe.</h2>
+
+<p>Dans notre <a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Object-oriented_JS#Object-oriented_programming_from_10000_meters">section sur la programmation orientée objet</a> nous avons également inclus  une classe <code>Etudiant</code> comme un concept qui hérite de toutes les fonctionnalités de la classe <code>Personne</code>, et qui a également une méthode <code>saluer()</code> differente de celle de <code>Personne</code> qui est beaucoup moins formelle que la méthode <code>saluer()</code> de <code>Professeur()</code>. Jetez un oeil à ce à quoi ressemble la méthode <code>saluer()</code> de la classe <code>Etudiant</code> dans cette section et essayez d'implémenter votre propre constructeur <code>Etudiant()</code> qui hérite de toutes les fonctionnalités de <code>Personne()</code> et la fonction <code>saluer()</code> différente.</p>
+
+<p><strong>Note</strong>: Si vous rencontrez un problème afin de faire fonctionner ce code comparez le à notre <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/advanced/oojs-class-inheritance-student.html">version finalisée</a> (Ou regarder tourner <a href="http://mdn.github.io/learning-area/javascript/oojs/advanced/oojs-class-inheritance-student.html">notre demo en ligne</a>).</p>
+
+<h2 id="Résumé_sur_les_membres_de_l'Objet">Résumé sur les membres de l'Objet</h2>
+
+<p>Pour résumer, vous avez de façon basique trois types de propriétés/méthodes à prendre en compte :</p>
+
+<ol>
+ <li>Celles définies au sein d'un constructeur et passées en paramètres aux instances de l'objet. Celles là ne sont pas difficiles à repérer — Dans votre propre code personnalisé, elles sont les membres définis en utilisant les lignes comme <code>this.x = x</code> ; Dans les codes préconstruits propres aux navigateurs, ils sont les membres seulement accessibles aux instances d'objet (usuellement créés en appelant un constructeur via l'utilisation du mot clé <code>new</code>, exemple : <code>var myInstance = new myConstructor()</code>).</li>
+ <li>Celles définies directement sur les constructeurs eux mêmes et accessibles uniquement sur les constructeurs. Celles là sont communément présentes uniquement dans les objets préconstruits des navigateurs et sont reconnus par le fait d'être directement chaînées sur un constructeur et non sur une instance. Par exemple, <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys">Object.keys()</a></code>.</li>
+ <li>Celles définies sur un prototype de constructeur qui sont héritées par toutes les instances des classes d'objet. Celles là incluent n'importe quel membre défini sur un prototype de constructeur, exemple : <code>myConstructor.prototype.x()</code>.</li>
+</ol>
+
+<p>Si vous êtes encore dans la confusion par rapport aux différents types ne vous inquiétez pas c'est normal — vous êtes encore entrain d'apprendre et la familiarité apparaîtra avec la pratique.</p>
+
+<h2 id="Quand_devez-vous_utiliser_l'héritage_en_JavaScript">Quand devez-vous utiliser  l'héritage en JavaScript?</h2>
+
+<p>Particulièrement après ce dernier article, vous pourriez penser "woa c'est compliqué". Bien, vous avez vu juste, prototypes et héritages représentent une partie des aspects les plus complexes de JavaScript, mais une bonne partie de la puissance et de la flexibilité de JavaScript vient de sa structure Objet et de l'héritage et il est vraiment très important de comprendre comment cela fonctionne. </p>
+
+<p>D'une certaine manière, vous utilisez l'héritage à plein temps — Que vous utilisiez différentes fonctionnalités d'une WebAPI , ou une méthode/propriété définie par défaut  sur un objet prédéfini du navigateur que vous invoquez sur vos chaînes de caractères, tableaux etc., vous utilisez de façon implicite l'héritage. </p>
+
+<p>En termes d'utilisation de l'héritage dans votre propre code, vous ne l'utiliserez probablement pas si souvent et spécialement pour débuter avec, et dans les petits projets — C'est une perte de temps d'utiliser les objets et l'héritage par amour pour cette pratique quand vous n'en avez pas besoin. Mais à mesure que les bases de votre code s'élargissent vous trouverez cette façon de faire probablement très utile. Si vous trouvez utile et plus pratique de commencer en créant un certain nombre d'objets spécialisés partageant les mêmes fonctionnalités, alors créer un objet générique qui contiendra toutes les fonctionnalités communes dont les objets spécialisés hériteront vous apparaîtra être une pratique peut être plus confortable et efficace par la suite. </p>
+
+<p><strong>Note</strong>: A cause de la manière dont JavaScript fonctionne, avec la chaîne de prototype, etc., le partage de fonctionnalités entre objet est souvent appelée <strong>délégation</strong> — Les objets spécialisés délèguent cette fonctionnalité à l'objet de type générique. C'est certainement beaucoup plus précis que de l'appeler héritage, puisque la fonctionnalité "héritée" n'est pas copiée dans les objets qui "héritent". Au contraire, elle demeure dans l'objet générique.</p>
+
+<p>Lorsque vous utilisez l'héritage, il est conseillé de ne pas avoir trop de degrés d'héritage et de toujours garder minutieusement trace de l'endroit où vous définissez vos propriétés et méthodes. Il est possible de commencer à écrire un code qui modifie temporairement les prototypes des objets prédéfinis du navigateur mais vous ne devriez pas le faire à moins que n'ayiez une très bonne raison. Trop de degrés d'héritages peut conduire à une confusion sans fin et une peine sans fin quand vous essayez de déboguer un tel code. </p>
+
+<p>En définitive, les objets sont juste une autre forme de réutilisation de code comme les fonctions et les boucles avec leurs propres rôles et avantages. Si vous trouvez utile de créer un lot de variables et fonctions relatives et que vous voulez les retracer ensemble et les empaqueter de façon ordonnée, un objet est une bonne idée. Les objets sont également très utiles quand vous souhaitez passer une collection de données d'un endroit à un autre. Toutes ces choses peuvent être accomplies sans l'utilisation d'un constructeur ou de l'héritage. Si vous n'avez besoin que d'une seule instance, l'utilisation d'un simple objet littéral serait certainement un choix beaucoup plus judicieux et vous n'avez certainement pas besoin de l'héritage.</p>
+
+<h2 id="Résumé">Résumé</h2>
+
+<p>Cet article a couvert le reste du coeur de la théorie du JSOO et des syntaxes que nous pensons que vous devriez connaître maintenant. A cet stade vous devriez comprendre l'objet JavaScript et les bases de la POO, les prototypes et l'héritage par prototype, comment créer les classes (constructeurs) et les instances d'objet, ajouter des fonctionnalités aux classes, et créer des sous classes qui héritent d'autres classes. </p>
+
+<p>Dans le prochain article, nous jetterons un regard sur comment travailler avec le (JSON),  un format commun d'échange de données écrit en utilisant les objets JavaScript.</p>
+
+<h2 id="Voir_aussi">Voir aussi</h2>
+
+<ul>
+ <li><a href="http://www.objectplayground.com/">ObjectPlayground.com</a> — Un site interactif d'appentissage très utile pour en savoir plus sur les Objets.</li>
+ <li><a href="https://www.amazon.com/gp/product/193398869X/">Secrets of the JavaScript Ninja</a>, Chapitre 6 — Un bon livre sur les concepts et techniques avancées du JavaScript par John Resig et Bear Bibeault. Le chapitre 6 couvre très bien les divers aspects des prototypes et de l'héritage ; vous trouverez sûrement facilement une version imprimée ou une version en ligne.</li>
+ <li><a href="https://github.com/getify/You-Dont-Know-JS/blob/master/this%20&amp;%20object%20prototypes/README.md#you-dont-know-js-this--object-prototypes">You Don't Know JS: this &amp; Object Prototypes</a> — Une partie de l'excellente série de manuels sur le JavaScript de Kyle Simpson. Le chapitre 5 en particulier jette un regard beaucoup plus approfondi sur les prototypes que nous ne l'avons fait ici. Nous avons présenté ici une vue simplifiée dans cette série d'articles dédiée aux débutants tandis que Kyle est allé dans les détails les plus profonds et fournit une image beaucoup plus complexe et plus précise.</li>
+</ul>
+
+<p>{{PreviousMenuNext("Learn/JavaScript/Objects/Object_prototypes", "Learn/JavaScript/Objects/JSON", "Learn/JavaScript/Objects")}}</p>
+
+<p> </p>
+
+<h2 id="Dans_ce_module">Dans ce module</h2>
+
+<ul>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Basics">Les bases de l'Objet</a></li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Object-oriented_JS">JavaScript  Orienté Objet pour débutants</a></li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Object_prototypes">Prototypes d'Objet</a></li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Inheritance">L'héritage en JavaScript</a></li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/JSON">Travailler avec les données JSON</a></li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Object_building_practice">Construire les Objets dans la pratique</a></li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Adding_bouncing_balls_features">Ajouter des fonctionnalités à la démo de nos balles bondissantes</a></li>
+</ul>
+
+<p> </p>
+</div>
+
+<p> </p>
diff --git a/files/fr/learn/javascript/objects/index.html b/files/fr/learn/javascript/objects/index.html
new file mode 100644
index 0000000000..c388ee3b62
--- /dev/null
+++ b/files/fr/learn/javascript/objects/index.html
@@ -0,0 +1,70 @@
+---
+title: Introduction aux objets JS
+slug: Learn/JavaScript/Objects
+tags:
+ - Apprendre
+ - Article
+ - Auto-évaluation
+ - Débutant
+ - Guide
+ - JavaScript
+ - Objets
+ - Tutoriel
+translation_of: Learn/JavaScript/Objects
+---
+<div>
+<div>{{JsSidebar}}</div>
+
+<div>{{PreviousNext("Apprendre/JavaScript/Building_blocks", "Learn/JavaScript/Objects/Basics")}}</div>
+</div>
+
+<p class="summary">En JavaScript, la plupart des choses sont des objets, des éléments du cœur de JavaScript, comme les chaînes de caractères et les tableaux, aux interfaces de programmation (APIs) des navigateurs construites sur la base de JavaScript. Vous pouvez même créer vos propres objets pour encapsuler des fonctions liées et des variables au sein de paquets efficaces, et se comportant comme des conteneurs de données. Il est important de comprendre la nature orientée objet du JavaScript si vous souhaitez aller loin dans votre connaissance du langage, aussi, avons-nous fourni ce module afin de vous aider. Ici, nous enseignons la théorie de l’objet et sa syntaxe en détail, ensuite, ce sera à vous de voir comment vous souhaitez créer vos propres objets.     </p>
+
+<h2 id="Prérequis">Prérequis</h2>
+
+<p>Avant de commencer ce module, vous devriez avoir quelques familiarités avec le HTML et le CSS. Il serait raisonnable de travailler sur les modules <a href="https://developer.mozilla.org/fr/Apprendre/HTML/Introduction_%C3%A0_HTML">Introduction au HTML</a> et <a href="https://developer.mozilla.org/fr/Apprendre/CSS/Introduction_%C3%A0_CSS">Introduction au CSS</a> avant de commencer avec le JavaScript.</p>
+
+<p>Vous devriez également être familiarisé avec les bases du JavaScript avant de poursuivre en détails avec les objets JavaScript. Avant de commencer ce module, travaillez sur <a href="https://developer.mozilla.org/fr/docs/Learn/JavaScript/First_steps">Premiers pas avec JavaScript</a> et <a href="https://developer.mozilla.org/fr/Apprendre/JavaScript/Building_blocks">Les blocs de construction en JavaScript</a>.</p>
+
+<div class="note">
+<p><strong>Remarque</strong>: Si vous travaillez sur un ordinateur, une tablette ou un autre appareil où vous n’avez pas la possibilité de créer vos propres fichiers, vous pouvez essayer les (la plupart des) exemples de code grâce à un programme en ligne comme <a href="http://jsbin.com/">JSBin</a> ou <a href="https://thimble.mozilla.org/">Thimble</a>.</p>
+</div>
+
+<h2 id="Guides">Guides</h2>
+
+<dl>
+ <dt><a href="https://developer.mozilla.org/fr/docs/Learn/JavaScript/Objects/Basics">Les bases de JavaScript orienté objet</a></dt>
+ <dd>Dans le premier article concernant les objets JavaScript, nous découvrirons la syntaxe fondamentale d’un objet JavaScript, et nous revisiterons certaines fonctionnalités du JavaScript que nous avions vues précédemment dans le cours, en insistant sur le fait que bon nombre d'éléments précedemment abordés sont en fait des objets.</dd>
+</dl>
+
+<dl>
+ <dt><a href="https://developer.mozilla.org/fr/docs/Learn/JavaScript/Objects/JS_orient%C3%A9-objet">JavaScript orienté objet pour les débutants</a><u> </u></dt>
+ <dd>
+ <p style="margin-left: 36.0pt;">Après avoir vu les notions de base, nous nous pencherons sur le JavaScript orienté objet (JSOO) — cet article présente une vue basique de la théorie de la programmation orientée objet (POO), et explore ensuite comment le JavaScript émule les classes d’objet via les fonctions des constructeurs et comment créer des instances d’objet.</p>
+ </dd>
+ <dt><a href="https://developer.mozilla.org/fr/docs/Learn/JavaScript/Objects/Prototypes_Objet">Objets prototypes</a></dt>
+ <dd>
+ <p style="margin-left: 36.0pt;">Les prototypes sont des mécanismes par lesquels les objets JavaScript héritent les fonctionnalités d’un autre objet, et ils fonctionnent différemment des mécanismes d’héritage des langages classiques de programmation orientée objet. Dans cet article, nous explorons cette différence, expliquant comment les chaînes de prototypes fonctionnent et jetant un regard sur comment la propriété prototype peut être utilisée pour ajouter des méthodes aux constructeurs existants.</p>
+ </dd>
+ <dt><a href="https://developer.mozilla.org/fr/docs/Learn/JavaScript/Objects/Heritage">L’héritage au sein de JavaScript</a></dt>
+ <dd>
+ <p style="margin-left: 36.0pt;">Avec la plupart des redoutables détails du JSOO maintenant expliqués, cet article montre comment créer les classes (constructeurs) d’objet “enfant” qui héritent des fonctionnalités de leur classes “parents”. De plus, nous présentons certains conseils sur où et comment utiliser le JSOO.</p>
+ </dd>
+ <dt><a href="https://developer.mozilla.org/fr/docs/Learn/JavaScript/Objects/JSON">Manipuler des données JSON</a></dt>
+ <dd>
+ <p style="margin-left: 36.0pt;">JavaScript Object Notation (JSON) est un format standard pour la représentation de données structurées comme les objets JavaScript, qui est communément utilisé pour représenter et transmettre les données sur les sites web (ex. : Envoyer certaines données du serveur au client, afin d’être affichées sur une page web). Vous le rencontrerez assez souvent. Aussi, dans cet article, nous vous donnons tout ce dont vous avez besoin pour travailler avec le format JSON utilisant le JavaScript, incluant l’accès aux éléments des données dans un objet JSON et l’écriture de votre propre JSON.</p>
+ </dd>
+ <dt><a href="https://developer.mozilla.org/fr/docs/Learn/JavaScript/Objects/Object_building_practice">Pratiques sur la construction d’objet</a></dt>
+ <dd>
+ <p style="margin-left: 36.0pt;">Dans l’article précédent nous avons fait le tour de l’essentiel de la théorie de l’objet JavaScript et les détails de sa syntaxe, vous donnant ainsi une solide base sur laquelle débuter. Dans cet article nous plongeons dans un exercice, vous donnant plus de pratique dans la construction d’objets JavaScript personnalisés, qui produisent quelque chose d’amusant et de plus coloré — quelques balles colorées et bondissantes.</p>
+ </dd>
+</dl>
+
+<h2 id="Auto-évaluation">Auto-évaluation</h2>
+
+<dl>
+ <dt><a href="https://developer.mozilla.org/fr/docs/Learn/JavaScript/Objects/Adding_bouncing_balls_features">Ajoutez des fonctionnalités  à notre  démo des ballons bondissants</a></dt>
+ <dd>Dans cette évaluation, vous devrez utiliser la démo des balles bondissantes de l’article précédent comme un point de départ et y ajouter quelques nouvelles et intéressantes fonctionnalités.</dd>
+</dl>
+
+<p>{{PreviousNext("Apprendre/JavaScript/Building_blocks", "JavaScript/Guide")}} </p>
diff --git a/files/fr/learn/javascript/objects/js_orienté-objet/index.html b/files/fr/learn/javascript/objects/js_orienté-objet/index.html
new file mode 100644
index 0000000000..c16e9a230e
--- /dev/null
+++ b/files/fr/learn/javascript/objects/js_orienté-objet/index.html
@@ -0,0 +1,278 @@
+---
+title: Le JavaScript orienté objet pour débutants
+slug: Learn/JavaScript/Objects/JS_orienté-objet
+tags:
+ - Apprendre
+ - Débutant
+ - Guide
+ - JavaScript
+ - OOJS
+ - OOP
+ - POO
+translation_of: Learn/JavaScript/Objects/Object-oriented_JS
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/JavaScript/Objects/Basics", "Learn/JavaScript/Objects/Object_prototypes", "Learn/JavaScript/Objects")}}</div>
+
+<p class="summary">Après avoir parcouru les fondamentaux, nous allons aborder en détail le JavaScript orienté objet (JSOO). Cet article présente une approche simple de la programmation orientée objet (POO) et détaille comment JavaScript émule des classes objet au travers des méthodes constructeur et comment instancier ces objets.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Pré-requis :</th>
+ <td>Connaissances de base en informatique et compréhension des notions HTML et CSS, notions de JavaScript (voir <a href="/fr/docs/Learn/JavaScript/First_steps">Premiers pas</a> et <a href="/fr/docs/Learn/JavaScript/Building_blocks">Blocs de construction</a>)</td>
+ </tr>
+ <tr>
+ <th scope="row">Objectif :</th>
+ <td>Comprendre les concepts de base derrière la programmation orientée objet et comment ils s'appliquent à JavaScript ( « tout est objet » ) et comment créer des constructeurs et instancier des objets.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="La_programmation_orientée_objet_de_loin">La programmation orientée objet de loin</h2>
+
+<p>Pour commencer, donnons une vue simplifiée et de haut niveau de ce qu'est la programmation orientée objet (POO). On parle d'une vision simplifiée étant donnée que la POO peut devenir très vite complexe et qu'être exhaustif rendrait probablement la découverte plus confuse et difficile qu'autre chose. L'idée de base de la POO consiste à utiliser des objets pour modéliser les objets du monde réel que l'on souhaite représenter dans nos programmes et/ou de fournir un moyen simple d'accéder à une fonctionnalité qu'il serait difficile d'utiliser autrement.</p>
+
+<p>Les objets peuvent contenir des données et du code représentant de l'information au sujet de la chose que l'on essaie de modéliser ainsi que des fonctionnalités ou un comportement que l'on souhaite lui appliquer. Les données (et bien souvent les fonctions) associées à un objet peuvent être stockées (le terme officiel est <strong>encapsulé</strong>) à l'intérieur d'un paquet objet. Il est possible de donner un nom spécifique à un paquet objet afin  d'y faire référence, on parle alors d'<strong>espace de noms</strong> ou <em>namespace</em>, il sera ainsi plus facile de le manipuler et d'y accéder. Les objets peuvent aussi servir pour stocker des données et les transférer facilement sur un réseau.</p>
+
+<h3 id="Définissons_un_modèle_objet">Définissons un modèle objet</h3>
+
+<p>Nous allons voir un programme simple qui affiche des informations à propos des élèves et des professeurs d'une école. Nous allons aborder la théorie de la programmation orientée objet de manière générale sans l'appliquer à un langage particulier.</p>
+
+<p>Pour débuter, nous pouvons réutiliser l'objet Personne que nous avons créé dans notre <a href="/fr/docs/Learn/JavaScript/Objects/Basics">premier article</a>, il définit un ensemble de données et actions d'une personne. Il existe tout un tas de choses que nous pourrions savoir au sujet d'une personne (son adresse, sa taille, sa pointure, son ADN, son numéro de passeport, ses traits particuliers significatifs… ). En l'occurrence, nous souhaitons uniquement afficher son nom, son âge, ses passions, écrire une petite introduction à son sujet en utilisant ces données et lui apprendre à se présenter. On parle alors d'<strong>abstraction </strong>: créer un modèle simplifié de quelque chose de complexe mais qui ne contient que les aspects qui nous intéressent. Il sera alors plus simple de manipuler ce modèle objet simplifié dans le cadre de notre programme.</p>
+
+<p><img alt="Classe Personne avec attributs élémentaires" src="https://mdn.mozillademos.org/files/14867/ClassePersonne.png" style="height: 216px; width: 604px;"></p>
+
+<p>Dans plusieurs langages de POO, la définition d'un objet est appelé une <strong>classe </strong>(comme on le verra ci-après, JavaScript se base sur un mécanisme et une terminologie différente). En réalité ce n'est pas vraiment un objet mais plutôt un modèle qui définit les propriétés que notre objet doit avoir.</p>
+
+<h3 id="Créons_des_objets">Créons des objets</h3>
+
+<p>À partir de notre classe, nous pouvons créer des objets, on parle alors d'<strong>instancier des objets</strong>, une classe objet a alors <strong>une instance</strong>. Il s'agit d'objets qui contiennent les données et attributs définis dans une classe. À partir de notre classe Personne, nous pouvons modéliser des personnes réelles :</p>
+
+<p><img alt="Instantiation on a Personn Class for JS examples (fr)" src="https://mdn.mozillademos.org/files/14869/InstancePersonne.png" style="height: 716px; width: 699px;"></p>
+
+<p>Lorsque l'instance d'un objet est créée, on appelle la <strong>fonction</strong> <strong>constructeur </strong>de la classe pour la créer. On parle d'<strong>instanciation</strong> d'un objet — l'objet ainsi créé est <strong>instancié</strong> à partir de la classe.</p>
+
+<h3 id="Classes_filles">Classes filles</h3>
+
+<p>Pour notre exemple, nous n'allons pas nous contenter de personnes génériques — nous pourrions utiliser des professeurs, des étudiants, qui sont des types un peu plus spécifiques de personnes. En POO, il est possible de créer de nouvelles classes à partir d'autres classes — ces <strong>classes filles</strong> nouvellement créées peuvent <strong>hériter</strong> des propriétés et des attributs de leur <strong>classe mère</strong>. Il est donc possible d'avoir des attributs partagés à l'ensemble des classes plutôt que de les dupliquer. Si besoin, il est possible d'ajouter des fonctions et attributs spécifiques sur chaque classe fille.</p>
+
+<p><img alt="Inheritance principle with French text for JS example" src="https://mdn.mozillademos.org/files/14887/HeritageClasse.PNG" style="height: 709px; width: 696px;"></p>
+
+<p>Cela s'avère très utile puisque les étudiants et les professeurs se ressemblent sur de nombreux aspects : ils ont un nom, un genre, un âge, il est donc utile de ne définir ces attributs qu'une seule fois. Il est aussi possible de redéfinir le même attribut dans différentes classes étant donné que l'attribut appartiendra à chaque fois à un nom d'espace différent. On pourra ainsi avoir différentes formes de salutations : « Hey, je m'appelle [prénom] » pour les étudiants ( « Hey je m'appelle Sam » ) tandis que les professeurs pourront dire quelque chose d'un peu plus formel comme « Bonjour, mon nom est [Titre][Nom] et j'enseigne [matière] » par exemple « Bonjour mon nom est M. Griffiths et j'enseigne la chimie ».</p>
+
+<div class="note">
+<p><strong>Note </strong>: On parle de <strong>polymorphisme</strong>, lorsque des objets réutilisent la même propriété,  mais c'est juste pour info, vous embêtez pas.</p>
+</div>
+
+<p>Une fois la classe fille créée il est alors possible de l'instancier et de créer des objets. Par exemple :</p>
+
+<p><img alt="Professor instantiation example for JS fr" src="https://mdn.mozillademos.org/files/14889/InstanceProf.png" style="height: 703px; width: 696px;"></p>
+
+<p>Dans la suite de l'article, nous nous intéresserons à la mise en œuvre de la programmation orientée objet (POO) au sein de JavaScript.</p>
+
+<h2 id="Constructeurs_et_instances_dobjet">Constructeurs et instances d'objet</h2>
+
+<p>Certains disent que le JavaScript n'est pas vraiment un langage de programmation orienté objet — Il n'existe pas, en JavaScript d'élément <code>class</code> pour créer des classes alors que c'est le cas dans plusieurs langages orientés objet. JavaScript quant à lui, utilise des fonctions spéciales appelées <strong>constructeurs</strong> pour définir les objets et leurs propriétés. Ces constructeurs s'avèrent utiles, puisque bien souvent, nous ne savons pas combien d'objets nous allons définir, les constructeurs nous permettent de créer autant d'objets que nécessaire et d'y associer des données et des fonctions au fur et à mesure.</p>
+
+<p>Lorsqu'un objet est instancié à partir d'une fonction constructeur, les fonctions de la classe ne sont pas copiées directement dans l'objet comme dans la plupart des langages orientés objet (OO). En JavaScript, les fonctions sont liées grâce à une chaîne de référence appelée chaîne prototype (voir <a href="/fr/docs/Learn/JavaScript/Objects/Object_prototypes">Prototypes Objet</a>). Il ne s'agit donc pas d'une véritable instanciation au sens strict puisque JavaScript utilise un mécanisme différent pour partager des fonctionnalités entre les objets.</p>
+
+<div class="note">
+<p><strong>Note</strong> : Ne pas être un "langage classique de POO" n'est pas nécessairement un défaut. Comme nous le mentionnions au début de l'article, la POO peut très vite devenir compliquée et JavaScript, grâce à ses différences parvient à utiliser certains concepts avancés tout en restant abordable.</p>
+</div>
+
+<p>Voyons comment créer des classes via les constructeurs et les utiliser pour instancier des objets en JavaScript. Nous allons commencer par faire une copie locale du fichier <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/introduction/oojs.html">oojs.html</a> que nous avons vu dans notre premier article sur les objets.</p>
+
+<h3 id="Un_exemple_simple">Un exemple simple</h3>
+
+<ol>
+ <li>Tout d'abord ; voyons comment définir une personne au travers d'une fonction classique. Vous pouvez ajouter l'exemple ci-dessous dans votre code existant :
+ <pre class="brush: js">function creerNouvellePersonne(nom) {
+ var obj = {};
+ obj.nom = nom;
+ obj.salutation = function() {
+ alert('Salut ! Je m\'appelle ' + this.nom + '.');
+ };
+ return obj;
+}</pre>
+ </li>
+ <li>Vous pouvez désormais créer une personne en appelant cette fonction, essayez en copiant les lignes suivantes dans la console JavaScript de votre navigateur :
+ <pre class="brush: js">var salva = creerNouvellePersonne('Salva');
+salva.nom;
+salva.salutation();</pre>
+ Ça fonctionne bien, mais on peut améliorer notre exemple. Si l'on sait que l'on va créer un objet, pourquoi créer un objet vide pour l'utiliser ensuite ? Heureusement, JavaScript est là et possède des fonctions adaptées comme les constructeurs. À l'abordage !</li>
+ <li>Remplacez la fonction précédente par celle-ci :
+ <pre class="brush: js">function Personne(nom) {
+ this.nom = nom;
+ this.salutation = function() {
+ alert('Bonjour ! Je m\'appelle ' + this.nom + '.');
+ };
+}</pre>
+ </li>
+</ol>
+
+<p>Le constructeur est l'équivalent JavaScript d'une classe. Il possède l'ensemble des fonctionnalités d'une fonction, cependant il ne renvoie rien et ne crée pas d'objet explicitement. Il se contente de définir les propriétés et les méthodes associées. Il y a aussi l'utilisation du mot-clé <code>this</code>, ce mot-clé sert au sein d'une instance qui sera créée à y faire référence, ainsi l'attribut nom sera, pour l'instance, égal au nom passé en argument de la fonction constructrice, la méthode <code>salutation</code><code>()</code> retournera elle aussi le nom passé en argument de la fonction constructrice.</p>
+
+<div class="note">
+<p><strong>Note </strong>: Les fonctions de type constructeur commencent généralement par une majuscule. Cette convention d'écriture permet de repérer les constructeurs plus facilement dans le code.</p>
+</div>
+
+<p>Comment pouvons-nous utiliser un constructeur ?</p>
+
+<ol>
+ <li>Ajoutez les lignes suivantes au code déjà existant :
+ <pre class="brush: js">var personne1 = new Personne('Bob');
+var personne2 = new Personne('Sarah');</pre>
+ </li>
+ <li>Enregistrez votre code et relancez le dans votre navigateur puis essayez d'entrer les lignes suivantes dans la console :
+ <pre class="brush: js">personne1.nom
+personne1.salutation()
+personne2.nom
+personne2.salutation()</pre>
+ </li>
+</ol>
+
+<p>Pas mal ! Vous voyez désormais que nous avons deux nouveaux objets sur cette page, chaque objet étant stocké dans un espace de nom différent, pour y accéder il faut utiliser <code>personne1</code> et <code>personne2</code> pour préfixer les fonctions et attributs. Ce rangement permet de ne pas tout casser et de ne pas rentrer en collision avec d'autres fonctionnalités. Cependant les objets disposent du même attribut <code>nom</code> et de la même méthode <code>salutation()</code>. Heureusement, les attributs et les méthodes utilisent <code>this</code> ce qui leur permet d'utiliser les valeurs propres à chaque instance et de ne pas les mélanger.</p>
+
+<p>Revoyons l'appel au constructeur :</p>
+
+<pre class="brush: js">var personne1 = new Personne('Bob');
+var personne2 = new Personne('Sarah');</pre>
+
+<p>Dans chaque cas, le mot clé <code>new</code> est utilisé pour dire au navigateur que nous souhaitons définir une nouvelle instance, il est suivi du nom de la fonction que l'on utilise et de ses paramètres fournis entre parenthèses, le résultat est stocké dans une variable. Chaque instance est créée à partir de cette définition :</p>
+
+<pre class="brush: js">function Personne(nom) {
+ this.nom = nom;
+ this.salutation = function() {
+ alert('Bonjour ! Je m\'appelle ' + this.nom + '.');
+ };
+}</pre>
+
+<p>Une fois les objets créés, les variables <code>personne1</code> et <code>personne2</code> contiennent les objets suivants :</p>
+
+<pre class="brush: js">{
+ nom: 'Bob',
+ salutation: function() {
+ alert('Bonjour ! Je m\'appelle ' + this.nom + '.');
+ }
+}
+
+{
+ nom: 'Sarah',
+ salutation: function() {
+ alert('Bonjour ! Je m\'appelle ' + this.nom + '.');
+ }
+}</pre>
+
+<p>On peut remarquer qu'à chaque appel de notre fonction constructrice nous définissons <code>salutation()</code> à chaque fois. Cela peut être évité via la définition de la fonction au sein du prototype, ce que nous verrons plus tard.</p>
+
+<h3 id="Créons_une_version_finalisée_de_notre_constructeur">Créons une version finalisée de notre constructeur</h3>
+
+<p>L'exemple que nous avons utilisé jusqu'à présent était destiné à aborder les notions de base des constructeurs. Créons un constructeur digne de ce nom pour notre fonction constructrice <code>Personne()</code>.</p>
+
+<ol>
+ <li>Vous pouvez retirer le code que vous aviez ajouté précédemment pour le remplacer par le constructeur suivant, c'est la même fonction, ça reste un constructeur, nous avons juste ajouté quelques détails :
+ <pre class="brush: js">function Personne(prenom, nom, age, genre, interets) {
+ this.nom = {
+ prenom,
+ nom
+ };
+ this.age = age;
+ this.genre = genre;
+ this.interets = interets;
+ this.bio = function() {
+ alert(this.nom.prenom + ' ' + this.nom.nom + ' a ' + this.age + ' ans. Il aime ' + this.interets[0] + ' et ' + this.interets[1] + '.');
+ };
+ this.salutation = function() {
+ alert('Bonjour ! Je m\'appelle ' + this.nom.prenom + '.');
+ };
+};</pre>
+ </li>
+ <li>Vous pouvez ajouter la ligne ci-dessous pour créer une instance à partir du constructeur :
+ <pre class="brush: js">var personne1 = new Personne('Bob', 'Smith', 32, 'homme', ['musique', 'ski']);</pre>
+ </li>
+</ol>
+
+<p>Vous pouvez accéder aux fonctions des objets instanciés de la même manière qu'avant :</p>
+
+<pre class="brush: js">personne1['age']
+personne1.interets[1]
+personne1.bio()
+// etc.</pre>
+
+<div class="note">
+<p><strong>Note</strong> : Si vous avez du mal à faire fonctionner cet exemple, vous pouvez comparez votre travail avec notre version (voir <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/introduction/oojs-class-finished.html">oojs-class-finished.html</a> (vous pouvez aussi jeter un œil à la <a href="https://mdn.github.io/learning-area/javascript/oojs/introduction/oojs-class-finished.html">démo</a>)</p>
+</div>
+
+<h3 id="Exercices">Exercices</h3>
+
+<p>Vous pouvez démarrer en instanciant de nouveaux objets puis en essayant de modifier et d'accéder à leurs attributs respectifs.</p>
+
+<p>D'autre part, il y a quelques améliorations possibles pour notre méthode <code>bio().</code> En effet elle affiche systématiquement le pronom 'il', même si votre personne est une femme ou bien préfère se définir par un autre genre. De plus, la biographie n'inclut que deux passions, même s'il y en a plus dans la liste. Essayez d'améliorer cette méthode. Vous pourrez mettre votre code à l'intérieur du constructeur (vous aurez probablement besoin de quelques structures conditionnelles et d'une boucle). Réflechissez à la syntaxe des phrases qui devra s'adapter en fonction du genre et du nombre de passions listées.</p>
+
+<div class="note">
+<p><strong>Note</strong>: Si vous êtes bloqués, nous avons mis une réponse possible sur notre dépôt <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/introduction/oojs-class-further-exercises.html">GitHub </a>(<a href="https://mdn.github.io/learning-area/javascript/oojs/introduction/oojs-class-further-exercises.html">la démo</a>) —tentez d'abord l'aventure avant d'aller regarder la réponse !</p>
+</div>
+
+<h2 id="Dautres_manières_dinstancier_des_objets">D'autres manières d'instancier des objets</h2>
+
+<p>Jusque là nous n'avons abordé que deux manières différentes pour créer une instance d'objet, la déclarer de manière explicite et en utilisant le constructeur.</p>
+
+<p>Elles sont toutes les deux valables, mais il en existe d'autres. Afin que vous les reconnaissiez lorsque vous vous baladez sur le Web, nous en avons listées quelques unes.</p>
+
+<h3 id="Le_constructeur_Object">Le constructeur Object()</h3>
+
+<p>Vous pouvez en premier lieu utiliser le constructeur <code><a href="/fr/docs/Web/JavaScript/Reference/Global_Objects/Object">Object()</a></code> pour créer un nouvel objet. Oui, même les objets génériques ont leur propre constructeur, qui génère un objet vide.</p>
+
+<ol>
+ <li>Essayez la commande suivante dans la console JavaScript de votre navigateur :
+ <pre class="brush: js">var personne1 = new Object();</pre>
+ </li>
+ <li>On stocke ainsi un objet vide dans la variable personne1. Vous pouvez ensuite ajouter des attributs et des méthodes à cet objet en utilisant la notation point ou parenthèses comme vous le souhaitez.
+ <pre class="brush: js">personne1.nom = 'Chris';
+personne1['age'] = 38;
+personne1.salutation = function() {
+ alert('Bonjour ! Je m\'appelle ' + this.nom + '.');
+};</pre>
+ </li>
+ <li>Vous pouvez aussi passer un objet en paramètre du constructeur <code>Object()</code>, afin de prédéfinir certains attributs et méthodes.
+ <pre class="brush: js">var personne1 = new Object({
+ nom: 'Chris',
+ age: 38,
+ salutation: function() {
+ alert('Bonjour ! Je m\'appelle ' + this.nom + '.');
+ }
+});</pre>
+ </li>
+</ol>
+
+<h3 id="Via_la_méthode_create">Via la méthode create()</h3>
+
+<p>Les constructeurs permettent de structurer le code : vous pouvez avoir l'ensemble de vos constructeurs au même endroit et ensuite créer les instances suivant vos besoins, en identifiant clairement leur origine.  </p>
+
+<p>Cependant, on peut vouloir créér des instances d'un objet, sans forcément définir un constructeur au préalable. (Particulierement si l'on a peu d'instances de cet object). JavaScript intègre directement une méthode appelée <code><a href="/fr/docs/Web/JavaScript/Reference/Global_Objects/Object/create">create()</a></code> qui rend cela possible. Elle permet d'instancier un objet à partir d'un objet existant  .</p>
+
+<ol>
+ <li>Essayez d'ajouter la ligne suivante dans votre console JavaScript :
+ <pre class="brush: js">var personne2 = Object.create(personne1);</pre>
+ </li>
+ <li>Maintenant :
+ <pre class="brush: js">personne2.nom
+personne2.salutation()</pre>
+ </li>
+</ol>
+
+<p><code>personne2</code> a été créée à partir de <code>personne1</code> — et elle possède les mêmes propriétés. </p>
+
+<p>L'inconvénient de <code>create()</code> est qu'elle n'est pas supportée par IE8. Ainsi, utiliser les constructeurs peut s'avérer plus judicieux lorsqu'il s'agit de supporter les anciens navigateurs Web.</p>
+
+<p>Nous verrons les détails et les effets de <code>create()</code> plus tard.</p>
+
+<h2 id="Résumé">Résumé</h2>
+
+<p>Cet article vous a donné un aperçu simplifié de la programmation orientée objet. Tout n'y a pas été détaillé mais ça vous permet de vous faire une idée. Nous avons vu comment JavaScript s'appuyait sur un certain nombre de principes orienté objet tout en ayant un certain nombre de particularités. Nous avons aussi vu comment implémenter des classes en JavaScript via la fonction constructeur ainsi que les différentes manières de générer des instances d'objets.</p>
+
+<p>Dans le prochain article, nous explorerons le monde des objets prototypes en JavaScript.</p>
+
+<p>{{PreviousMenuNext("Learn/JavaScript/Objects/Basics", "Learn/JavaScript/Objects/Object_prototypes", "Learn/JavaScript/Objects")}}</p>
diff --git a/files/fr/learn/javascript/objects/json/index.html b/files/fr/learn/javascript/objects/json/index.html
new file mode 100644
index 0000000000..b06c79006d
--- /dev/null
+++ b/files/fr/learn/javascript/objects/json/index.html
@@ -0,0 +1,338 @@
+---
+title: Manipuler des données JSON
+slug: Learn/JavaScript/Objects/JSON
+tags:
+ - Apprendre
+ - Article
+ - Débutant
+ - JSON
+ - JavaScript
+ - Manuel
+ - Objets
+ - Tutoriel
+translation_of: Learn/JavaScript/Objects/JSON
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/JavaScript/Objects/Inheritance", "Learn/JavaScript/Objects/Object_building_practice", "Learn/JavaScript/Objects")}}</div>
+
+<p class="summary">Le JavaScript Object Notation (JSON) est un format standard utilisé pour représenter des données structurées de façon semblable aux objets Javascript. Il est habituellement utilisé pour structurer et transmettre des données sur des sites web (par exemple, envoyer des données depuis un serveur vers un client afin de les afficher sur une page web ou vice versa). Comme cette notation est extrêmement courante, cet article a pour but de vous donner les connaissances nécessaires pour travailler avec JSON en JavaScript, vous apprendre à analyser la syntaxe du JSON afin d'en extraire des données et écrire vos propres objets JSON.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Prérequis :</th>
+ <td>Vocabulaire de base d'informatique, connaissances de base en HTML et CSS, connaissances de base en JavaScript (voir <a href="/en-US/docs/Learn/JavaScript/First_steps">Premiers pas</a> et <a href="/en-US/docs/Learn/JavaScript/Building_blocks">Les blocs</a>) et en Javascript orienté objets (voir <a href="/en-US/docs/Learn/JavaScript/Object-oriented/Introduction">Introduction aux objets</a>).</td>
+ </tr>
+ <tr>
+ <th scope="row">Objectif :</th>
+ <td>Comprendre comment utiliser les données stockées dans un objet JSON, et créer vos propres objets JSON.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Plus_sérieusement_quest_ce_que_le_JSON">Plus sérieusement, qu'est ce que le JSON ?</h2>
+
+<p>{{glossary("JSON")}} est un format de données semblable à la syntaxe des objets JavaScript, qui a été popularisé par <a href="https://en.wikipedia.org/wiki/Douglas_Crockford">Douglas Crockford</a>. Malgré sa syntaxe très similaire à celle des objets littéraux JavaScript, JSON peut être utilisé indépendamment de ce langage et ainsi, de nombreux autres langages de programmation disposent de fonctionnalités permettant d'analyser la syntaxe du JSON et d'en générer.</p>
+
+<p>Le JSON se présente sous la forme  d'une chaîne de caractères —utile lorsque vous souhaitez transmettre les données sur un réseau. Il a donc besoin d'être converti en un objet JavaScript natif lorsque vous souhaitez accéder aux données. Ce n'est pas vraiment un souci puisque le JavaScript fournit un objet global <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON">JSON</a> disposant des méthodes pour assurer la conversion entre les deux.</p>
+
+<div class="note">
+<p><strong>Note </strong>: Convertir une chaîne de caractères en un objet natif se nomme <strong>analyse syntaxique (parsage)</strong> tandis que le contraire porte le nom  de la <strong>linéarisation (stringification)</strong>.</p>
+</div>
+
+<p>Un objet JSON peut être stocké dans son propre fichier qui se présente simplement sous la forme d'un fichier texte avec l'extension <code>.json</code> et le {{glossary("MIME type")}} <code>application/json</code>.</p>
+
+<h3 id="Structure_du_JSON">Structure du JSON</h3>
+
+<p>Nous disions tout à l'heure qu'un objet JSON n'était ni plus ni moins qu'un objet Javascript tout à fait normal et c'est généralement le cas. Un objet JSON accepte comme valeur les mêmes types de données de base que tout autre objet Javascript — chaînes de caractères, nombres, tableaux, booléens et tout autre objet littéral. Cela vous permet de hiérarchiser vos données comme ceci :</p>
+
+<pre class="brush: json">{
+  "squadName": "Super hero squad",
+  "homeTown": "Metro City",
+  "formed": 2016,
+  "secretBase": "Super tower",
+ "active": true,
+  "members": [
+    {
+      "name": "Molecule Man",
+      "age": 29,
+      "secretIdentity": "Dan Jukes",
+      "powers": [
+        "Radiation resistance",
+        "Turning tiny",
+        "Radiation blast"
+      ]
+    },
+    {
+      "name": "Madame Uppercut",
+      "age": 39,
+      "secretIdentity": "Jane Wilson",
+      "powers": [
+        "Million tonne punch",
+        "Damage resistance",
+        "Superhuman reflexes"
+      ]
+    },
+    {
+      "name": "Eternal Flame",
+      "age": 1000000,
+      "secretIdentity": "Unknown",
+      "powers": [
+        "Immortality",
+        "Heat Immunity",
+        "Inferno",
+        "Teleportation",
+        "Interdimensional travel"
+      ]
+    }
+  ]
+}</pre>
+
+<p>Si nous chargeons cet objet dans un fichier Javascript au sein d'une variable appelée <code>superHeroes</code> par exemple, nous pouvons accéder à ses données de la même façon que nous l'avons fait dans l'article <a href="/fr/docs/Learn/JavaScript/Objects/Basics">Les bases de JavaScript orienté objets</a> à l'aide de la notation point / crochets. Par exemple :</p>
+
+<pre class="brush: js">superHeroes.hometown
+superHeroes['active']</pre>
+
+<p>Pour accéder aux données plus profondes de la hiérarchie, vous n'avez qu'à enchaîner à la fois les noms des propriétés et les indexes des tableaux. Par exemple, l'expression suivante pointe vers le troisième superpouvoir du second super héros présent dans la liste :</p>
+
+<pre class="brush: js">superHeroes['members'][1]['powers'][2]</pre>
+
+<ol>
+ <li>D'abord, nous partons de la variable — <code>superHeroes</code></li>
+ <li>À l'intérieur de laquelle nous désirons accéder à la propriété <code>members</code>, donc, nous tapons <code>["members"]</code>.</li>
+ <li><code>members</code> contient un tableau renfermant des objets. Nous désirons accéder au second de ces objets, donc nous utilisons <code>[1]</code>.</li>
+ <li>À l'intérieur de cet objet, nous souhaitons accéder à la propriété <code>powers</code>, donc, nous utilisons <code>["powers"]</code>.</li>
+ <li>Enfin, à l'intérieur de cette propriété <code>powers</code> nous trouvons un nouveau tableau qui contient les super pouvoirs de ce héros. Nous désirons obtenir le troisième, donc nous tapons <code>[2]</code>.</li>
+</ol>
+
+<div class="note">
+<p><strong>Note </strong>: L'objet JSON vu ci-dessus est disponible au sein d'une variable dans notre exemple <a href="http://mdn.github.io/learning-area/javascript/oojs/json/JSONTest.html">JSONTest.html</a> (voir le <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/json/JSONTest.html">code source</a>). Essayez de le charger et d'accéder aux données en utilisant la console Javascript de votre navigateur.</p>
+</div>
+
+<h3 id="Des_tableaux_en_tant_que_JSON">Des tableaux en tant que JSON</h3>
+
+<p>Un peu plus haut, nous avons dit qu'un objet JSON n'était ni plus ni moins qu'un objet Javascript tout à fait normal et c'est généralement le cas. La raison pour laquelle nous avons dit "généralement le cas" est qu'un tableau peut également être un objet JSON valide, par exemple :</p>
+
+<pre class="brush: json">[
+ {
+ "name": "Molecule Man",
+ "age": 29,
+ "secretIdentity": "Dan Jukes",
+ "powers": [
+ "Radiation resistance",
+ "Turning tiny",
+ "Radiation blast"
+ ]
+ },
+ {
+    "name": "Madame Uppercut",
+    "age": 39,
+    "secretIdentity": "Jane Wilson",
+    "powers": [
+      "Million tonne punch",
+      "Damage resistance",
+      "Superhuman reflexes"
+    ]
+  }
+]</pre>
+
+<p>Le code ci dessus est une notation JSON parfaitement valide. Vous n'aurez qu'à accéder aux éléments de votre tableau en commençant avec un index, par exemple : <code>[0]["powers"][0]</code>.</p>
+
+<h3 id="Notes_diverses">Notes diverses</h3>
+
+<ul>
+ <li>Un objet JSON est uniquement un format de données — il ne contient que des propriétés mais pas de méthodes.</li>
+ <li>La notation JSON nécessite l'usage des guillemets pour être valide. Il est obligatoire d'utiliser des guillemets et non les apostrophes autour des chaînes de caractères et des noms de propriétés.</li>
+ <li>Une simple virgule ou un double point mal placé peut rendre votre fichier JSON invalide et non fonctionnel. Soyez très attentif aux données que vous utilisez (bien que le JSON généré automatiquement par un programme sera moins enclin à contenir des erreurs, à partir du moment où le programme est codé correctement). Vous pouvez utiliser une application comme <a href="http://jsonlint.com/">JSONLint</a> pour valider votre code JSON.</li>
+ <li>Dans l'absolu, le JSON peut prendre la forme de n'importe quel type de données qui serait valide pour être contenu dans du JSON et non juste des tableaux ou des objets. Ainsi, par exemple, une simple chaîne de caractères ou un nombre serait un objet JSON valide.</li>
+ <li>Contrairement au JavaScript dans lequel les propriétés (<em>keys</em>) non entourées de guillemets peuvent être utilisées, en JSON, seules les chaînes de caractères entourées de guillemets peuvent être utilisées en tant que propriétés.</li>
+</ul>
+
+<h2 id="Activité_Manipuler_le_JSON_au_travers_dun_exemple">Activité : Manipuler le JSON au travers d'un exemple</h2>
+
+<p>Allez ! Un petit exemple pour voir comment nous pouvons nous servir de données JSON sur un site web.</p>
+
+<h3 id="Lançons_nous">Lançons nous</h3>
+
+<p>Pour commencer, faites une copie locale de nos fichiers <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/json/heroes.html">heroes.html</a> et <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/json/style.css">style.css</a>. Le dernier contient simplement quelques instructions CSS pour la mise en forme de notre page alors que le premier n'est ni plus ni moins qu'un squelette HTML de base :</p>
+
+<pre class="brush: html">&lt;header&gt;
+&lt;/header&gt;
+
+&lt;section&gt;
+&lt;/section&gt;</pre>
+
+<p>Nous trouvons également un élément {{HTMLElement("script")}} dans lequel nous écrirons le code Javascript de cet exercice. Pour le moment, il ne contient que deux lignes destinées à récuperer les éléments {{HTMLElement("header")}} et {{HTMLElement("section")}} pour les stocker dans des variables :</p>
+
+<pre class="brush: js">var header = document.querySelector('header');
+var section = document.querySelector('section');</pre>
+
+<p>Nos données JSON sont disponibles sur notre GitHub ici : <a href="https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json">https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json</a>.</p>
+
+<p>Nous souhaitons les récupérer et, après quelques manipulations du DOM, les afficher comme ceci :</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/13857/json-superheroes.png" style="display: block; margin: 0 auto;"></p>
+
+<h3 id="Chargeons_notre_JSON">Chargeons notre JSON</h3>
+
+<p>Pour charger nos données JSON, nous allons utiliser l'API {{domxref("XMLHttpRequest")}} (qu'on appelle plus couramment <strong>XHR</strong>). Il s'agit d'un objet JavaScript extrêmement utile qui nous permet de construire une requête afin d'interroger un serveur pour obtenir des ressources diverses (images, texte, JSON, ou n'importe quel extrait HTML) le tout en Javascript. En d'autres termes, cela nous permet de mettre à jour de petites sections de contenu sans avoir à recharger notre page toute entière. Ceci conduit à des pages web plus réactives. Mais même si le sujet est très tentant, il dépasse largement l'objet de cet article pour être expliqué plus en détails.</p>
+
+<ol>
+ <li>Donc, pour commencer, nous allons charger l'URL du fichier JSON que nous voulons récupérer dans une variable. Aussi, ajouter la ligne suivante à votre code Javascript :
+ <pre class="brush: js">var requestURL = 'https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json';</pre>
+ </li>
+ <li>Afin de créer une requête, nous avons besoin d'instancier un nouvel objet <code>XMLHttpRequest</code> à partir de son constructeur en utilisant le mot clé new. Ajouter la ligne suivante à votre script :
+ <pre class="brush: js">var request = new XMLHttpRequest();</pre>
+ </li>
+ <li>Maintenant, nous avons besoin d'ouvrir une nouvelle requête grâce à la méthode <code><a href="/en-US/docs/Web/API/XMLHttpRequest/open">open()</a></code>. Ajoutez la ligne suivante :
+ <pre class="brush: js">request.open('GET', requestURL);</pre>
+
+ <p>Cette méthode prend au moins deux paramètres — il y a d'autres paramètres optionnels disponibles.  Deux suffiront pour notre exemple :</p>
+
+ <ul>
+ <li>La méthode HTTP à utiliser sur le réseau pour notre requête. Dans notre cas, la méthode <code><a href="/en-US/docs/Web/HTTP/Methods/GET">GET</a></code> est appropriée dans la mesure où nous voulons simplement récupérer quelques données.</li>
+ <li>L'URL où adresser notre requête — il s'agit de l'URL du fichier JSON dont nous parlions tout à l'heure.</li>
+ </ul>
+ </li>
+ <li>Ensuite, ajoutez les deux lignes suivantes — ici, nous attribuons la valeur <code>'json'</code><strong> </strong>à  <code><a href="/en-US/docs/Web/API/XMLHttpRequest/responseType">responseType</a></code>, signalant ainsi au serveur que nous attendons une réponse au format JSON. Puis, nous envoyons notre requête à l'aide de la méthode <code><a href="/en-US/docs/Web/API/XMLHttpRequest/send">send()</a></code> :
+ <pre class="brush: js">request.responseType = 'json';
+request.send();</pre>
+ </li>
+ <li>La dernière partie de cette section concerne la réponse du serveur et son traitement. Ajoutez les lignes suivantes à la fin de votre code :
+ <pre class="brush: js">request.onload = function() {
+ var superHeroes = request.response;
+ populateHeader(superHeroes);
+ showHeroes(superHeroes);
+}</pre>
+ </li>
+</ol>
+
+<p>Ici, nous stockons la réponse à notre requête (disponible au travers de la propriété <code><a href="/en-US/docs/Web/API/XMLHttpRequest/response">response</a></code>) dans la variable <code>superHeroes</code> ; cette variable contiendra désormais l'objet JavaScript basé sur le JSON ! Nous passerons ensuite cet objet en paramètre à deux fonctions — la première remplira le &lt;<code>header&gt;</code> avec les données correspondantes tandis que la seconde créera une carte d'identité pour chaque héros de l'équipe et l'ajoutera dans la <code>&lt;section&gt;</code>.</p>
+
+<p>Nous avons encapsulé ce code dans un gestionnaire d'évènements qui s'exécutera quand l'évènement load sera déclenché sur l'objet request (voir <code><a href="/en-US/docs/Web/API/XMLHttpRequestEventTarget/onload">onload</a></code>) — simplement parce que l'évènement load est déclenché quand une réponse a été renvoyée avec succès ; en procédant de la sorte, nous serons certains que la propriété <code>request.response</code> sera disponible au moment où nous essayerons d'en faire quelque chose.</p>
+
+<h3 id="Remplissage_de_len-tête">Remplissage de l'en-tête</h3>
+
+<p>Maintenant que nous avons récupéré et converti en objet JavaScript nos données JSON, il est temps d'en faire bon usage : implémentons donc les deux fonctions évoquées ci-dessus. Avant tout, ajoutons les lignes suivantes en dessous de notre code :</p>
+
+<pre class="brush: js">function populateHeader(jsonObj) {
+ var myH1 = document.createElement('h1');
+ myH1.textContent = jsonObj['squadName'];
+ header.appendChild(myH1);
+
+ var myPara = document.createElement('p');
+ myPara.textContent = 'Hometown: ' + jsonObj['homeTown'] + jsonObj['formed'];
+ header.appendChild(myPara);
+}</pre>
+
+<p>Nous avons appelé le paramètre de cette fonction <code>jsonObj</code>  afin de garder en tête que cet objet JavaScript provient du JSON. Ici, nous créons tout d'abord un élément {{HTMLElement("h1")}} à l'aide de <code><a href="/en-US/docs/Web/API/Document/createElement">createElement()</a></code>, nous fixons son <code><a href="/en-US/docs/Web/API/Node/textContent">textContent</a></code> à la valeur de la propriété <code>squadName</code> de l'objet, puis nous l'ajoutons à l'en-tête en utilisant <code><a href="/en-US/docs/Web/API/Node/appendChild">appendChild()</a></code>. Ensuite, nous faisons quelque chose de relativement similaire avec un élément paragraphe : nous le créons, fixons son contenu et l'ajoutons à l'en-tête. La seule différence est que pour son contenu, nous avons concaténé la chaîne de caractère <code>homeTown</code> et la propriété <code>formed</code> de l'objet.</p>
+
+<h3 id="Création_des_fiches_des_héros">Création des fiches des héros</h3>
+
+<p>Maintenant, ajoutons la fonction suivante qui crée et affiche les fiches de nos super-héros en dessous de notre code :</p>
+
+<pre class="brush: js">function showHeroes(jsonObj) {
+ var heroes = jsonObj['members'];
+
+ for (var i = 0; i &lt; heroes.length; i++) {
+ var myArticle = document.createElement('article');
+ var myH2 = document.createElement('h2');
+ var myPara1 = document.createElement('p');
+ var myPara2 = document.createElement('p');
+ var myPara3 = document.createElement('p');
+ var myList = document.createElement('ul');
+
+ myH2.textContent = heroes[i].name;
+ myPara1.textContent = 'Secret identity: ' + heroes[i].secretIdentity;
+ myPara2.textContent = 'Age: ' + heroes[i].age;
+ myPara3.textContent = 'Superpowers:';
+
+ var superPowers = heroes[i].powers;
+ for (var j = 0; j &lt; superPowers.length; j++) {
+ var listItem = document.createElement('li');
+ listItem.textContent = superPowers[j];
+ myList.appendChild(listItem);
+ }
+
+ myArticle.appendChild(myH2);
+ myArticle.appendChild(myPara1);
+ myArticle.appendChild(myPara2);
+ myArticle.appendChild(myPara3);
+ myArticle.appendChild(myList);
+
+ section.appendChild(myArticle);
+ }
+}</pre>
+
+<p>Pour commencer, on stocke la propriété <code>members</code> de l'objet JavaScript dans une nouvelle variable. Ce tableau contient plusieurs objets contenant les informations relatives à chaque héros.</p>
+
+<p>Maintenant, on utilise une <a href="/fr/docs/Apprendre/JavaScript/Building_blocks/Looping_code">boucle for</a> pour parcourir chaque object du tableau. Pour chaque cas, il faut :</p>
+
+<ol>
+ <li>Créer plusieurs nouveaux éléments : un <code>&lt;article&gt;</code>, un <code>&lt;h2&gt;</code>, trois <code>&lt;p&gt;</code>s, et un <code>&lt;ul&gt;</code>.</li>
+ <li>Mettre le <code>name</code> du héros actuel dans le <code>&lt;h2&gt;</code>.</li>
+ <li>Remplir les trois paragraphes avec leur <code>secretIdentity</code>, leur <code>age</code>, et une ligne nommée "Superpowers:" pour présenter la liste des super-pouvoirs.</li>
+ <li>Stocker la propriété <code>powers</code> dans une nouvelle variable nommée <code>superPowers</code> contenant un tableau listant les super-pouvoirs du héros actuel.</li>
+ <li>Utiliser une autre boucle <code>for</code> pour parcourir les super-pouvoirs du héros actuel — créer pour chacun d'entre eux un élément <code>&lt;li&gt;</code>, y placer le super-pouvoir et placer le <code>listItem</code> dans l'élément <code>&lt;ul&gt;</code> (<code>myList</code>) en utilisant <code>appendChild()</code>.</li>
+ <li>Pour finir, on ajoute <code>&lt;h2&gt;</code>, les <code>&lt;p&gt;</code>s et <code>&lt;ul&gt;</code> à <code>&lt;article&gt;</code> (<code>myArticle</code>), et on ajoute <code>&lt;article&gt;</code> à <code>&lt;section&gt;</code>. L'ordre d'ajout est important, c'est l'ordre dans lequel les éléments seront affichés dans le HTML.</li>
+</ol>
+
+<div class="note">
+<p><strong>Note </strong>: Si vous ne parvenez pas à faire fonctionner l'exemple, consultez notre code source <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/json/heroes-finished.html">heroes-finished.html</a> (ou regardez-le <a href="http://mdn.github.io/learning-area/javascript/oojs/json/heroes-finished.html">en action</a>.)</p>
+</div>
+
+<div class="note">
+<p><strong>Note </strong>: Si vous comprenez difficilement la notation avec un point/une accolade utilisée pour accéder au JSON, ouvrez le fichier <a href="http://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json">superheroes.json</a> dans un nouvel onglet ou dans votre éditeur de texte et consultez-le pendant la lecture de notre code Javascript. Vous pouvez également vous reporter à notre article <a href="/fr/docs/Learn/JavaScript/Objects/Basics">Les bases du JavaScript orienté objet</a> pour obtenir plus de détails sur la notation avec un point et avec une accolade.</p>
+</div>
+
+<h2 id="Conversion_entre_objets_et_textes">Conversion entre objets et textes</h2>
+
+<p>Dans l'exemple ci-dessus, accéder au JSON est simple, il suffit de définir la requête XHR pour renvoyer la réponse au format JSON en écrivant :</p>
+
+<pre class="brush: js">request.responseType = 'json';</pre>
+
+<p>Mais on n'a pas toujours cette chance — il est possible de recevoir la réponse JSON sous la forme d'une chaîne de caractères et il faut alors la convertir en objet. À l'inverse, lorsqu'on veut envoyer un objet JavaScript à travers le réseau il faut au préalable le convertir en JSON (une chaîne de caractères). Heureusement, ces deux problèmes sont tellement communs dans le développement web qu'un objet <a href="/fr/docs/Web/JavaScript/Reference/Objets_globaux/JSON">JSON</a> interne a été ajouté aux navigateurs depuis longtemps, contenant les deux méthodes suivantes :</p>
+
+<ul>
+ <li><code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse">parse()</a></code> qui accepte un objet JSON sous la forme d'une chaîne de caractères en paramètre et renvoie l'objet JavaScript correspondant.</li>
+ <li><code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify">stringify()</a></code> qui accepte un objet JavaScript  en paramètre et renvoie son équivalent sous la forme d'une chaîne de caractères JSON.</li>
+</ul>
+
+<p>Vous pouvez voir la première méthode en action dans notre exemple <a href="http://mdn.github.io/learning-area/javascript/oojs/json/heroes-finished-json-parse.html">heroes-finished-json-parse.html</a> (voir le <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/json/heroes-finished-json-parse.html">code source</a>) — C'est la même chose que pour l'exemple que nous avons écrit un peu plus tôt, à ceci près qu'on indique à la requête XHR de renvoyer la réponse en JSON sous forme de texte avant d'utiliser la méthode <code>parse()</code> pour la convertir en objet JavaScript. La partie du code correspondante se trouve ci-dessous :</p>
+
+<pre class="brush: js">request.open('GET', requestURL);
+request.responseType = 'text'; // now we're getting a string!
+request.send();
+
+request.onload = function() {
+ var superHeroesText = request.response; // get the string from the response
+ var superHeroes = JSON.parse(superHeroesText); // convert it to an object
+ populateHeader(superHeroes);
+ showHeroes(superHeroes);
+}</pre>
+
+<p>Comme vous pouvez le deviner, <code>stringify()</code> fait exactement le contraire. Essayez d'entrer les lignes ci-dessous une par une dans la console Javascript de votre navigateur pour voir la méthode en action :</p>
+
+<pre class="brush: js">var myJSON = { "name": "Chris", "age": "38" };
+myJSON
+var myString = JSON.stringify(myJSON);
+myString</pre>
+
+<p>On commence par créer un objet JavaScript puis on vérifie son contenu avant de le convertir en chaîne de caractères JSON avec <code>stringify()</code> — en sauvegardant au passage le résultat dans une nouvelle variable avant d'effectuer à nouveau une vérification du contenu.</p>
+
+<h2 id="Résumé">Résumé</h2>
+
+<p>Dans cet article, nous vous donnons un manuel simple pour utiliser le JSON dans vos programmes, incluant les méthodes de  création et d'analyse syntaxique (parsage)  du JSON  et d'accès aux données qu'il contient. Dans le prochain article, nous débuterons l'apprentissage du Javascript orienté objet.</p>
+
+<h2 id="Voir_aussi">Voir aussi</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON">La page de référence sur l'objet JSON</a></li>
+ <li><a href="/en-US/docs/Web/API/XMLHttpRequest">La page de référence sur l'objet XMLHttpRequest</a></li>
+ <li><a href="/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest">Utiliser XMLHttpRequest</a></li>
+ <li><a href="/en-US/docs/Web/HTTP/Methods">Les méthodes de requêtes HTTP </a></li>
+ <li><a href="http://json.org">Le site web officiel  avec un lien vers les normes de l' ECMA</a></li>
+</ul>
+
+<p>{{PreviousMenuNext("Learn/JavaScript/Objects/Inheritance", "Learn/JavaScript/Objects/Object_building_practice", "Learn/JavaScript/Objects")}}</p>
diff --git a/files/fr/learn/javascript/objects/la_construction_d_objet_en_pratique/index.html b/files/fr/learn/javascript/objects/la_construction_d_objet_en_pratique/index.html
new file mode 100644
index 0000000000..a2ab4270eb
--- /dev/null
+++ b/files/fr/learn/javascript/objects/la_construction_d_objet_en_pratique/index.html
@@ -0,0 +1,316 @@
+---
+title: La construction d'objet en pratique
+slug: Learn/JavaScript/Objects/la_construction_d_objet_en_pratique
+tags:
+ - Apprendre
+ - Article
+ - Canvas
+ - Débutant
+ - JavaScript
+ - Manuel
+ - Objets
+ - Tutoriel
+translation_of: Learn/JavaScript/Objects/Object_building_practice
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/JavaScript/Objects/JSON", "Learn/JavaScript/Objects/Adding_bouncing_balls_features", "Learn/JavaScript/Objects")}}</div>
+
+<p class="summary">Dans l'article précédent, nous avons passé en revue l'essentiel de la théorie de l'objet Javascript et sa syntaxe détaillée, vous donnant ainsi des bases solides sur lesquelles commencer. Dans le présent article nous plongeons dans un exercice pratique afin d'accroître votre savoir-faire dans la construction d'objets entièrement personnalisés donnant un résultat plutôt amusant et très coloré.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Pré-requis :</th>
+ <td>
+ <p>Connaissance basique de l'informatique, une compréhension basique du HTML et du CSS, une familiarité avec  les bases du JavaScript (voir <a href="/en-US/docs/Learn/JavaScript/First_steps">Premiers pas</a> et <a href="/en-US/docs/Learn/JavaScript/Building_blocks">Les blocs de construction</a>) et les bases de la programmation objet en JavaScript (voir <a href="/en-US/docs/Learn/JavaScript/Object-oriented/Introduction">Introduction aux objets</a>). </p>
+ </td>
+ </tr>
+ <tr>
+ <th scope="row">Objectif :</th>
+ <td>
+ <p>Acquérir plus de pratique dans l'utilisation des objets et des techniques orientées objet dans un contexte "monde réel".</p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Faisons_bondir_quelques_balles">Faisons bondir quelques balles</h2>
+
+<p>Dans cet article, nous écrirons une démo classique de "balles bondissantes", pour vous montrer à quel point les objets peuvent être utiles en JavaScript. Nos petites balles bondiront partout sur notre écran et changeront de couleurs lorsqu'elles se toucheront. L'exemple finalisé ressemblera un peu à ceci : </p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/13865/bouncing-balls.png" style="display: block; height: 614px; margin: 0px auto; width: 800px;"></p>
+
+<ol>
+</ol>
+
+<p>Cet exemple utilise l'<a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Drawing_graphics">API Canvas </a> pour dessiner les balles sur l'écran, et l'API <a href="/en-US/docs/Web/API/window/requestAnimationFrame">requestAnimationFrame</a>  pour animer l'ensemble de l'affichage — Nul besoin d'avoir une connaissance préalable de ces APIs, nous expérons qu'une fois cet article terminé, vous aurez envie d'en faire une exploration approfondie. Tout le long du parcours nous utiliserons certains objets formidables et vous montrerons nombre de techniques sympathiques comme des balles bondissantes sur les murs et la vérification de balles qui s'entrechoquent (encore connue sous l'appelation <strong>détection de collision</strong>).</p>
+
+<p>Pour commencer, faites des copies locales de nos fichiers <code><a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/bouncing-balls/index.html">index.html</a></code>, <code><a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/bouncing-balls/style.css">style.css</a></code>, et <code><a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/bouncing-balls/main.js">main.js</a></code>. Ces fichiers contiennent respectivement :</p>
+
+<ol>
+ <li>Un document  HTML très simple contenant un élément {{HTMLElement("h1")}} , un élément {{HTMLElement("canvas")}} pour dessiner nos balles dessus et des élements  pour appliquer notre CSS et notre JavaScript à notre HTML ;</li>
+ <li>Quelques styles très simples qui servent principalement à mettre en forme et placer le <code>&lt;h1&gt;</code>, et se débarasser de toutes barres de défilement ou de marges autour du pourtour de notre page (afin que cela paraisse plus sympathique et élégant) ;</li>
+ <li>Un peu de JavaScript qui sert à paramétrer l'élément  <code>&lt;canvas&gt;</code> et fournir les fonctions globalles que nous utiliserons.</li>
+</ol>
+
+<p>La première partie du script ressemble à ceci :</p>
+
+<pre class="brush: js">const canvas = document.querySelector('canvas');
+
+const ctx = canvas.getContext('2d');
+
+const width = canvas.width = window.innerWidth;
+const height = canvas.height = window.innerHeight;</pre>
+
+<p>Ce script prend une référence à l'élément  <code>&lt;canvas&gt;</code> et ensuite invoque la méthode  <code><a href="/en-US/docs/Web/API/HTMLCanvasElement/getContext">getContext()</a></code> sur lui, nous donnant ainsi un contexte sur lequel nous pouvons commencer à dessiner. La variable résultante  (<code>ctx</code>)  est l'objet qui représente directement la surface du Canvas où nous pouvons dessiner et qui nous permet de dessiner des formes 2D sur ce dernier. </p>
+
+<p>Après, nous configurons  les variables <code>width</code> (largeur) et <code>height</code>(hauteur),  et la largeur et la hauteur de l'élément canvas (représentés par les propriétés  <code>canvas.width</code> et <code>canvas.height</code> ) afin qu'elles soient identiques à la fenêtre du navigateur (la surface sur laquelle apparaît la page web— Ceci peut être tiré des propriétés {{domxref("Window.innerWidth")}} et {{domxref("Window.innerHeight")}}).</p>
+
+<p>Vous verrez qu'ici nous enchaînons les assignations des valeurs des différentes variables ensemble à des fins de rapidité. Ceci est parfaitement autorisé.</p>
+
+<p>Le dernier morceau du script ressemble à ceci :</p>
+
+<pre class="brush: js">function random(min, max) {
+ var num = Math.floor(Math.random() * (max - min + 1)) + min;
+ return num;
+}</pre>
+
+<p>Cette fonction prend deux nombres comme arguments, et renvoie un nombre compris entre les deux. </p>
+
+<h2 id="Modéliser_une_balle_dans_notre_programme">Modéliser une balle dans notre programme</h2>
+
+<p>Notre programme met en œuvre beaucoup de balles bondissant partout sur l'écran. Comme nos balles se comporteront toutes de la même façon, cela semble tout à fait sensé de les représenter avec un objet. Commençons donc en ajoutant le constructeur suivant à la fin de notre code.</p>
+
+<pre class="brush: js">function Ball(x, y, velX, velY, color, size) {
+  this.x = x;
+  this.y = y;
+  this.velX = velX;
+  this.velY = velY;
+  this.color = color;
+  this.size = size;
+}</pre>
+
+<p>Ici, nous incluons des paramètres qui définissent  des propriétés dont chaque balle aura besoin pour fonctionner dans notre programme :</p>
+
+<ul>
+ <li>Les coordonnées <code>x</code> et <code>y</code>  — les coordonnées verticales et horizontales où la balle débutera sur l'écran. Ceci peut se trouver entre 0 (coin à gauche en haut) et la valeur de la hauteur et de la largeur de la fenêtre du navigateur (coin en bas à droite).</li>
+ <li>Une vitesse horizontale et verticale (<code>velX</code> et <code>velY</code>) — à chaque balle est attribuée une vitesse horizontale et verticale; en termes réels ces valeurs seront régulièrement ajoutéés aux valeurs de la coordonnée <code>x</code>/<code>y</code> quand nous commencerons à animer les balles, afin de les faire bouger d'autant sur chaque vignette (frame).</li>
+ <li><code>color</code> — chaque balle a une couleur.</li>
+ <li><code>size</code> — chaque balle a une taille — ce sera son rayon mesuré en pixels.</li>
+</ul>
+
+<p>Ceci règle le problème des propriétés mais qu'en est il des méthodes ? Nous voulons maintenant amener nos balles à faire quelque chose dans notre programme.</p>
+
+<h3 id="Dessiner_la_balle">Dessiner la balle</h3>
+
+<p>En premier lieu ajoutez la méthode <code>draw()</code> au <code>prototype</code> de <code>Ball()</code> :</p>
+
+<pre class="brush: js">Ball.prototype.draw = function() {
+ ctx.beginPath();
+ ctx.fillStyle = this.color;
+ ctx.arc(this.x, this.y, this.size, 0, 2 * Math.PI);
+ ctx.fill();
+}</pre>
+
+<p>En utilisant cette fonction, nous pouvons dire à notre balle de se dessiner sur l'écran en appelant une série de membres du contexte 2D du canvas que nous avons défini plus tôt  (<code>ctx</code>). Le contexte est comme le papier et maintenant nous allons demander à notre stylo d'y dessiner quelque chose :</p>
+
+<ul>
+ <li>Premièrement, nous utilisons <code><a href="/en-US/docs/Web/API/CanvasRenderingContext2D/beginPath">beginPath()</a></code> pour spécifier que nous voulons dessiner une forme sur le papier.</li>
+ <li>Ensuite, nous utilisons <code><a href="/en-US/docs/Web/API/CanvasRenderingContext2D/fillStyle">fillStyle</a></code> pour définir de quelle couleur nous voulons que la forme soit — nous lui attribuons la valeur de la propriété <code>color</code> de notre balle.</li>
+ <li>Après, nous utilisons la méthode <code><a href="/en-US/docs/Web/API/CanvasRenderingContext2D/arc">arc()</a></code> pour tracer une forme en arc sur le papier. Ses paramètres sont :
+ <ul>
+ <li>Les positions <code>x</code> et <code>y</code> du centre de l'arc — nous specifions donc les propriétés <code>x</code> et <code>y </code>de notre balle.</li>
+ <li>Le rayon de l'arc — nous specifions la propriété <code>size</code> de notre balle.</li>
+ <li>Les deux derniers paramètres spécifient l'intervalle de début et de fin en degrés pour dessiner l'arc. Ici nous avons spécifié 0 degrés et <code>2 * PI </code>qui est l'équivalent de 360 degrés en radians (malheureusement  vous êtes obligés  de spécifier ces valeurs en radians et non en degrés). Cela nous donne un cercle complet. Si vous aviez spécifié seulement  <code>1 * PI</code>, vous auriez eu un demi-cercle (180 degrés).</li>
+ </ul>
+ </li>
+ <li>En dernière position nous utilisons la méthode <code><a href="/en-US/docs/Web/API/CanvasRenderingContext2D/fill">fill()</a></code> qui est habituellement utilisée pour spécifier que nous souhaitons mettre fin au dessin que nous avons commencé avec <code>beginPath()</code>, et remplir la surface délimitée avec la couleur que nous avions spécifiée plus tôt avec <code>fillStyle</code>.</li>
+</ul>
+
+<p>Vous pouvez déjà commencer à tester votre objet.</p>
+
+<ol>
+ <li>Sauvegardez le code et chargez le fichier html dans un navigateur.</li>
+ <li>Ouvrez la console JavaScript du navigateur et actualisez la page afin que la taille du canvas change et prenne la petite taille restante de la fenêtre lorsque la console est ouverte.</li>
+ <li>Tapez dans la console ce qui suit afin de créer une nouvelle instance de balle :
+ <pre class="brush: js">let testBall = new Ball(50, 100, 4, 4, 'blue', 10);</pre>
+ </li>
+ <li>Essayez d'appeler ses membres :
+ <pre class="brush: js">testBall.x
+testBall.size
+testBall.color
+testBall.draw()</pre>
+ </li>
+ <li>Lorsque vous entrerez la dernière ligne, vous devriez voir la balle se dessiner quelque part sur votre canvas.</li>
+</ol>
+
+<h3 id="Mettre_à_jour_les_données_de_la_balle">Mettre à jour les données de la balle</h3>
+
+<p>Nous pouvons dessiner la balle dans n'importe quelle position, mais actuellement pour commencer à la bouger nous aurons besoin d'une sorte de fonction de mise à jour. Insérez donc le code suivant à la fin de votre fichier JavaScript pour ajouter une méthode <code>update()</code> au <code>prototype</code> de <code>Ball()</code>:</p>
+
+<pre class="brush: js">Ball.prototype.update = function() {
+ if ((this.x + this.size) &gt;= width) {
+ this.velX = -(this.velX);
+ }
+
+ if ((this.x - this.size) &lt;= 0) {
+ this.velX = -(this.velX);
+ }
+
+ if ((this.y + this.size) &gt;= height) {
+ this.velY = -(this.velY);
+ }
+
+ if ((this.y - this.size) &lt;= 0) {
+ this.velY = -(this.velY);
+ }
+
+ this.x += this.velX;
+ this.y += this.velY;
+}</pre>
+
+<p>Les quatre premières parties de la fonction vérifient si la balle a atteint le rebord  du canvas. Si c'est le cas, nous inversons la polarité de la vitesse appropriée pour faire bouger la balle dans le sens opposé. Donc par exemple, si la balle se déplaçait vers le haut (positif <code>velY</code>) alors la vitesse verticale est changée afin qu'elle commence à bouger plutôt vers le bas (negatif <code>velY</code>).</p>
+
+<p>Dans les quatre cas nous :</p>
+
+<ul>
+ <li>Verifions si la coordonnée <code>x</code> est plus grande que la largeur du canvas (la balle est en train de sortir du côté droit).</li>
+ <li>Verifions si la coordonnée <code>x</code> est plus petite que 0 (la balle est en train de sortir du côté gauche).</li>
+ <li>Verifions si la coordonnée <code>y</code> est plus grande que la hauteur du canvas (la balle est en train de sortir par le bas).</li>
+ <li>Verifions si la coordonnée <code>y</code> est plus petite que 0 (la balle est en train de sortir par le  haut).</li>
+</ul>
+
+<p>Dans chaque cas, nous incluons la taille <code>size</code> de la balle dans les calculs parce que les coordonnées  <code>x</code>/<code>y</code>  sont situées au centre de la balle mais nous voulons que le pourtour de la balle rebondisse sur le rebord  — nous ne voulons pas que la balle sorte à moité hors de l'écran avant de commencer à rebondir vers l'arrière.</p>
+
+<p>Les deux dernières lignes ajoutent la valeur <code>velX</code> à la coordonnée <code>x</code> et la valeur <code>velY</code> à la coordonnée <code>y</code> — la balle est en effet mise en mouvement chaque fois que cette méthode est invoquée.</p>
+
+<p><span class="short_text" id="result_box" lang="fr"><span>Cela suffira pour l'instant,</span> <span>passons à l'animation !</span></span></p>
+
+<h2 id="Animer_la_balle">Animer la balle</h2>
+
+<p><span id="result_box" lang="fr"><span>Maintenant, rendons cela amusant.</span> <span>Nous allons commencer à ajouter des balles au canvas et à les animer.</span></span></p>
+
+<ol>
+ <li><span id="result_box" lang="fr"><span>Tout d'abord, nous avons besoin d'un endroit où stocker toutes nos balles.</span> <span>Le tableau suivant fera ce travail </span></span>— <span lang="fr"><span>ajoutez-le au bas de votre code maintenant :</span></span>
+
+ <pre class="brush: js">let balls = [];
+</pre>
+
+ <pre>while (balls.length &lt; 25) {
+ let size = random(10,20);
+ let ball = new Ball(
+ // ball position always drawn at least one ball width
+ // away from the edge of the canvas, to avoid drawing errors
+ random(0 + size,width - size),
+ random(0 + size,height - size),
+ random(-7,7),
+ random(-7,7),
+ 'rgb(' + random(0,255) + ',' + random(0,255) + ',' + random(0,255) +')',
+ size
+ );
+
+ balls.push(ball);
+}</pre>
+ <span>Tous les programmes qui animent les choses impliquent généralement une boucle d'animation, qui sert à mettre à jour les informations dans le programme et à restituer ensuite la vue résultante sur chaque image de l'animation.</span> <span>C'est la base de la plupart des jeux et autres programmes similaires.</span></li>
+ <li><span id="result_box" lang="fr"><span>Ajoutez ce qui suit au bas de votre code maintenant :</span></span>
+ <pre class="brush: js">function loop() {
+ ctx.fillStyle = 'rgba(0, 0, 0, 0.25)';
+ ctx.fillRect(0, 0, width, height);
+
+ for (let i = 0; i &lt; balls.length; i++) {
+ balls[i].draw();
+ balls[i].update();
+ }
+
+ requestAnimationFrame(loop);
+}</pre>
+
+ <p>Notre fonction <code>loop()</code> fonctionne comme suit :</p>
+
+ <ul>
+ <li><span id="result_box" lang="fr"><span>On définit la couleur de remplissage du canvas en noir semi-transparent, puis dessine un rectangle de couleur sur toute la largeur et la hauteur du canvas, en utilisant <code>fillRect()</code> (les quatre paramètres fournissent une coordonnée de départ et une largeur et une hauteur pour le rectangle dessiné</span> <span>).</span> <span>Cela sert à masquer le dessin de l'image précédente avant que la suivante ne soit dessinée.</span> <span>Si vous ne faites pas cela, vous verrez juste de longs serpents se faufiler autour de la toile au lieu de balles qui bougent !</span> <span>La couleur du remplissage est définie sur semi-transparent, <code>rgba (0,0,0,.25)</code>, pour permettre aux quelques images précédentes de briller légèrement, produisant les petites traînées derrière les balles lorsqu'elles se déplacent.</span> <span>Si vous avez changé 0.25 à 1, vous ne les verrez plus du tout.</span> <span>Essayez de faire varier ce dernier nombre (entre 0 et 1) pour voir l'effet qu'il a.</span></span></li>
+ <li><span id="result_box" lang="fr"><span>On crée un nouvel objet <code>Ball()</code> avec des attributs générées aléatoirement grâce à la fonction <code>random()</code>, puis on ajoute l'objet au tableau, mais seulement lorsque le nombre de balles dans le tableau est inférieur à 25. Donc</span> <span>quand on a 25 balles à l'écran, plus aucune balle supplémentaire n'apparaît.</span> <span>Vous pouvez essayer de faire varier le nombre dans <code>balls.length &lt;25</code> pour obtenir plus, ou moins de balles à l'écran.</span> <span>En fonction de la puissance de traitement de votre ordinateur / navigateur, spécifier plusieurs milliers de boules peut ralentir l'animation de façon très significative !</span></span></li>
+ <li><span id="result_box" lang="fr"><span>Le programme boucle à travers tous les objets du tableau sur chacun desquels il exécute la fonction <code>draw()</code> et <code>update()</code> pour dessiner à l'écran chaque balle et faire les mise à jour de chaque attribut vant le prochain rafraîchissement.</span></span></li>
+ <li><span id="result_box" lang="fr"><span>Exécute à nouveau la fonction à l'aide de la méthode <code>requestAnimationFrame()</code> </span></span>—<span lang="fr"><span> lorsque cette méthode est exécutée en permanence et a reçu le même nom de fonction, elle exécute cette fonction un nombre défini de fois par seconde pour créer une animation fluide.</span> <span>Cela se fait généralement de manière récursive </span></span>—<span lang="fr"><span> ce qui signifie que la fonction s'appelle elle-même à chaque fois qu'elle s'exécute, de sorte qu'elle sera répétée encore et encore.</span></span></li>
+ </ul>
+ </li>
+ <li>Finallement mais non moins important, ajoutez la ligne suivante au bas de votre code — nous devons appeler la fonction une fois pour démarrer l'animation.
+ <pre class="brush: js">loop();</pre>
+ </li>
+</ol>
+
+<p>Voilà pour les bases — <span id="result_box" lang="fr"><span>essayez d'enregistrer et de rafraîchir pour tester vos balles bondissantes!</span></span></p>
+
+<h2 id="Ajouter_la_détection_de_collision">Ajouter la détection de collision</h2>
+
+<p><span id="result_box" lang="fr"><span>Maintenant, pour un peu de plaisir, ajoutons une détection de collision à notre programme, afin que nos balles sachent quand elles ont frappé une autre balle.</span></span></p>
+
+<ol>
+ <li><span id="result_box" lang="fr"><span>Tout d'abord, ajoutez la définition de méthode suivante ci-dessous où vous avez défini la méthode <code>update()</code> (c'est-à-dire le bloc <code>Ball.prototype.update</code>).</span></span>
+
+ <pre class="brush: js">Ball.prototype.collisionDetect = function() {
+ for (let j = 0; j &lt; balls.length; j++) {
+ if (!(this === balls[j])) {
+ const dx = this.x - balls[j].x;
+ const dy = this.y - balls[j].y;
+ const distance = Math.sqrt(dx * dx + dy * dy);
+
+ if (distance &lt; this.size + balls[j].size) {
+ balls[j].color = this.color = 'rgb(' + random(0, 255) + ',' + random(0, 255) + ',' + random(0, 255) +')';
+ }
+ }
+ }
+}</pre>
+
+ <p><span id="result_box" lang="fr"><span>Cette méthode est un peu complexe, donc ne vous inquiétez pas si vous ne comprenez pas exactement comment cela fonctionne pour le moment.</span> Regardons cela pas-à-pas<span> :</span></span></p>
+
+ <ul>
+ <li><span id="result_box" lang="fr"><span>Pour chaque balle <em>b</em>, nous devons vérifier chaque autre balle pour voir si elle est entrée en collision avec <em>b</em>.</span> <span>Pour ce faire, on inspecte toutes les balles du tableau</span></span> <code>balls[]</code> dans une boucle <code>for</code>.</li>
+ <li><span id="result_box" lang="fr"><span>Immédiatement à l'intérieur de cette boucle <code>for</code>, une instruction <code>if</code> vérifie si la balle courante  <em>b'</em> , inspectée dans la boucle, n'est égale à la balle <em>b. Le code correspondant est :  </em><code><em>b</em>'!== <em>b</em></code></span></span><span lang="fr"><span><em>. </em>En effet,</span> n<span>ous ne voulons pas vérifier si une balle <em>b</em> est entrée en collision avec elle-même !</span> N<span>ous contrôlons donc si la balle actuelle <em>b</em></span></span>—<span lang="fr"><span>dont la méthode <code>collisionDetect()</code> est invoquée</span></span>—<span lang="fr"><span>est distincte de la balle <em>b' </em>inspectée dans la boucle<em>. </em>Ainsi</span> <span>le bloc de code venant après l'instruction <code>if</code> ne s'exécutera que si les balles <em>b</em> et <em>b'</em> ne sont pas identiques.</span></span></li>
+ <li><span id="result_box" lang="fr"><span>Un algorithme classique permet ensuite de vérifier la superposition de deux disques</span><span>.</span> <span>Ceci est expliqué plus loin dans</span></span> <a href="/en-US/docs/Games/Techniques/2D_collision_detection">2D collision detection</a>.</li>
+ <li><span id="result_box" lang="fr"><span>Si une collision est détectée, le code à l'intérieur de l'instruction interne <code>if</code> est exécuté.</span> <span>Dans ce cas, nous définissons simplement la propriété <code>color</code> des deux cercles à une nouvelle couleur aléatoire.</span> <span>Nous aurions pu faire quelque chose de bien plus complexe, comme faire rebondir les balles de façon réaliste, mais cela aurait été beaucoup plus complexe à mettre en œuvre.</span> <span>Pour de telles simulations de physique, les développeurs ont tendance à utiliser des bibliothèques de jeux ou de physiques telles que</span></span> <a href="http://wellcaffeinated.net/PhysicsJS/">PhysicsJS</a>, <a href="http://brm.io/matter-js/">matter.js</a>, <a href="http://phaser.io/">Phaser</a>, etc.</li>
+ </ul>
+ </li>
+ <li><span id="result_box" lang="fr"><span>Vous devez également appeler cette méthode dans chaque image de l'animation.</span> <span>Ajouter le code ci-dessous</span></span>  juste après la ligne <code>balls[i].update();</code>:
+ <pre class="brush: js">balls[i].collisionDetect();</pre>
+ </li>
+ <li><span id="result_box" lang="fr"><span>Enregistrez et rafraîchissez la démo à nouveau, et vous verrez vos balles changer de couleur quand elles entrent en collision !</span></span></li>
+</ol>
+
+<div class="note">
+<p><strong>Note </strong>: <span id="result_box" lang="fr"><span>Si vous avez des difficultés à faire fonctionner cet exemple, essayez de comparer votre code JavaScript avec notre <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/bouncing-balls/main-finished.js">version finale</a> (voir également la <a href="http://mdn.github.io/learning-area/javascript/oojs/bouncing-balls/index-finished.html">démo en ligne</a>).</span></span></p>
+</div>
+
+<h2 id="Résumé">Résumé</h2>
+
+<p><span id="result_box" lang="fr"><span>Nous espérons que vous vous êtes amusé à écrire votre propre exemple de balles aléatoires bondissantes comme dans le monde réel, en utilisant diverses techniques orientées objet et divers objets d'un bout à l'autre du module !</span> Nous espérons vous avoir offert un aperçu<span> utile de l'utilisation des objets.</span><br>
+ <br>
+ <span>C'est tout pour les articles sur les objets </span></span>—<span lang="fr"><span> il ne vous reste plus qu'à tester vos compétences dans l'évaluation sur les objets.</span></span></p>
+
+<h2 id="Voir_aussi">Voir aussi</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Web/API/Canvas_API/Tutorial">Didacticiel sur canvas</a> — <span id="result_box" lang="fr"><span>un guide pour débutants sur l'utilisation de canvas 2D.</span></span></li>
+ <li><a href="/en-US/docs/Web/API/window/requestAnimationFrame">requestAnimationFrame()</a></li>
+ <li><span id="result_box" lang="fr"><span><a href="/en-US/docs/Games/Techniques/2D_collision_detection">Détection de collision 2D</a> </span></span></li>
+ <li><span id="result_box" lang="fr"><span><a href="/en-US/docs/Games/Techniques/3D_collision_detection">Détection de collision 3D</a> </span></span></li>
+ <li><a href="/en-US/docs/Games/Tutorials/2D_Breakout_game_pure_JavaScript">Jeu d'évasion 2D utilisant du JavaScript pu</a> —<span id="result_box" lang="fr"><span>un excellent tutoriel pour débutant montrant comment construire un jeu en 2D.</span></span></li>
+ <li><a href="/en-US/docs/Games/Tutorials/2D_breakout_game_Phaser">Jeu d'évasion 2D utilisant phaser</a> — <span id="result_box" lang="fr"><span>explique les bases de la construction d'un jeu 2D en utilisant une bibliothèque de jeux JavaScript.</span></span></li>
+</ul>
+
+<p>{{PreviousMenuNext("Learn/JavaScript/Objects/JSON", "Learn/JavaScript/Objects/Adding_bouncing_balls_features", "Learn/JavaScript/Objects")}}</p>
+
+
+
+<h2 id="Dans_ce_module">Dans ce module</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/JavaScript/Objects/Basics">Les bases de l'objet</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object-oriented_JS">JavaScript orienté objet pour les débutants</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object_prototypes">Prototypes d'objets</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Objects/Inheritance">Héritage en JavaScript</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Objects/JSON">Travailler avec des données JSON</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object_building_practice">Pratique de construction d'objets</a></li>
+ <li><a href="/en-US/docs/Learn/JavaScript/Objects/Adding_bouncing_balls_features">Ajout de fonctionnalités à notre démo de balles bondissantes</a></li>
+</ul>
diff --git a/files/fr/learn/javascript/objects/prototypes_objet/index.html b/files/fr/learn/javascript/objects/prototypes_objet/index.html
new file mode 100644
index 0000000000..efb3681f18
--- /dev/null
+++ b/files/fr/learn/javascript/objects/prototypes_objet/index.html
@@ -0,0 +1,244 @@
+---
+title: Prototypes Objet
+slug: Learn/JavaScript/Objects/Prototypes_Objet
+tags:
+ - Constructeur
+ - JavaScript
+ - Prototype
+translation_of: Learn/JavaScript/Objects/Object_prototypes
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/JavaScript/Objects/Object-oriented_JS", "Learn/JavaScript/Objects/Inheritance", "Learn/JavaScript/Objects")}}</div>
+
+<p class="summary">Les prototypes sont un mécanisme au sein de JavaScript qui permettent aux objets JavaScript d'hériter des propriétés d'autres objets. Les prototypes implémentent un héritage différent de celui rencontré dans les langages de programmation objets habituels. Dans cet article, nous allons aborder ces différences, nous allons aussi voir comment la chaîne de prototypage fonctionne. Nous verrons aussi comment les propriétés prototypes peuvent être utilisées afin d'ajouter des méthodes à des constructeurs existants.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Pré-requis :</th>
+ <td>Une connaissance générale de l'informatique, des notions d'HTML et CSS, une connaissance des bases en JavaScript (voir <a href="/fr/docs/Learn/JavaScript/First_steps">Premiers pas</a> et <a href="/fr/docs/Learn/JavaScript/Building_blocks">Blocs de construction</a>) ainsi que des notions de JavaScript orienté objet (JSOO) (voir <a href="/fr/docs/Learn/JavaScript/Object-oriented/Introduction">Introduction aux objets</a>).</td>
+ </tr>
+ <tr>
+ <th scope="row">Objectifs :</th>
+ <td>Comprendre le concept de prototype en JavaScript, comprendre comment fonctionne une chaîne de prototypage et comment ajouter de nouvelles méthodes aux propriétés d'un prototype.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Un_langage_basé_sur_des_prototypes">Un langage basé sur des prototypes ?</h2>
+
+<p>JavaScript est souvent décrit comme un langage basé sur les prototypes, chaque objet pouvant avoir un <strong>prototype objet</strong> d'où il hérite des méthodes et des attributs. Un prototype peut lui aussi avoir son prototype objet duquel il héritera des méthodes et des attributs et ainsi de suite. On parle alors de chaîne de prototypage (ou <em>prototype chain<strong> </strong></em>en anglais). Cela permet d'expliquer pourquoi différents objets possèdent des attributs et des méthodes définis à partir d'autres objets.</p>
+
+<p>En réalité, les méthodes et attributs sont définis dans l'attribut <code>prototype</code> , la fonction constructrice de l'objet et non pas dans les instances des objets elles-mêmes.</p>
+
+<p>En programmation orientée objet classique, les classes sont définies, puis lorsque des instances sont créées, l'ensemble des attributs et des méthodes sont copiés dans l'instance. En JavaScript en revanche, tout n'est pas copié : on établit un lien entre l'objet instancié et son constructeur (c'est un lien dans la chaîne de prototypage). On détermine alors les méthodes et les attributs en remontant la chaîne.</p>
+
+<div class="note">
+<p><strong>Note:</strong> Il faut bien comprendre qu'il y a une différence entre la notion de prototype d'un objet (qu'on obtient via <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getPrototypeOf">Object.getPrototypeOf(obj)</a></code>, ou via la propriété dépréciée  <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto">__proto__</a></code> ) et l' attribut <code>prototype</code>d'une fonction constructrice. La première concerne chaque instance, le dernier existe uniquement sur une fonction constructrice. Cela dit, <code>Object.getPrototypeOf(new Foobar())</code> renvoie au même object que<code>Foobar.prototype</code>.</p>
+</div>
+
+<p>Prenons un exemple afin de rendre cela un peu plus clair.</p>
+
+<h2 id="Comprendre_les_prototypes_objet">Comprendre les prototypes objet</h2>
+
+<p>Reprenons notre exemple dans lequel nous avions écrit notre constructeur <code>Personne()</code>. Chargez cet exemple dans votre navigateur, si vous ne l'avez plus, vous pouvez utiliser notre exemple<a href="https://mdn.github.io/learning-area/javascript/oojs/introduction/oojs-class-further-exercises.html"> oojs-class-further-exercises.html</a> example (voir aussi le <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/introduction/oojs-class-further-exercises.html">code source</a>).</p>
+
+<p>Dans cet exemple, nous avons défini un constructeur comme suit :</p>
+
+<pre class="brush: js">function Personne(prenom, nom, age, genre, interets) {
+
+ // property and method definitions
+
+};</pre>
+
+<p>Nous avons ensuite instancié des objets comme ceci :</p>
+
+<pre class="brush: js">var personne1 = new Personne('Bob', 'Smith', 32, 'homme', ['musique', 'ski']);</pre>
+
+<p>Si vous entrez  « <code>personne1</code> » dans votre console JavaScript, vous devriez voir que le navigateur essaie de faire de l'auto-complétion avec les attributs de cet objet.</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/14907/autocomplete_Personne.png" style="height: 304px; width: 288px;"><img alt="" src="https://mdn.mozillademos.org/files/14919/autocomplete_Personne.png" style="height: 288px; width: 303px;"></p>
+
+<p>Dans cette liste vous verrez les membres définis au niveau du constructeur de <code>personne1</code> qui n'est autre  <code>Personne()</code>. On y trouve les valeurs suivantes : <code>nom</code>, <code>age</code>, <code>genre</code>, <code>interets</code>, <code>bio</code>, et <code>salutation</code>. On peut voir aussi d'autres membres tels que <code>watch</code>, <code>valueOf</code> …  Ces membres particuliers sont définis au niveau du prototype objet du constructeur <code>Personne()</code>, qui est <code><a href="/fr/docs/Web/JavaScript/Reference/Global_Objects/Object">Object</a></code>. On voit ici une mise en œuvre de la chaine de prototypage.</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/14921/prototype_chaine.PNG" style="height: 137px; width: 703px;"></p>
+
+<p>Que peut-il bien se passer lorsque l'on tente d'appeler une méthode définie pour <code>Object</code> en l'appliquant à <code>Personne</code>1 ? Par exemple :</p>
+
+<pre class="brush: js">personne1.valueOf()</pre>
+
+<p>Cette méthode renvoie simplement la valeur de l'objet pour lequel elle est appelée. Vous pouvez essayer dans votre console ! Lorsque l'on effectue cet appel, il se produit les choses suivantes :</p>
+
+<ul>
+ <li>Le navigateur tente de déterminer si l'objet <code>personne1</code> implémente une méthode <code>valueOf().</code></li>
+ <li>Aucune n'est présente, le navigateur vérifie donc si le prototype objet de <code>personne1</code> (<code>Personne</code>) contient cette méthode.</li>
+ <li>Pas de <code>valueOf()</code> non plus, donc le navigateur regarde si le prototype objet du constructeur <code>Personne()</code> (<code>Object</code>) possède cette méthode. Il y en a une, donc il l'appelle et tout va bien !</li>
+</ul>
+
+<div class="note">
+<p><strong>Note </strong>: Encore une fois, il est important d'insister sur le fait que les méthodes et attributs ne sont <strong>pas</strong> copiés d'un objet à un autre, mais qu'on y accède à chaque fois en remontant la chaine de prototypage.</p>
+</div>
+
+<div class="note">
+<p><strong>Note</strong> : Il n'existe pas de façon officielle d'accéder directement au prototype d'un objet donné. Les « liens » entre les éléments de la chaine sont définis au sein d'une propriété interne appelée <code>[[prototype]]</code> définie dans la spécification de JavaScript. (voir <a href="fr/docs/Web/JavaScript/Language_Resources">ECMAScript</a>). Néanmoins, la plupart des navigateurs modernes implémentent l'attribut <code><a href="/fr/docs/Web/JavaScript/Reference/Global_Objects/Object/proto">__proto__</a></code>   (deux tirets soulignés ou <em>underscore</em> de chaque côté) qui contient le prototype objet d'un objet. Vous pouvez tenter <code>personne1.__proto__</code> et <code>personne1.__proto__.__proto__</code> pour voir à quoi ressemble une chaine de prototypage dans la console !</p>
+</div>
+
+<h2 id="Lattribut_prototype_là_où_lon_définit_les_éléments_héritables">L'attribut prototype : là où l'on définit les éléments héritables</h2>
+
+<p>Mais alors, où définissons-nous les attributs et méthodes qui seront hérités au long de la chaîne de prototypage ? En effet, s'il on regarde à la page de documentation <code><a href="/fr/docs/Web/JavaScript/Reference/Global_Objects/Object">Object</a></code> on peut voir un large éventail d'attributs et de méthodes qui sont définis, une liste bien plus longue que celle disponible pour notre objet <code>Personne1</code>. Pourquoi <code>Personne1</code> hérite de certains de ces éléments mais pas de tous ?</p>
+
+<p>Cela vient du fait que les éléments hérités sont ceux définis au niveau de l'attribut <code>prototype</code> d'<code>Object</code> (on peut voir cet attribut comme un sous espace de noms). Ainsi, les éléments listés sont ceux sous <code>Object.prototype.</code> et pas ceux situés juste sous <code>Object.</code> La valeur de l'attribut <code>prototype</code> est un objet qui rassemble les attributs et méthodes que l'on souhaite appliquer aux objets tout au long de la chaine de prototypage.</p>
+
+<p>Ainsi <code><a href="/fr/docs/Web/JavaScript/Reference/Global_Objects/Object/watch">Object.prototype.watch()</a></code>, <code><a href="/fr/docs/Web/JavaScript/Reference/Global_Objects/Object/valueOf">Object.prototype.valueOf()</a></code> …  sont disponibles pour n'importe quel objet qui hérite de <code>Object.prototype</code> ce qui inclus les nouvelles instances créées à partir du constructeur <code>Personne()</code>.</p>
+
+<p><code><a href="/fr/docs/Web/JavaScript/Reference/Global_Objects/Object/is">Object.is()</a></code>, <code><a href="/fr/docs/Web/JavaScript/Reference/Global_Objects/Object/keys">Object.keys()</a></code>, ainsi que d'autres membres non définis dans <code>prototype</code> ne sont pas hérités par les instances d'objet ou les objets qui héritent de <code>Object.prototype</code>. Ces méthodes et attributs sont disponibles uniquement pour le constructeur <code>Object()</code>.</p>
+
+<div class="note">
+<p><strong>Note</strong> : Ça paraît bizarre, d'avoir une méthode définie au sein d'un constructeur qui est lui même une fonction non ? Et bien, une fonction est aussi un type d'objet — vous pouvez jeter un  œil à la documentation du constructeur <code><a href="/fr/docs/Web/JavaScript/Reference/Global_Objects/Function">Function()</a></code> si vous ne nous croyez pas.</p>
+</div>
+
+<ol>
+ <li>Vous pouvez vérifier les attributs du prototype en reprenant l'exemple précédent et en entrant le code suivant dans la console JavaScript :
+ <pre class="brush: js">Personne.prototype</pre>
+ </li>
+ <li>Il n'y a pas grand chose renvoyé par le navigateur. En même temps, nous n'avons rien défini dans l'attribut prototype de notre constructeur, et par défaut l'attribut prototype d'un constructeur est toujours vide. Voyons ce que renvoie le code suivant :
+ <pre class="brush: js">Object.prototype</pre>
+ </li>
+</ol>
+
+<p>On observe que plusieurs méthodes sont définies au niveau de l'attribut <code>prototype</code> d'<code>Object</code>, qui seront alors disponibles pour les objets qui héritent d'<code>Object</code>, comme nous l'avons vu plus haut.</p>
+
+<p>Vous verrez qu'il existe plein d'exemples de chaine de prototypage dans JavaScript. Vous pouvez essayer de trouver les méthodes et les attributs définis dans les attributs <code>prototype</code> des objets globeaux comme <code><a href="/fr/docs/Web/JavaScript/Reference/Global_Objects/String">String</a></code>,  <code><a href="/fr/docs/Web/JavaScript/Reference/Global_Objects/Date">Date</a></code>, <code><a href="/fr/docs/Web/JavaScript/Reference/Global_Objects/Number">Number</a></code>, et <code> <a href="/fr/docs/Web/JavaScript/Reference/Global_Objects/Array">Array</a></code>. Chacun de ces objets possède des éléments au sein de leur attribut prototype. Dès lors que l'on crée une chaine de caractères, comme celle-ci :</p>
+
+<pre class="brush: js">var maChaine = 'Ceci est ma chaine de caracteres.';</pre>
+
+<p><code>maChaine </code>possède aussitôt plusieurs méthodes utiles pour manipuler les chaines de caractères telles que <code><a href="/fr/docs/Web/JavaScript/Reference/Global_Objects/String/split">split()</a></code>, <code><a href="/fr/docs/Web/JavaScript/Reference/Global_Objects/String/indexOf">indexOf()</a></code>, <code><a href="/fr/docs/Web/JavaScript/Reference/Global_Objects/String/replace">replace()</a></code>…</p>
+
+<div class="warning">
+<p><strong>Important </strong>: L'attribut <code>prototype</code> est un des éléments JavaScript qui peut le plus prêter à confusion. On pourrait penser qu'il s'agit du prototype objet de l'objet courant mais ça ne l'est pas (on peut y accéder via <code>__proto__</code>). L'attribut <code>prototype </code>est un attribut qui contient un objet où l'on définit les éléments dont on va pouvoir hériter.</p>
+</div>
+
+<h2 id="Revenons_sur_create">Revenons sur create()</h2>
+
+<p>Nous avons vu précedemment que la méthode <code><a href="/fr/docs/Web/JavaScript/Reference/Global_Objects/Object/create">Object.create()</a></code> pouvait être utilisée pour instancier des objets.</p>
+
+<ol>
+ <li>Par exemple, vous pouvez essayer le code suivant dans la console JavaScript :
+ <pre class="brush: js">var personne2 = Object.create(personne1);</pre>
+ </li>
+ <li>En réalité <code>create()</code> se contente de créer un nouvel objet à partir d'un prototype spécifique. Dans cet exemple, <code>personne2</code> est créé à partir de <code>personne1</code> qui agit en tant que prototype. Vous pouvez le vérifier via :
+ <pre class="brush: js">person2.__proto__</pre>
+ </li>
+</ol>
+
+<p>Cela renverra l'objet <code>personne1</code>.</p>
+
+<h2 id="Lattribut_constructor">L'attribut <em>constructor</em></h2>
+
+<p>Chaque fonction possède un attribut prototype dont la valeur est un objet contenant un attribut <code><a href="/fr/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor">constructor</a></code>. L'attribut <code>constructor</code> renvoie vers la méthode constructrice utilisée. Nous allons le voir dans la section suivante, les attributs définis dans l'attribut <code>Personne.prototype</code> deviennent disponibles pour toutes les instances créées à partir du constructeur <code>Personne()</code>. De cette manière, l'attribut <code>constructor</code> est aussi disponible au sein de <code>personne1</code> et <code>personne2</code>.</p>
+
+<ol>
+ <li>Par exemple, vous pouvez tester le code suivant :
+ <pre class="brush: js">personne1.constructor
+personne2.constructor</pre>
+
+ <p>Chaque commande devrait renvoyer le constructeur <code>Personne()</code> étant donné qu'il a permis d'instancier ces objets.</p>
+
+ <p>Une astuce qui peut s'avérer utile est d'ajouter des parenthèses à la fin de l'attribut <code>constructor</code> pour le transformer en méthode. Après tout, le constructeur est une fonction que l'on peut appeler si besoin. Il faut juste utiliser le mot-clé <code>new</code> pour signifier que l'on souhaite construire un objet.</p>
+ </li>
+ <li>Par exemple :
+ <pre class="brush: js">var personne3 = new personne1.constructor('Karen', 'Stephenson', 26, 'femme', ['jouer de la batterie', 'escalade']);</pre>
+ </li>
+ <li>Vous pouvez désormais essayer d'accéder aux propriétés de personne3 :
+ <pre class="brush: js">personne3.prenom
+personne3.age
+personne3.bio()</pre>
+ </li>
+</ol>
+
+<p>Ça fonctionne bien. A priori, ce n'est pas la manière la plus simple de créer un objet et vous n'aurez pas à l'utiliser souvent. En revanche, ça peut vous débloquer quand vous devez créer une nouvelle instance et que vous ne disposez pas facilement du constructeur d'origine.</p>
+
+<p>L'attribut <code><a href="/fr/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor">constructor</a></code> possède d'autres intérêts. Par exemple, si vous disposez du nom d'une instance objet vous pouvez utiliser le code suivant pour renvoyer le nom de son constructeur :</p>
+
+<pre class="brush: js">instanceName.constructor.name</pre>
+
+<p>Vous pouvez essayer :</p>
+
+<pre class="brush: js">personne1.constructor.name</pre>
+
+<h2 id="Modifions_les_prototypes">Modifions les prototypes</h2>
+
+<p>Voyons au travers d'un exemple comment modifier l'attribut <code>prototype</code> d'un constructeur (les méthodes ajoutées au prototype seront alors disponibles pour toutes les instances créées à partir du constructeur).</p>
+
+<ol>
+ <li>Revenons à notre exemple <a href="https://mdn.github.io/learning-area/javascript/oojs/introduction/oojs-class-further-exercises.html">oojs-class-further-exercises.html</a> et faisons une copie local du <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/introduction/oojs-class-further-exercises.html">code source</a>. En dessous du JavaScript existant, vous pouvez ajouter le code suivant, ce qui aura pour effet d'ajouter une nouvelle méthode à l'attribut <code>prototype</code> du constructeur :
+
+ <pre class="brush: js">Personne.prototype.aurevoir = function() {
+ alert(this.nom.prenom + ' est sorti. Au revoir !');
+}</pre>
+ </li>
+ <li>Enregistrez vos modifications et chargez la page dans votre navigateur. Vous pouvez ensuite entrer le code suivant dans la console :
+ <pre class="brush: js">personne1.aurevoir();</pre>
+ </li>
+</ol>
+
+<p>Vous devriez voir une fenêtre s'afficher avec un message contenant le nom de la personne. Cette fonctionalité est utile, mais là où ça devient plus intéressant c'est que la chaine de prototypage a été mis à jour dynamiquement, rendant automatiquement cette méthode disponible à l'ensemble des instances existantes.</p>
+
+<p>Revoyons en détail ce qui s'est passé : tout d'abord, nous avons défini le constructeur. Ensuite, nous avons instancié un objet à partir du constructeur. Enfin, nous avons ajouté une nouvelle méthode au prototype du construceur :</p>
+
+<pre class="brush: js">function Personne(prenom, nom, age, genre, interets) {
+
+ // définition des attrbuts et des méthodes
+
+};
+
+var personne1 = new Personne('Tammi', 'Smith', 32, 'neutre', ['musique', 'ski', 'kickboxing']);
+
+Personne.prototype.aurevoir= function() {
+ alert(this.nom.prenom + ' est sorti. Au revoir !');
+}</pre>
+
+<p>Même si nous l'avons déclaré après, la méthode <code>aurevoir()</code> est disponible pour l'instance <code>personne1</code>. Son existence a mis à jour dynamiquement les méthodes de l'instance. Cela démontre ce que nous expliquions plus haut au sujet de la chaine de prototypage : le navigateur la parcourt de manière ascendante. Ainsi, il est possible de trouver directement les méthodes qui n'ont pas été définies au niveau de l'instance, plutôt que de les recopier au sein de l'instance. Cela nous permet de bénéficier d'un système extensible de manière simple et élégante.</p>
+
+<div class="note">
+<p><strong>Note </strong>: Si vous avez du mal à faire fonctionner cet exemple, vous pouvez jeter un œil au notre (<a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/advanced/oojs-class-prototype.html">oojs-class-prototype.html</a>, voir la <a href="https://mdn.github.io/learning-area/javascript/oojs/advanced/oojs-class-prototype.html">démo</a>)</p>
+</div>
+
+<p>Vous verrez peu d'attributs définis au sein de l'attribut <code>prototype</code>, pour la simple et bonne raison que c'est assez peu pratique. Vous pourriez avoir :</p>
+
+<pre class="brush: js">Personne.prototype.nomComplet = 'Bob Smith';</pre>
+
+<p>Mais ce n'est pas très pratique, étant donné qu'une personne ne sera peut-être pas appelée de cette manière. Il est plus cohérent de construire le nom entier en combinant le nom et le prénom :</p>
+
+<pre class="brush: js">Personne.prototype.nomComplet = this.nom.prenom + ' ' + this.nom.nom;</pre>
+
+<p>Ça ne fonctionnera toujours pas. En effet, <code>this</code> aura une portée globale et ne sera pas dans le contexte de la fonction. En appelant cet attribut, nous aurions alors <code>undefined undefined</code>. Dans les exemples précédents sur le prototype, nous arrivions à obtenir quelque chose de fonctionnel puisque nous étions au sein d'une méthode, qui sera utilisée par l'instance. Il est donc possible de définir des attributs invariables au niveau du prototype mais de manière générale, il est préférable de les définir au sein du constructeur.</p>
+
+<p>En fait, on retrouve généralement la chose suivante : les attributs sont définis dans le constructeur, tandis que les méthodes sont définies au niveau du prototype. Cela rend le code plus simple à lire puisque les attributs sont groupés et les méthodes structurées en blocs distincts. Par exempe :</p>
+
+<pre class="brush: js">// Constructeur avec définition des attributs
+
+function Test(a, b, c, d) {
+ // définition des attributs
+};
+
+// Définition de la première méthode
+
+Test.prototype.x = function() { ... }
+
+// Définition de la seconde méthode
+
+Test.prototype.y = function() { ... }
+
+// etc...</pre>
+
+<p>Ce type d'implémentation peut être observée dans l'appli <a href="https://github.com/zalun/school-plan-app/blob/master/stage9/js/index.js">plan d'école</a> de Piotr Zalewa par exemple.</p>
+
+<h2 id="Résumé">Résumé</h2>
+
+<p>Cet article a traité des prototypes objet en JavaScript, en incluant la chaine de prototypage qui permet aux objets d'hériter des propriétés d'un autre objet. Nous avons aussi vu l'attribut prototype et comment nous pouvons l'utiliser pour ajouter des méthodes au constructeur.</p>
+
+<p>Dans le prochain article, nous verrons comment appliquer l'héritage entre deux de nos propres objets.</p>
+
+<p>{{PreviousMenuNext("Learn/JavaScript/Objects/Object-oriented_JS", "Learn/JavaScript/Objects/Inheritance", "Learn/JavaScript/Objects")}}</p>
diff --git a/files/fr/learn/performance/css/index.html b/files/fr/learn/performance/css/index.html
new file mode 100644
index 0000000000..fe7befdd0e
--- /dev/null
+++ b/files/fr/learn/performance/css/index.html
@@ -0,0 +1,100 @@
+---
+title: Optimisation des performances en CSS
+slug: Learn/Performance/CSS
+tags:
+ - CSS
+ - Optimisation
+ - Performance
+ - Tutoriel
+translation_of: Learn/Performance/CSS
+---
+<p>{{LearnSidebar}}{{PreviousMenuNext("Learn/Performance/html", "Learn/Performance/fonts", "Learn/Performance")}} {{draft}}</p>
+
+<p>Afficher une page sans mise en forme, puis ré-afficher cette même page une fois sa mise en forme chargée serait un processus bien désagréable pour l'utilisateur. Afin d'éviter ce désagrément, le CSS retarde l'affichage de la page sur le naviguateur tant qu'il n'a pas été entièrement chargé et interprêté : on dit que <span class="seoSummary">le CSS bloque le rendu de la page</span> (on le qualifie d'ailleurs de "render blocking" en anglais). C'est cette configuration que le navigateur utilise par défaut, bien que l'on puisse spécifier une stratégie d'affichage différente comme indiqué dans la section suivante.</p>
+
+<p>Le navigateur suit une procédure d'affichage très précise : l'affichage n'intervient qu'après la mise en page, qui elle-même dépend de la génération de l'abre de rendu par le navigateur, qui requiert lui aussi l'existence de deux autres ressources : le <a href="/fr/docs/Glossaire/DOM">DOM</a> (Document Object Model) et le <a href="/fr/docs/MDN/Doc_status/API/CSSOM">CSSOM</a> (CSS Object Model). <span class="seoSummary">Optimiser les performances en CSS revient donc d'une part à réduire le temps de chargement des ressources, et d'autre part à optimiser la construction du CSSOM.</span> Pour se faire, quelques bonnes pratiques :</p>
+
+<ul>
+ <li>Retirez les règles de styles inutilisées ou dupliquées,</li>
+ <li>Minimisez la taille de votre fichier CSS (en retirant les espaces, retours à la ligne et tabulations par exemple),</li>
+ <li>compressez votre fichier CSS et enregistrez-le dans le cache du navigateur client,</li>
+ <li>enregistrez dans des fichiers additionnels les règles CSS qui ne sont pas nécessaires lors du chargement de la page afin de diminuer le temps de bloquage.</li>
+</ul>
+
+<h3 id="Optimiser_le_temps_de_bloquage_du_rendu">Optimiser le temps de bloquage du rendu</h3>
+
+<p>Une des forces du CSS réside dans sa capacité à appliquer des styles différents selon l'appareil utilisé, par le biais de <a href="/fr/docs/Web/CSS/Requ%C3%AAtes_m%C3%A9dia/Utilisation_requ%C3%AAtes_media_accessibilit%C3%A9">Requêtes Média</a> ("media queries" en anglais) permettant de poser des conditions de mise en page selon les caractéristiques de l'apareil. Ces requettes média sont d'une importance capitale pour le <a href="/fr/docs/Apprendre/CSS/CSS_layout/Responsive_Design">responsive design</a> (mise en page flexible) et peuvent également nous permettre d'optimiser une partie critique du processus de rendu. En effet, le navigateur bloque le rendu de la page tant qu'il n'a pas entièrement interprêté les règles CSS, mais ne bloquera plus ni le rendu, ni l'affichage pour des fichiers CSS dont il sait ne pas avoir l'utilité - comme c'est le cas pour la mise en page d'impression papier, destinée à l'imprimante et non à l'écran. En réorganisant alors l'ensemble des règles CSS en plusieurs fichiers suivant des requêtes média, nous pouvons alors éviter de bloquer inutilement le rendu en attendant le chargement de ressources superflues pour l'affichage.</p>
+
+<p>Pour obtenir ce résultat dans les faits, il suffit de placer le code CSS inutilisé lors du rendu, par exemple celui de l'impression papier, dans un fichier à part puis de l'intégrer à la page par le biais d'une balise <code><a href="/fr/docs/Web/HTML/Element/link">&lt;link&gt;</a></code>. On spécifie ensuite l'attribut <code>media</code> de cette balise pour y ajouter notre requête média : dans notre exemple, cette requête spécifierait que ce n'est utile que pour une imprimante.</p>
+
+<pre class="brush: html notranslate">&lt;link rel="stylesheet" href="styles.css"&gt; &lt;!-- bloquant --&gt;
+&lt;link rel="stylesheet" href="print.css" media="print"&gt; &lt;!-- non bloquant --&gt;
+&lt;link rel="stylesheet" href="mobile.css" media="screen and (max-width: 480px)"&gt; &lt;!-- non boquant sur grand écran --&gt;</pre>
+
+<p>Par défaut, le navigateur suppose que chaque fichier CSS est bloquant, car probablement utile pour le rendu. En utilisant cet attribut <code>media</code>, le navigateur comprend alors quel fichier utiliser dans quel scénario : il téléchargera alors le fichier, mais ne bloquera pas le rendu lors de son interprétation, ce qui résultera en un affichage plus rapide pour l'utilisateur. Dans le cas ci-dessus, le fichier <code>styles.css</code> est boquant quelque soit l'appareil utilisé, <code>print.css</code> devient bloquant pour une imprimante et <code>mobile.css</code> devient bloquant seulement lorsque la largeur de l'écran n'excède pas 480 pixels.</p>
+
+<h3 id="Interprêter_les_animations_sur_le_GPU">Interprêter les animations sur le GPU</h3>
+
+<p>Les navigateurs sont déjà optimisés pour manipuler les animations CSS, ainsi que les propriétés d'animation qui ne provoquent pas de réorganisation soudaine du document (ces autres propriétés nécessiteront alors un nouveau rendu). Cette optimisation s'effectue en plaçant les éléments animés sur un autre fil d'execution que l'on peut alors envoyer sur le GPU, bien plus rapide pour ce genre de tâche. Pour profiter de cette optimisation, il faut alors animer de préférence avec les propriétés de transformation 3D (<code><a href="/en-US/docs/Web/CSS/transform">transform: translateZ()</a></code>, <code><a href="/en-US/docs/Web/CSS/transform-function/rotate3d">rotate3d()</a></code>, etc.), de transformation 2D ainsi que les propriétés <code><a href="/en-US/docs/Web/CSS/opacity">opacity</a></code>, <code><a href="/en-US/docs/Web/CSS/position">position: fixed</a></code>, <code><a href="/en-US/docs/Web/CSS/will-change">will-change</a></code> et <code><a href="/en-US/docs/Web/CSS/filter">filter</a></code>. D'autres éléments, parmi lesquels <code><a href="/en-US/docs/Web/HTML/Element/video">&lt;video&gt;</a></code>, <code><a href="/en-US/docs/Web/HTML/Element/canvas">&lt;canvas&gt;</a></code> ou encore <code><a href="/en-US/docs/Web/HTML/Element/iframe">&lt;iframe&gt;</a></code>, fonctionnent aussi sur leur propre fil d'execution. Cette technique permet donc de tirer profit de la vitesse d'exécution du GPU pour chaque élément géré sur un nouveau fil d'éxécution, et permet d'obtenir de bien meilleures performance, en particulier sur mobile.</p>
+
+<h3 id="La_propriété_cssxrefwill-change">La propriété {{cssxref('will-change')}}</h3>
+
+<p>La propriété CSS {{cssxref('will-change')}} indique au navigateur les propriétés CSS d'un élément qui sont suceptibles d'être modifiés par la suite (lors d'animations par exemple), afin que le navigateur puisse s'y préparer et optimiser ces changements. Cela permet principalement d'améliorer les performances en réalisant en amont des calculs parfois gourmands.</p>
+
+<pre class="brush: css notranslate">will-change: opacity, transform;</pre>
+
+<h3 id="La_propriété_cssxreffont-display">La propriété {{cssxref('font-display')}}</h3>
+
+<p>Insérée dans une règle {{cssxref('@font-face')}}, la propriété CSS {{cssxref('font-display')}} permet de définir la logique de chargement et d'affichage des polices par le navigateur. Elle permet par exemple d'afficher le texte avec une police par défaut le temps que l'autre charge ou lorsque le chargement échoue. Cela permet de rendre le texte visible sans l'attente du chargement des polices, mais a pour défaut un flash brusque de changement de police une fois la ressource chargée.</p>
+
+<pre class="brush: css notranslate">@font-face {
+ font-family: someFont;
+ src: url(/path/to/fonts/someFont.woff) format('woff');
+ font-weight: 400;
+ font-style: normal;
+ font-display: fallback;
+}</pre>
+
+<p>Dans cet exemple, la dernière règle <code>font-display: fallback;</code> permet justement d'afficher le texte avec une police par défaut en attendant le chargement de la police <code>someFont.woff</code>.</p>
+
+<h3 id="La_propriété_cssxrefcontain">La propriété {{cssxref('contain')}}</h3>
+
+<p>La propriété CSS {{cssxref('contain')}} permet quant à elle de spécifier au navigateur qu'un élément et son contenu sont, dans la mesure du possible, indépendant du reste de l'arborescence du document. Ceci offre la possibilité au navigateur de recalculer la mise en page, le style, le rendu, la taille ou toute combinaison de ces propriétés seulement pour une portion de l'arborescence DOM, sans avoir à étendre ces calculs à la totalité de la page.</p>
+
+<h2 id="Conclusion">Conclusion</h2>
+
+<p>Optimiser les performances en CSS revient ainsi à améliorer deux étapes cruciales et chronophages du rendu de page :</p>
+
+<ul>
+ <li>d'une part le chargement des ressources CSS de la page (en compressant, en divisant le fichier, ou encore en l'enregistrant dans le cache par exemple),</li>
+ <li>d'autre part le rendu, en établissant une stratégie ingénieuse de chargement et d'interprétation des ressources, notamment en distinguant les ressources essentielles pour le rendu et les autres ressources annexes, qui peuvent attendre;</li>
+</ul>
+
+<p>Enfin, les outils de développement du navigateur sont à votre disposition pour vous aider à cibler les étapes chronophages qui ralentissent le rendu de vos pages et gagner encore en efficacité, au prix parfois de quelques compromis.</p>
+
+<p>{{PreviousMenuNext("Learn/Performance/html", "Learn/Performance/fonts", "Learn/Performance")}}</p>
+
+<h2 id="Dans_ce_module">Dans ce module</h2>
+
+<ul>
+ <li><a href="/fr/docs/Learn/Performance/pourquoi_performance_web">Le "pourquoi" des performances web</a></li>
+ <li><a href="/en-US/docs/Learn/Performance/What_is_web_performance">What is web performance?</a></li>
+ <li><a href="/en-US/docs/Learn/Performance/Perceived_performance">How do users perceive performance?</a></li>
+ <li><a href="/en-US/docs/Learn/Performance/Measuring_performance">Measuring performance</a></li>
+ <li><a href="/en-US/docs/Learn/Performance/Multimedia">Multimedia: images</a></li>
+ <li><a href="/en-US/docs/Learn/Performance/video">Multimedia: video</a></li>
+ <li><a href="/en-US/docs/Learn/Performance/JavaScript">JavaScript performance best practices</a>.</li>
+ <li><a href="/en-US/docs/Learn/Performance/HTML">HTML performance features</a></li>
+ <li><a href="/fr/docs/Learn/Performance/CSS">CSS performance featuresOptimisation des performances en CSS</a></li>
+ <li><a href="/en-US/docs/Learn/Performance/Fonts">Fonts and performance</a></li>
+ <li><a href="/en-US/docs/Learn/Performance/Mobile">Mobile performance</a></li>
+ <li><a href="/en-US/docs/Learn/Performance/business_case_for_performance">Focusing on performance</a></li>
+</ul>
+
+<h2 id="Voir_aussi">Voir aussi</h2>
+
+<ul>
+ <li>
+ <p><a href="/en-US/docs/Web/Performance/CSS_JavaScript_animation_performance">CSS animation performance</a></p>
+ </li>
+</ul>
diff --git a/files/fr/learn/performance/index.html b/files/fr/learn/performance/index.html
new file mode 100644
index 0000000000..9f51e78656
--- /dev/null
+++ b/files/fr/learn/performance/index.html
@@ -0,0 +1,81 @@
+---
+title: Performance Web
+slug: Learn/Performance
+tags:
+ - Apprendre
+ - CSS
+ - HTML
+ - HTTP
+ - JavaScript
+ - Performance
+ - Performance Web
+ - TopicStub
+translation_of: Learn/Performance
+---
+<p>{{LearnSidebar}}</p>
+
+<p class="summary">La création de sites Web nécessite HTML, CSS, et JavaScript. Pour créer des sites Web et des applications que les gens veulent utiliser, qui attirent et fidélisent les utilisateurs, vous devez créer une bonne expérience utilisateur. Une bonne expérience utilisateur consiste à s'assurer que le contenu est rapide à charger et réactif à l'interaction de l'utilisateur. Ceci est connu sous le nom de <strong>performance web</strong>, et dans ce module, vous vous concentrerez sur les principes fondamentaux de la création de sites Web performants.</p>
+
+<p class="summary">Le reste de notre matériel d'apprentissage pour débutants a essayé de s'en tenir autant que possible aux meilleures pratiques du Web telles que les performances et l'<a href="/fr/docs/Apprendre/a11y">accessibilité</a>,cependant, il est bon de se concentrer spécifiquement sur ces sujets et de s'assurer que vous les connaissez bien.</p>
+
+<h2 id="Parcours_dapprentissage">Parcours d'apprentissage</h2>
+
+<p>Bien que la connaissance de HTML, CSS et JavaScript soit nécessaire pour mettre en <span class="tlid-translation translation" lang="fr"><span title="">œuvre de nombreuses recommandations d'amélioration des performances Web, savoir comment créer des applications n'est pas une condition préalable nécessaire pour comprendre et mesurer les performances Web.</span></span> Nous vous recommandons cependant, avant de commencer à utiliser ce module, d'avoir au moins une idée de base du développement Web en consultant notre module <a href="/fr/docs/Apprendre/Commencer_avec_le_web">Commencer avec le web</a>.</p>
+
+<p>Il serait également utile d'approfondir un peu ces sujets, avec des modules tels que:</p>
+
+<ul>
+ <li><a href="/fr/docs/Apprendre/HTML/Introduction_à_HTML">Introduction au HTML</a></li>
+ <li><a href="/fr/docs/Learn/CSS/First_steps">Premiers pas avec CSS</a></li>
+ <li><a href="/fr/docs/Learn/JavaScript/First_steps">Premiers pas en JavaScript</a></li>
+</ul>
+
+<p>Une fois que vous aurez parcouru ce module, vous serez probablement ravi d'approfondir les performances Web — vous pouvez trouver de nombreux autres enseignement dans notre <a href="/fr/docs/Web/Performance">section principale de performance Web MDN</a>, y compris des aperçus des API de performance, des outils de test et d'analyse, et goulots d'étranglement des performances.</p>
+
+<h2 id="Guides">Guides</h2>
+
+<p>Cette rubrique contient les guides suivants. Voici un ordre suggéré pour les parcourir; vous devriez certainement commencer par le premier.</p>
+
+<dl>
+ <dt><a href="/fr/docs/Learn/Performance/pourquoi_performance_web">Le "pourquoi" des performances Web</a></dt>
+ <dd>Cet article explique pourquoi les performances Web sont importantes pour l'accessibilité, l'expérience utilisateur et vos objectifs commerciaux.</dd>
+ <dt><a href="/en-US/docs/Learn/Performance/What_is_web_performance">Qu'est-ce que la performance Web?</a></dt>
+ <dd>Vous savez que les performances Web sont importantes, mais en quoi consistent les performances Web? Cet article présente les composants de la performance, du chargement et du rendu de la page Web, en passant par la manière dont votre contenu est intégré dans le navigateur de votre utilisateur pour être visualisé, aux groupes de personnes dont nous devons tenir compte lors de la réflexion sur les performances.</dd>
+ <dt><a href="/en-US/docs/Learn/Performance/Perceived_performance">Comment les utilisateurs perçoivent-ils les performances?</a></dt>
+ <dd>La vitesse à laquelle vos utilisateurs perçoivent votre site est plus importante que la vitesse de votre site Web en millisecondes. Ces perceptions sont affectées par le temps de chargement réel de la page, l'inactivité, la réactivité à l'interaction de l'utilisateur et la fluidité du défilement et d'autres animations. Dans cet article, nous discutons des différentes métriques de chargement, de l'animation et de la réactivité, ainsi que des meilleures pratiques pour améliorer la perception de l'utilisateur, sinon les timings réels.</dd>
+</dl>
+
+<dl>
+ <dt><a href="/en-US/docs/Learn/Performance/Measuring_performance">Mesurer les performances</a></dt>
+ <dd>Maintenant que vous comprenez quelques métriques de performance, nous nous penchons plus en profondeur sur les outils de performance, les métriques et les API et comment nous pouvons intégrer les performances dans le flux de travail de développement Web.</dd>
+ <dt><a href="/en-US/docs/Learn/Performance/Multimedia">Multimédia: images</a></dt>
+ <dd>Le fruit le plus bas de la performance Web est souvent l'optimisation des médias. Il est possible de diffuser différents fichiers multimédias en fonction de la capacité, de la taille et de la densité de pixels de chaque agent utilisateur. Dans cet article, nous discutons de l'impact des images sur les performances et des méthodes pour réduire le nombre d'octets envoyés par image.</dd>
+ <dt><a href="/en-US/docs/Learn/Performance/video">Multimédia: vidéo</a></dt>
+ <dd>Le fruit le plus bas de la performance Web est souvent l'optimisation des médias. Dans cet article, nous discutons de l'impact du contenu vidéo sur les performances, et des astuces telles que la suppression de pistes audio des vidéos d'arrière-plan peuvent améliorer les performances.</dd>
+ <dt><a href="/en-US/docs/Learn/Performance/JavaScript">Meilleures pratiques en matière de performances JavaScript</a></dt>
+ <dd>JavaScript, lorsqu'il est utilisé correctement, peut permettre des expériences Web interactives et immersives - ou il peut considérablement nuire au temps de téléchargement, au temps de rendu, aux performances dans l'application, à l'autonomie de la batterie et à l'expérience utilisateur. Cet article décrit certaines bonnes pratiques JavaScript à prendre en compte pour garantir que même un contenu complexe est aussi performant que possible.</dd>
+ <dt><a href="/en-US/docs/Learn/Performance/HTML">Fonctionnalités de performances HTML</a></dt>
+ <dd>Certains attributs et l'ordre source de votre balisage peuvent avoir un impact sur les performances de votre site Web. En minimisant le nombre de nœuds DOM, en vous assurant que le meilleur ordre et les meilleurs attributs sont utilisés pour inclure du contenu tel que des styles, des scripts, des médias et des scripts tiers, vous pouvez considérablement améliorer l'expérience utilisateur. Cet article examine en détail comment le HTML peut être utilisé pour garantir des performances optimales.</dd>
+ <dt><a href="/fr/docs/Learn/Performance/CSS">Optimisation des performances en CSS</a></dt>
+ <dd>Le CSS peut être un objectif d'optimisation moins important pour améliorer les performances, mais certaines fonctionnalités CSS ont un impact plus important sur les performances que d'autres. Dans cet article, nous examinons certaines propriétés CSS qui ont un impact sur les performances et suggérons des méthodes de gestion des styles pour garantir que les performances ne sont pas affectées négativement.</dd>
+ <dt><a href="/en-US/docs/Learn/Performance/Fonts">Polices et performances</a></dt>
+ <dd>Examinez si vous devez inclure des polices externes et, le cas échéant, comment inclure les polices dont votre conception a besoin avec le moins d'impact sur les performances de vos sites.</dd>
+</dl>
+
+<dl>
+ <dt><a href="/en-US/docs/Learn/Performance/Mobile">Performances mobiles</a></dt>
+ <dd>L'accès Web sur les appareils mobiles étant si populaire et toutes les plates-formes mobiles ayant des navigateurs Web à part entière, mais éventuellement une bande passante, un processeur et une autonomie de batterie limités, il est important de prendre en compte les performances de votre contenu Web sur ces plates-formes. Cet article examine les considérations de performances spécifiques aux mobiles.</dd>
+ <dt><a href="/en-US/docs/Learn/Performance/business_case_for_performance">Mettre l'accent sur la performance</a></dt>
+ <dd>Un développeur peut faire de nombreuses choses différentes pour améliorer les performances, mais à quelle vitesse est-il assez rapide? Comment pouvez-vous convaincre les pouvoirs de l'importance de ces efforts? Une fois optimisé, comment pouvez-vous vous assurer que le ballonnement ne revient pas? Dans cet article, nous examinons des directions convaincantes, développons une culture de performance et un budget de performance, et introduisons des moyens de garantir que les régressions ne se faufilent pas dans votre base de code.</dd>
+</dl>
+
+<h2 id="Voir_aussi">Voir aussi</h2>
+
+<dl>
+ <dt><a href="/en-US/docs/Learn/Performance/Web_Performance_Basics">Ressources de performance Web</a></dt>
+ <dd>Outre les composants frontaux des fichiers HTML, CSS, JavaScript et multimédia, il existe des fonctionnalités qui peuvent ralentir les applications et des fonctionnalités qui peuvent rendre les applications subjectivement et objectivement plus rapides. Il existe de nombreuses API, outils de développement, bonnes pratiques et mauvaises pratiques relatives aux performances Web. Ici, nous présenterons bon nombre de ces fonctionnalités au niveau de base et fournirons des liens vers des plongées plus approfondies pour améliorer les performances de chaque sujet.</dd>
+ <dt><a href="/en-US/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images">Images responsives</a></dt>
+ <dd>Dans cet article, nous découvrirons le concept d'images responsives - des images qui fonctionnent bien sur des appareils avec des tailles d'écran, des résolutions et d'autres fonctionnalités très différentes - et nous examinerons les outils fournis par HTML pour les implémenter. Cela permet d'améliorer les performances sur différents appareils. Les images responsives ne sont qu'une partie du <a href="/fr/docs/Apprendre/CSS/CSS_layout/Responsive_Design">responsive design</a>, un futur sujet CSS à apprendre.</dd>
+ <dt><a href="/fr/docs/Web/Performance">Section principale des performances Web sur MDN</a></dt>
+ <dd>Notre section principale sur les performances Web - vous trouverez ici beaucoup plus de détails sur les performances Web, y compris des aperçus des API de performance, des outils de test et d'analyse et des problèmes de goulots d'étranglement des performances.</dd>
+</dl>
diff --git a/files/fr/learn/performance/pourquoi_performance_web/index.html b/files/fr/learn/performance/pourquoi_performance_web/index.html
new file mode 100644
index 0000000000..ec49c36548
--- /dev/null
+++ b/files/fr/learn/performance/pourquoi_performance_web/index.html
@@ -0,0 +1,101 @@
+---
+title: Le "pourquoi" des performances Web
+slug: Learn/Performance/pourquoi_performance_web
+tags:
+ - Apprendre
+ - Débutant
+ - Introduction
+ - Performance
+ - Performance Web
+ - Reference
+ - Tutoriel
+translation_of: Learn/Performance/why_web_performance
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{NextMenu("Learn/Performance/What_is_web_performance", "Learn/Performance")}}</div>
+
+<p>La performance Web consiste à rendre les sites Web rapides, y compris à rendre les processus lents rapides. Cet article explique pourquoi les performances Web sont importantes pour les visiteurs du site et pour vos objectifs commerciaux.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Prérequis:</th>
+ <td>Connaissances de base en informatique, <a href="/fr/docs/Apprendre/Commencer_avec_le_web/Installation_outils_de_base">installation des outils de base</a>, et connaissances de base des <a href="/fr/docs/Apprendre/Commencer_avec_le_web">technologies Web côté client</a>.</td>
+ </tr>
+ <tr>
+ <th scope="row">Objectif:</th>
+ <td>Connaître les raisons pour lesquelles les performances Web sont importantes pour une bonne expérience utilisateur.</td>
+ </tr>
+ </tbody>
+</table>
+
+<p>Les performances Web font référence à la rapidité avec laquelle le contenu du site se <strong>charge</strong> et <strong>s'affiche</strong> dans un navigateur web, et à la façon dont il répond à l'interaction de l'utilisateur. Les sites peu performants sont lents à afficher et à répondre aux entrées. Les sites mal performants augmentent l'abandon des sites. Au pire, une mauvaise performance rend le contenu totalement inaccessible. Un bon objectif pour les performances Web est que les utilisateurs ne remarquent pas les performances. Alors que la perception d'un individu sur les performances du site est subjective, le chargement et le rendu peuvent être mesurés. De bonnes performances peuvent ne pas être évidentes pour la plupart des visiteurs du site, mais la plupart reconnaîtront immédiatement un site lent. C'est pourquoi nous nous soucions de cela.</p>
+
+<h2 id="Pourquoi_se_soucier_de_la_performance">Pourquoi se soucier de la performance?</h2>
+
+<p class="summary">Les performances Web et les meilleurs pratiques associées sont essentielles pour que les visiteurs de votre site Web aient une bonne expérience. En un sens, les performances Web peuvent être considérées comme un sous-ensemble de l'<a href="/fr/docs/Apprendre/a11y">accessibilité web</a>. Avec les performaces comme avec l'accessibilité, vous considérez que appareil un visiteur du site utilise pour accéder au site et la vitesse de connexion de l'appareil.</p>
+
+<p class="summary">À titre d'exemple, considérons l'expérience de chargement de CNN.com, qui, au moment de la rédaction de cet article,  avait plus de 400 requêtes HTTP avec une taille de fichier supérieure à 22.6Mo.</p>
+
+<ul>
+ <li class="summary">Imaginez charger ceci sur un ordinateur de bureau connecté à un réseau de fibre optique. Cela semblerait relativement rapide, et la taille du fichier serait en grande partie sans importance.</li>
+ <li class="summary">Imaginez charger ce même site en utilisant des données mobiles connectées sur un iPad de 9 ans tout en vous rendant chez vous en transport en commun. Le même site sera lent à se charger, voir presque inutilisable en fonction de la couverture cellulaire. Vous pourriez abandonner avant la fin du chargement.</li>
+ <li class="summary">Imaginez charger ce même site sur un appareil Huawei à 35$ dans une Inde rurale avec une couverture limitée ou pas de couverture. Le site sera très lent à se charger - s'il se charge du tout - avec des scripts de blocage pouvant expirer et un impact négatif sur le processeur provoquant des plantages du navigateur s'il se charge.</li>
+</ul>
+
+<p class="summary">Un site de 22.6 Mo peut prendre jusqu'à 83 secondes pour se charger sur un réseau 3G, avec <code><a href="/en-US/docs/Web/API/Document/DOMContentLoaded_event">DOMContentLoaded</a></code> (c'est-à-dire la structure HTML de base du site) à 31.86 secondes.</p>
+
+<p class="summary">Et ce n'est pas seulement le temps de téléchargement qui est un problème majeur. De nombreux pays ont encore des connexions internet facturées âr mégaoctet. Notre exemple de 22,6 Mo d'expérience CNN.com coûterait environ 11% du salaire quotidien moyen d'un Indien à télécharger. À partir d'un appareil mobile en Afrique du Nord-Ouest, cela peut coûter deux jours de salaire moyen. Et si ce site était chargé sur le plan d'itinérance internationale d'un opérateur américain? Les coûts feraient pleurer n'importe qui. (Voir <a href="https://whatdoesmysitecost.com/">combien coûte le téléchargement de votre site</a>.)</p>
+
+<p dir="ltr"></p>
+
+<h3 dir="ltr" id="Améliorer_les_taux_de_conversion">Améliorer les taux de conversion</h3>
+
+<p>La réduction du temps de téléchargement et de rendu d'un site améliore les taux de conversion et la fidélisation des utilisateurs.</p>
+
+<p>Un <strong>taux de conversion</strong> est le taux auquel les visiteurs du site effectuent une action mesurée ou souhaitée. Par exemple, il peut s'agir d'effectuer un achat, de lire un article ou de vous abonner à une newsletter. L'action mesurée en tant que taux de conversion dépend des objectifs commerciaux du site web.</p>
+
+<p>La performance influe sur la conversion; l'amélioration des performances Web améliore la conversion. Les visiteurs du site s'attendent à ce qu'un site se charge en deux secondes ou moins; parfois encore moins sur mobile (où cela prend généralement plus de temps). Ces mêmes visiteurs du site commencent à abandonner les sites lents à 3 secondes.</p>
+
+<p>La vitesse à laquelle un site se charge est un facteur. Si le site est lent à réagir à l'interaction de l'utilisateur, ou semble saccadé, cela entraîne une perte d'intérêt et de confiance des visiteurs du site.</p>
+
+<p dir="ltr">Voici quelques exemples concrets d'améliorations des performances:</p>
+
+<ul>
+ <li dir="ltr">
+ <p dir="ltr"><a href="https://wpostats.com/2018/05/30/tokopedia-new-users.html">Tokopedia a réduit le temps de rendu de 14s à 2s pour les connexions 3G et a vu une augmentation de 19% des visiteurs, 35% d'augmentation du nombre total de sessions, 7% d'augmentation des nouveaux utilisateurs, 17% d'augmentation des utilisateurs actifs et 16% d'augmentation des sessions par utilisateur.</a></p>
+ </li>
+ <li dir="ltr">
+ <p dir="ltr"><a href="https://wpostats.com/2017/03/10/pinterest-seo.html">La reconstruction des pages Pinterest pour les performances a entraîné une réduction de 40% du temps d'attente, une augmentation de 15% du trafic SEO et d'une augmentation de 15% du taux de conversion pour l'inscription.</a></p>
+ </li>
+</ul>
+
+<p class="summary">Pour créer des sites Web et des applications que les gens veulent utiliser; pour attirer et fidéliser les visiteurs du site, vous devez créer un site accessible qui offre une bonne expérience utilisateur. La création de sites Web nécessite HTML, CSS et JavaScript, y compris généralement des types de fichiers binaires tels que des images et des vidéos. Les décisions que vous prenez et les outils que vous choisissez lors de la création de votre site peuvent grandement affecter les performances du travail fini.</p>
+
+<p class="summary">Une bonne performance est un atout. Une mauvaise performance est une responsabilité. La vitesse du site affecte directement les taux de rebond, la conversion, les revenus, la satisfaction des utilisateurs et le classement des moteurs de recherche. Il a été démontré que les sites performants augmentent la rétention des visiteurs et la satisfaction des utilisateurs. Il a été démontré que la lenteur du contenu conduit à l'abandon du site, certains visiteurs partant pour ne jamais revenir. La réduction de la quantité de données qui passe entre le client et le serveur réduit les coûts pour toutes les parties. La réduction de la taille des fichiers HTML/CSS/JavaScript et multimédia réduit à la fois le temps de chargement et la consommation d'énergie d'un site (voir <a href="/fr/docs/Web/Performance/Budgets_de_performance">performance budgets</a>).</p>
+
+<p>Le suivi des performances est important. Plusieurs facteurs, notamment la vitesse du réseau et les capacités de l'appareil, affectent les performances. Il n'y a pas de mesure de performance unique; et des objectifs commerciaux différents peuvent signifier que différentes mesures sont plus pertinentes pour les objectifs du site ou de l'organisation qu'il prend en charge. La perception de la performance de votre site est l'expérience utilisateur!</p>
+
+<h2 id="Conclusion">Conclusion</h2>
+
+<p>Les performances Web sont importantes pour l'accessibilité et également pour d'autres mesures de site Web qui servent les objectifs d'une organisation ou d'une entreprise. Les bonnes ou mauvaises performances du site Web sont fortement corrélées à l'expérience utilisateur, ainsi qu'à l'efficacité globale de la plupart des sites. C'est pourquoi vous devez vous soucier des performances Web.</p>
+
+<p>{{NextMenu("Learn/Performance/What_is_web_performance", "Learn/Performance")}}</p>
+
+<h2 id="Dans_ce_module">Dans ce module</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/Performance/why_web_performance">The "why" of web performance</a></li>
+ <li><a href="/en-US/docs/Learn/Performance/What_is_web_performance">What is web performance?</a></li>
+ <li><a href="/en-US/docs/Learn/Performance/Perceived_performance">How do users perceive performance?</a></li>
+ <li><a href="/en-US/docs/Learn/Performance/Measuring_performance">Measuring performance</a></li>
+ <li><a href="/en-US/docs/Learn/Performance/Multimedia">Multimedia: images</a></li>
+ <li><a href="/en-US/docs/Learn/Performance/video">Multimedia: video</a></li>
+ <li><a href="/en-US/docs/Learn/Performance/JavaScript">JavaScript performance best practices</a>.</li>
+ <li><a href="/en-US/docs/Learn/Performance/HTML">HTML performance features</a></li>
+ <li><a href="/fr/docs/Learn/Performance/CSS">Optimisation des performances en CSS</a></li>
+ <li><a href="/en-US/docs/Learn/Performance/Fonts">Fonts and performance</a></li>
+ <li><a href="/en-US/docs/Learn/Performance/Mobile">Mobile performance</a></li>
+ <li><a href="/en-US/docs/Learn/Performance/business_case_for_performance">Focusing on performance</a></li>
+</ul>
diff --git a/files/fr/learn/server-side/django/admin_site/index.html b/files/fr/learn/server-side/django/admin_site/index.html
new file mode 100644
index 0000000000..1485d7e8a1
--- /dev/null
+++ b/files/fr/learn/server-side/django/admin_site/index.html
@@ -0,0 +1,371 @@
+---
+title: 'Django didactique Section 4: Site d''administration de Django'
+slug: Learn/Server-side/Django/Admin_site
+tags:
+ - Apprentissage
+ - Article
+ - Didacticiel
+ - Débutant
+ - Python
+ - django
+ - django_admin
+translation_of: Learn/Server-side/Django/Admin_site
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/Server-side/Django/Models", "Learn/Server-side/Django/Home_page", "Learn/Server-side/Django")}}</div>
+
+<p class="summary">Nous avons créé le modèle de données pour le site web de la <a href="/fr/docs/Learn/Server-side/Django/Tutorial_local_library_website">bibliothèque locale</a>. Dans ce chapitre nous allons utiliser le site d'administration pour introduire des données réelles pour les livres. Dans un premier temps, nous aborderons la manière d'enregistrer les données des objets sur le site d'administration et comment se connecter au site et créer des données. La fin de ce chapitre sera dédié à des éléments d'amélioration possible du site d'administration.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Pré-requis:</th>
+ <td>Avoir complété <a href="/fr/docs/Learn/Server-side/Django/Models">Django didactique Section 3: Utilisation des modèles de données</a></td>
+ </tr>
+ <tr>
+ <th scope="row">Objectif:</th>
+ <td>Comprendre les avantages et les limites du site d'administration de Django. Utiliser ce site pour enregistrer des données pour les objets créés dans le chapitre précédent.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Survol">Survol</h2>
+
+<p>Le site d'administration et l'application admin associée de Django peut utiliser les objets déclarés du modèle de données pour réaliser automatiquement un espace de publications, de création, de mise à jour ou de suppression d'enregistrements. Cet outil permet d'économiser du temps pendant les développements et de tester rapidement le modèle de données et par voie de conséquence de vérifier la disponibilité des données et la cohérence du modèle créé. En fonction de votre type d'application web, le site d'administration peut aussi servir à gérer les données du site en production. Comme une approche centrée sur le modèle de données n'est pas appropriée à une présentation utilisateur, les concepteurs de Django recommandent de ne se servir de ce site que pour une administration interne des données (c'est-à-dire, juste pour les administrateurs techniques ou fonctionnels de l'application).</p>
+
+<p>Quand nous avons créé <a href="/fr/docs//Learn/Server-side/Django/skeleton_website">le squelette du projet</a>, nous avons généré automatiquement toute ce qui était nécessaire à son administration au sein de l'application web (<a href="https://docs.djangoproject.com/fr/2.2/ref/contrib/admin/">le détail des relations en jeux</a> sont décrites sur le site documentaire Django). Au final, vous n'aurez juste qu'à ajouter vos modèles dans l'administration du site en les enregistrant. A la fin de ce chapitre, vous aurez des pistes sur l'une des manière d'améliorer l'affichage des données dans la zone d'administration.</p>
+
+<p>Passons aux actes ! Après l'enregsitrment des objets du modèle relationnel, nous verrons comment créer un super-utilisateur, s'authetifier et ensuite créer quelques livres, auteurs et ouvrages à la dispostion des lecteurs. Ces données seront très utiles pour tester ensuite les vues et gabarits qui seront abordés dans les chapitres suivants.</p>
+
+<h2 id="Enregistrer_les_objets_de_la_modélisation">Enregistrer les objets de la modélisation</h2>
+
+<p>En premier lieu, il faut editer le fichier <strong>admin.py</strong> de l'application catalog (c'est-à-dire le fichier <strong>./locallibrary/catalog/admin.py</strong>). Il devrait ressembler à celui ci-dessous — notez qu'il contient d'ores et déjà l'import du module <code>django.contrib.admin</code>:</p>
+
+<pre class="brush: python">from django.contrib import admin
+
+# Register your models here.
+</pre>
+
+<p>L'enregistrement de objets de modélisation ce fait par l'appel de la fonction <code>admin.site.register</code> comme indiqué ci-dessous. Il vous suffit pour le moment de copier le texte ci-dessous et de l'ajouter à la fin du fichier.Register the models by copying the following text into the bottom of the file.</p>
+
+<pre class="brush: python">from catalog.models import Author, Genre, Book, BookInstance
+
+admin.site.register(Book)
+admin.site.register(Author)
+admin.site.register(Genre)
+admin.site.register(BookInstance)
+</pre>
+
+<div class="note"><strong>Note</strong>: Si vous avez répondu au défi de la modelisation des langues des livres (<a href="/fr/docs/Learn/Server-side/Django/Models">voir le chapitre précédent sur les modèles de données</a>), vous pouvez aussi importer cet objet !<br>
+<br>
+Cela devrait être de la forme : <code>admin.site.register(Language)</code> et n'oubliez pas d'importer l'objet.</div>
+
+<p>C'est la méthode la plus rapide et la plus simple pour enregistrer un ou plusieurs modèles. Le site d'administration est très adaptable et nous aborderons plus loin ces questions.</p>
+
+<h2 id="Générer_un_super-utilisateur">Générer un super-utilisateur</h2>
+
+<p>Pour acceder au site d'administration, il est necessaire de s'authentifier avec un utilisateur qui dispose du statut <em>Statut d'équipe</em> activé. Afin de visualiser et créer des enregsitrement, vous aurez aussi besoin de disposer de droits de manipulation des obejts. A ce stade, vous pouvez créer à l'aide du fichier <strong>manage.py</strong> un super-utilisateur qui dispose de tous les droits et permissions.</p>
+
+<p>Exécutez la commande python ci-dessous qui appelle le fichier <strong>manage.py</strong> en étant dans le même dossier que le fichier (c'est-à-dire <strong>./locallibrary/</strong>), pour créer le super-utilsiateur. La commande va vous demander de répondre le nom d'utilsiateur, l'adresse mail et un mot de passe fort.</p>
+
+<pre class="brush: bash">python3 manage.py createsuperuser
+</pre>
+
+<p>Une fois cette étape réalisée, vous pouvez redémarrer le serveur de développement :</p>
+
+<pre class="brush: bash">python3 manage.py runserver
+
+</pre>
+
+<h2 id="Accéder_et_utiliser_le_site_admin">Accéder et utiliser le site admin</h2>
+
+<p>Pour vous authentifier au site, ouvrez l'URL <em>/admin </em>du site local (concrètement, <a href="http://127.0.0.1:8000/admin/">http://127.0.0.1:8000/admin</a>) et identifiez vous avec votre compte de super-utilisateur.</p>
+
+<div class="blockIndicator note">
+<p>Vous serez redirigez vers l'application interne à Django de gestion de l'authentification et la pages de demande d'authentitification avant d'accéder réellement au site d'administration.</p>
+
+<p>Si vous accéder au site local sans /admin, vous aurez un message d'erreur car les routages d'URL n'ont pas encore été traité. ne vous en inquiétez pas cela va venir...</p>
+</div>
+
+<p>Cet partie du site affiche tous les modèles définis et déclarés dans le fichier de contrôle de l'administration du site. Les objets sont regroupés par application (pour notre cas, uniquement l'application Catalog à cette étape des travaux). Vous pouvez cliquez sur chacun des noms d'objet publiés pour accéder à l'écran qui gère les informations sur les objets de ce type contenu en base de données et vous pouvez les éditer et les modifier. Vous pouvez aussi cliquer sur le lien <strong>+ Ajouter</strong> pour créer un nouvel enregistrement.</p>
+
+<p><img alt="Admin Site - Home page" src="https://mdn.mozillademos.org/files/13975/admin_home.png" style="display: block; height: 634px; margin: 0px auto; width: 998px;"></p>
+
+<p>Cliquez sur le lien <strong>+ Ajouter</strong> à la droite de l'objet Books pour créer un nouveau livre. Le site va afficher une page de saisie de données (analogue à celle ci-dessous). Notez que Django prend en compte le type de champs définit dans le modèle pour utiliser le widget associé ainsi que le champs <code>help_text</code> quand vous l'aviez défini. </p>
+
+<p>Entrez les valeurs des champs. Pour les champs qui relève de relations entre objet, vous pouvez utiliser le bouton + pour accéder en cascade au formulkaire de saisie des informations nécessaires à la créarion de cette objet. Vous pouvez aussi sélectionner un objet si d'autres avaient été créés précédement. Ne pas oublier de cliquer sur <strong>Enregistrer et ajouter un nouveau</strong> ou <strong>Enregistrer et continuer les modification</strong> pour sauvegarder en base de données les informations saisies.</p>
+
+<p><img alt="Admin Site - Book Add" src="https://mdn.mozillademos.org/files/13979/admin_book_add.png" style="border-style: solid; border-width: 1px; display: block; height: 780px; margin: 0px auto; width: 841px;"></p>
+
+<div class="note">
+<p><strong>Note</strong>: À ce stade, prenez le temps d'enregistrer plusieurs livres, genres et auteurs. Assurez-vous que chacun est associé à plusieurs autres éléments cela rendra vos listes à venir plus riches et intéressantes quand nous aborderons ces sujets.</p>
+</div>
+
+<p>Après avoir saisie les informations et ajouté vos livres, cliquez sur le lien <strong>Accueil</strong> pour revenir à la page principale du site d'administration. Cliquez sur le lien <strong>Books</strong> pour afficher la liste des livres enregistrés (ou sur d'autres liens pour voir les autres objets présents en base). Après avoir ajouter quelques livres, votre page devrait ressembler à celle ci-dessous. La liste des livres est affichée par titre ; c'est, en fait, la valeur délivrée par la méthode <code>__str__()</code> du modèle d'objet Book comme cela a été codé dans le précédent chapitre.</p>
+
+<p><img alt="Admin Site - List of book objects" src="https://mdn.mozillademos.org/files/13935/admin_book_list.png" style="border-style: solid; border-width: 1px; display: block; height: 407px; margin: 0px auto; width: 1000px;"></p>
+
+<p>À partir de la liste affichée, vous pouvez supprimer des instances en selectionnant les items par les cases à cocher à gauche du titre puis <em>supprimer...</em> dans la liste des actions proposée puis en cliquant sur <strong>Envoyer</strong>. Vous pouvez aussi ajouter des livres en cliquant sur <strong>AJOUTER BOOK</strong>.</p>
+
+<p>Vous pouvez editer un livre en cliquant son nom sur la liste des ouvrages. La page d'édition, image ci-dessous, est proche de celle d'ajout d'un livre. Les principales différences sont le titre de la page (Modification de book, au lieu d'ajout de bbok), l'ajout en rouge du bouton supprimer, l'historique des modifications et voir sur le site. Ce dernier bouton est visible car nous créer la méthode <code>get_absolute_url()</code> dans la définition du modèle de données (à ce stade, une erreur sera provoquée si vous cliquez sur ce bouton).</p>
+
+<p><img alt="Admin Site - Book Edit" src="https://mdn.mozillademos.org/files/13977/admin_book_modify.png" style="border-style: solid; border-width: 1px; display: block; height: 780px; margin: 0px auto; width: 841px;"></p>
+
+<p>Revenez à la page d'accueil (à l'aide du lien <strong>Accueil</strong> du fil d'Ariane), puis affichez les listes des <strong>Authors</strong> et des <strong>Genres</strong>. Vous devriez déjà en avoir créé un certain nombre à partir de l'ajout des nouveaux livres, mais n'hésitez pas à en ajouter d'autres.</p>
+
+<p>Ce qui manque actuellement ce sont des <em>Book Instances</em>. Vous n'en avez pas car elles ne sont pas créées à partir des objets Books (bien que vous pourriez créer un objet <code>Book</code> à partir d'un objet <code>BookInstance</code> car c'est la nature de la relation <code>ForeignKey</code>). Retournez à la page d'acceuil et cliquez sur le bouton <strong>Ajouter</strong> associé aux objets Book Instance et accéder à l'écran de création. Vous pouvez noter le très grand identifiant unique global utilisé pour identifier séparelment les ouvrages.</p>
+
+<p><img alt="Admin Site - BookInstance Add" src="https://mdn.mozillademos.org/files/13981/admin_bookinstance_add.png" style="border-style: solid; border-width: 1px; display: block; height: 514px; margin: 0px auto; width: 863px;"></p>
+
+<p>Créez plusieurs de ces enregistrements pour chacun de vos livres. Définissez un statut <strong>Available</strong> (<em>Disponible</em>) pour certains d'entre eux et <strong>On loan</strong> (<em>Prêt</em>) pour d’autres. Pour un statut différent de <em>Available</em>, vous devrez préciser une date d'échéance à venir.</p>
+
+<p>Nous avons terminé cette étape ! Vous savez comment configurer et utiliser le site d'administration. Vous pouvez continuer à créer des enregistrements pour Book, BookInstance, Genre et Author, que nous pourrons utiliser une fois que nous aurons créé nos propres vues de détail.</p>
+
+<h2 id="Configuration_avancée">Configuration avancée</h2>
+
+<p>La cadriciel Django réalise une excellente assistance avec la création d'un site d'administration debase en utilisant les données des enregistrements effectués :</p>
+
+<ul>
+ <li>Pour chaque modèles, les enregistrement sont identifiés par le résultat de la méthode<code> __str__()</code>, et les détails sont accessible par des vues dédiées. Par défaut, ces vues et formulaires dispose d'un menu en haut et vous pouvez opérer des opérations de suppressions en bloc en sélectionnant les enregistrements.</li>
+ <li>Le détail de chaque modèle est contenu dans un formulaire où chaque champ est affiché verticalement dans l'ordre de déclaration de ces derniers dans le modèle d'objet. </li>
+</ul>
+
+<p>mais vous avez la possibilité de personnaliser le comportement du site d'administration. Vous allez pouvoir notamment faire :</p>
+
+<ul>
+ <li>Des vues en liste
+ <ul>
+ <li>Ajouter des champs ou des informations supplémentaires affichés pour chaque enregistrement.</li>
+ <li>Ajouter des filtres pour sélectionner les enregistrements répertoriés, en fonction de la date ou d’une autre valeur de sélection (par exemple, le statut du prêt du livre).</li>
+ <li>Ajouter des options supplémentaires au menu Actions dans les vues de liste et choisir l'emplacement où ce menu est affiché dans le formulaire.</li>
+ </ul>
+ </li>
+ <li><span class="tlid-translation translation" lang="fr"><span title="">Vues détaillées</span></span>
+ <ul>
+ <li><span class="tlid-translation translation" lang="fr"><span title="">Choisir les champs à afficher (ou à exclure), ainsi que leur ordre, leur groupement, leur caractère modifiable, le widget utilisé, leur orientation, etc.</span></span></li>
+ <li><span class="tlid-translation translation" lang="fr"><span title="">Ajouter des champs associés à un enregistrement pour permettre la modification en ligne (par exemple, ajoutez la possibilité d'ajouter et de modifier des enregistrements de livre lors de la création de leur auteur).</span></span></li>
+ </ul>
+ </li>
+</ul>
+
+<p>Dans la section qui suit, nous allons effectuer quelques modification pour améliorer l'interface de votre application <em>LocalLibrary</em>. Nous allons notamment ajouter des information pour les objets <code>Book</code> et <code>Author</code>, et améliorer la présentation de leur vue d'édition. Il n'y aura pas de changement pour les objets <code>Language</code> et <code>Genre</code> qui ne possède pas assez d'information pour que cela puisse avoir une incidence réelle !</p>
+
+<p>Le détail complet de la personnalisation du site d'administration est disponible <a href="https://docs.djangoproject.com/fr/2.2/ref/contrib/admin/">sur le site documentaire de Django</a>.</p>
+
+<h3 id="Enregistrer_un_objet_de_la_classe_ModelAdmin">Enregistrer un objet de la classe ModelAdmin</h3>
+
+<p>Pour modifier la manière d'afficher un objet hérité de la classe Model dans l'interface d'administration, vous devez définir une classe d'objet héritée de la classe ModelAdmin qui décrit l'affichage d'un objet et de l'enregistrer avec votre objet Model.</p>
+
+<p>Commençons avec l'objet <code>Author</code>. Éditez le fichier <strong>admin.py</strong> dans le dossier catalog de l'application(concrètement le fichier <strong>/locallibrary/catalog/admin.py</strong>). Commentez la ligne qui vous a permis d'enregistrer l'objet <code>Author</code> :</p>
+
+<pre class="brush: js"># admin.site.register(Author)</pre>
+
+<p>Ensuite ajoutez une nouvelle classe d'objets <code>AuthorAdmin</code> et enregistrez-le comme indiqué ci-dessous.</p>
+
+<pre class="brush: python"># Define the admin class
+class AuthorAdmin(admin.ModelAdmin):
+ pass
+
+# Register the admin class with the associated model
+admin.site.register(Author, AuthorAdmin)
+</pre>
+
+<p>Ensuite nous allons opérer de manière analogue avec un objet hérité de <code>ModelAdmin</code> pour les objets <code>Book</code>, et <code>BookInstance</code>. À nouveau, nous commentons les enregistrements initiaux :</p>
+
+<pre class="brush: js"># admin.site.register(Book)
+# admin.site.register(BookInstance)</pre>
+
+<p>Puis nous créons et enrgistrons les nouveaux modèles. Pour les besoins de l'exercice, nous allons utiliser, pour enregistrer ces modèles, le décorateur <code>@register</code> qui réalise la même opération que la méthode <code>admin.site.register()</code> :</p>
+
+<pre class="brush: python"># Register the Admin classes for Book using the decorator
+@admin.register(Book)
+class BookAdmin(admin.ModelAdmin):
+ pass
+
+# Register the Admin classes for BookInstance using the decorator
+@admin.register(BookInstance)
+class BookInstanceAdmin(admin.ModelAdmin):
+ pass
+</pre>
+
+<p>Pour le moment, toutes les classes d’administration sont vides (cf. pass), par conséquent le comportement d'affichage n'est pas modifié. Cependant, nous allons pouvoir désormais modifier les comportements d'affichage pour chacun des objets nouvellements enregistrés.</p>
+
+<h3 id="Configurer_les_vues_en_liste">Configurer les vues en liste</h3>
+
+<p>La liste des auteurs (objet <code>Author</code>) est affiché dans l'application <em>LocalLibrary</em> à l'aide du nom généré par la méthode  <code>__str__()</code>. Ceci fonctionne bien, judqu'à ce que vous aurez de nombreux auteurs et éventuellement des doublons parmi ces auteurs. Pour bien les différencier, ou simplement parce que vous souhaitez avoir directement plus d'informations, vous allez utiliser la directive <a href="https://docs.djangoproject.com/fr/2.2/ref/contrib/admin/#django.contrib.admin.ModelAdmin">list_display</a> tpour ajouter d'autres champs de l'objet <code>Author</code>.</p>
+
+<p><span class="tlid-translation translation" lang="fr"><span title="">Modifiez votre classe <code>AuthorAdmin</code> comme décrit ci-dessous (vous pouvez copier et coller le code).</span> <span title="">Les noms de champs à afficher dans la liste sont déclarés dans un tuple dans l'ordre requis. Ils sont identiques à </span></span><span class="tlid-translation translation" lang="fr"><span title="">ceux spécifiés dans votre modèle d'objet <code>Author</code>.</span></span></p>
+
+<pre class="brush: python">class AuthorAdmin(admin.ModelAdmin):
+ list_display = ('last_name', 'first_name', 'date_of_birth', 'date_of_death')
+</pre>
+
+<p>Si vous accèdez à la page d'administration des auteurs, vous devriez obtenir une page équivalente à celle ci-dessous :</p>
+
+<p><img alt="Admin Site - Improved Author List" src="https://mdn.mozillademos.org/files/14023/admin_improved_author_list.png" style="border-style: solid; border-width: 1px; display: block; height: 302px; margin: 0px auto; width: 941px;"></p>
+
+<p>Pour les livres, nous allons visulaiser les objets  <code>Book</code> en affichant les champs <code>author</code> and <code>genre</code>. Le champs <code>author</code> est de type <code>ForeignKey</code> décrivant une relation un à n. En conséquence, nous afficherons l'élément produit par la méthode <code>__str__()</code> de l'objet <code>Author</code> pour l'instance associée à votre livre. Le genre est une relation n à n, donc nous allons avoir à traiter son affichage de manière particulière. Modifiez la classe <code>BookAdmin</code> comme suit :</p>
+
+<pre class="brush: python">class BookAdmin(admin.ModelAdmin):
+ list_display = ('title', 'author', 'display_genre')
+</pre>
+
+<p>Le champ <font face="Consolas, Liberation Mono, Courier, monospace">genre </font>représente une relation n à n (<code>ManyToManyField</code>)qui ne peut pas être prise en charge par la directive <code>list_display</code>. Le coût d'accès à la base de donnée peut être important et donc le cadriciel se protège de ce phénomène. A la place, nous devons définir une fonction(<code>display_genre</code>) qui permettra de traiter l'affichage des informations souhaitées pour le genre.</p>
+
+<div class="note">
+<p><strong>Note</strong>: C'est dans un but pédagogique que nous recherchons ici l'affichage du <code>genre</code> qui n'a peut-être pas nécessaire d'intérêt et peut représenter un coût d'accès. Nous montrons, ici, comment appler les fonctions dans vos modèles ce qui sera très utile pour la suite de vos applications  — par exemple pour ajouter un lien de suppression de vos enregistrements en liste.</p>
+</div>
+
+<p>Ajoutez le code ci-dessous dans votre modèle d'objet <code>Book</code> (concrètement dans le fichier <strong>locallibrary/catalog/models.py</strong>). Cette fonction génère une chaîne de caractère contenant les trois premières valeurs de tous les genres (s'ils existent) et créer une courte destription (<code>short_description</code>) qui sera utilisé par le site d'administration avec cette méthode.</p>
+
+<pre class="brush: python">    def display_genre(self):
+ """Create a string for the Genre. This is required to display genre in Admin."""
+ return ', '.join(genre.name for genre in self.genre.all()[:3])
+
+ display_genre.short_description = 'Genre'
+</pre>
+
+<p>Après avoir sauvegardé vos fichiers models.py et admin.py, vous pouvez accéder à la page web d'administration des livres et vous y découvrirez une page semblable à celle ci-dessous :</p>
+
+<p><img alt="Admin Site - Improved Book List" src="https://mdn.mozillademos.org/files/14025/admin_improved_book_list.png" style="border-style: solid; border-width: 1px; display: block; height: 337px; margin: 0px auto; width: 947px;"></p>
+
+<p>Les champs <code>Genre</code> <code>Language</code> ne dispose que d'une seule valeur. Il n'est donc pas utile de créer une page d'affichage spélicale.</p>
+
+<div class="note">
+<p><strong>Note</strong>: Vous trouverez en fin d'article dans la défis personnel des propositions pour améliorer les ouvrages en prêt <code>BookInstance</code> !</p>
+</div>
+
+<h3 id="Ajouter_des_filtres">Ajouter des filtres</h3>
+
+<p>Si vous avez beaucoup d'éléments à l'affichage des listes, il devient utile de d'appliquer des filtres pour les afficher. Ceci est réalisé avec l'attribut <code>list_filter</code> de la classe ModelAdmin. Modifier votre classe d'objet d'affichage <code>BookInstanceAdmin</code> avec les code ci-dessous :</p>
+
+<pre class="brush: python">class BookInstanceAdmin(admin.ModelAdmin):
+<strong> list_filter = ('status', 'due_back')</strong>
+</pre>
+
+<p>La page de la vue en liste des ouvrages à consultation (BookInstance) est désormais agrémentée d'un bloc de filtrage par statut (champs status) et date de retour (due back). Vous pouvez sélectionner la valeur de ces deux critères de filtrage (remarquez la manière avec laquelle les valeurs des critères est proposée).</p>
+
+<p><img alt="Admin Site - BookInstance List Filters" src="https://mdn.mozillademos.org/files/14037/admin_improved_bookinstance_list_filters.png" style="height: 528px; width: 960px;"></p>
+
+<h3 id="Organiser_la_vue_d'affichage_d'un_modèle">Organiser la vue d'affichage d'un modèle</h3>
+
+<p>La vue est agencée, par défaut, en affichant verticalement dans l'ordre de déclaration des champs de l'objet modèle. Cette règle d'affichage peut être modifiée en indiquant quels champs afficher (ou exclure) et organiser les informations en sections avec un affichage horizontal ou vertical et les widgets à utiliser.</p>
+
+<div class="note">
+<p><strong>Note</strong>: Les modèles de l'application <em>LocalLibrary</em> ne sont pas très compliqués sans énormément d'information à traiter. Il n'y a pas un grand besoin de changement d'affichage ; les éléments ci-dessous sont données pour avoir une idée des possibilités et savoir, le moment venu, comment faire.</p>
+</div>
+
+<h4 id="Contrôler_l'affichage_et_la_dispostion_des_champs">Contrôler l'affichage et la dispostion des champs</h4>
+
+<p>Modifiez votre classe d'objet <code>AuthorAdmin</code> en ajoutant l'attribut <code>fields</code> comme indiqué en gras ci-dessous :</p>
+
+<pre class="brush: python">class AuthorAdmin(admin.ModelAdmin):
+ list_display = ('last_name', 'first_name', 'date_of_birth', 'date_of_death')
+<strong> fields = ['first_name', 'last_name', ('date_of_birth', 'date_of_death')]</strong>
+</pre>
+
+<p>Ce champ (<code>fields</code>) contrôle l'affichage des champs. Les champs déclarés sont affichés verticalement dans l'ordre de déclaration et seront affichés en groupe horizontalement s'ils sont déclarés dans un tuple (c'est le cas pour les date de naissance et de décès des auteurs).</p>
+
+<p>La page web de votre application locale devrait ressembler à celle ci-dessous :</p>
+
+<p><img alt="Admin Site - Improved Author Detail" src="https://mdn.mozillademos.org/files/14027/admin_improved_author_detail.png" style="border-style: solid; border-width: 1px; display: block; height: 282px; margin: 0px auto; width: 928px;"></p>
+
+<div class="note">
+<p><strong>Note</strong>: Vous pouvez aussi utiliser l'attribut <code>exclude</code> pour identifier des attributs du modèle que vous souhaitez exclure de l'affichage (les autres attributs seront alors affichés). Pour plus de détails vous pouvez consulter la documentation Django sur l'attribut <a href="https://docs.djangoproject.com/fr/2.2/ref/contrib/admin/#django.contrib.admin.ModelAdmin.exclude">exclude</a>.</p>
+</div>
+
+<h4 id="Organiser_des_sections_dans_votre_vue_de_détail">Organiser des sections dans votre vue de détail</h4>
+
+<p>Vous avez la possibilité de créer des sections à l'affichage pour regrouper des éléments à renseigner en utilisant l'attribut <a href="https://docs.djangoproject.com/fr/2.2/ref/contrib/admin/#django.contrib.admin.ModelAdmin.fieldsets">fieldsets</a>.</p>
+
+<p>Nous allons utiliser l'objet <code>BookInstance</code> pour mettre en avant cette possibilité. Nous avons à afficher des informations sur l'ouvrage (nom, édition, id) et sur sa disponibilité actuelle ou à venir (statut et retour de prêt). Nous choisissons d'afficher ces éléments dans deux sections différentes, l'une nommée et l'autre pas. Modifiez l'objet BookInstanceAdmin avec le texte en gras comme ci-dessous :</p>
+
+<pre class="brush: python">@admin.register(BookInstance)
+class BookInstanceAdmin(admin.ModelAdmin):
+ list_filter = ('status', 'due_back')
+
+<strong> fieldsets = (
+ (None, {
+ 'fields': ('book', 'imprint', 'id')
+ }),
+ ('Availability', {
+ 'fields': ('status', 'due_back')
+ }),
+ )</strong></pre>
+
+<p>Chaque section peut avoir un titre (ou aucun si vous indiquez la valeur <code>None</code>) et des champs regroupés à l'aide de tuples enregistrés dans un dictionnaire — le schéma de déclaration peut paraître compliqué à décrire mais assez aisé à comprendre à la lecture du code ci-dessus formaté pour être plus compréhensible.</p>
+
+<p>Le résultat de cette description devrait vous apparaître de manière analogue à celle présente  ci-dessous :</p>
+
+<p><img alt="Admin Site - Improved BookInstance Detail with sections" src="https://mdn.mozillademos.org/files/14029/admin_improved_bookinstance_detail_sections.png" style="border-style: solid; border-width: 1px; display: block; height: 580px; margin: 0px auto; width: 947px;"></p>
+
+<h3 id="Publier_des_enregistrements_associés">Publier des enregistrements associés</h3>
+
+<p>Parfois, il peut être très utile d'ajouter à l'affichage des éléments associés en même temps. C'est le cas, par exemple, pour les copies d'ouvrage associés à un livre en bibliothèque. Il est utile pour le bibliothécaire de disposer à la fois des informations sur le livre et des copies présentes ou non en rayonnage..</p>
+
+<p>Pour cela, vous pouvez utiliser un d'objet pour un affichage horizontal (<a href="https://docs.djangoproject.com/fr/2.2/ref/contrib/admin/#django.contrib.admin.TabularInline">TabularInline</a>) ou vertical (<a href="https://docs.djangoproject.com/fr/2.2/ref/contrib/admin/#django.contrib.admin.StackedInline">StackedInline)</a> (qui n'est autre que l'affichage standard des données). Modifiez le code associé à votre modèle <code>BookInstance</code> dans le fichier <strong>admin.py</strong> pour disposer des informations <em>inline</em> à l'affichage des informations sur votre objet <code>Book</code>. Gardez en mémoire que c'est l'objet  <code>BookAdmin</code> qui gère l'affichage les informations de l'objet <code>Book</code>; c'est donc <code>BookAdmin</code> il doit donc être modifié :</p>
+
+<pre class="brush: python"><strong>class BooksInstanceInline(admin.TabularInline):
+    model = BookInstance</strong>
+
+@admin.register(Book)
+class BookAdmin(admin.ModelAdmin):
+    list_display = ('title', 'author', 'display_genre')
+<strong>    inlines = [BooksInstanceInline]</strong>
+</pre>
+
+<p>Si vous allez consulter un livre, vous devriez pouvoir, au bas de la page, consulter la liste des copies enregistrées :</p>
+
+<p><img alt="Admin Site - Book with Inlines" src="https://mdn.mozillademos.org/files/14033/admin_improved_book_detail_inlines.png" style="border-style: solid; border-width: 1px; display: block; height: 889px; margin: 0px auto; width: 937px;"></p>
+
+<p>Dans le cas présent nous avons juste décidé d'afficher toutes les informations des copies associées à un livre. Si vous consultez sur la documentation Django les informations relatives au type <a href="https://docs.djangoproject.com/fr/2.2/ref/contrib/admin/#django.contrib.admin.TabularInline">TabularInline</a> vous aurez accès à l'ensemble des éléments qui permettent de filtrer et afficher les éléments dont vous aurez besoin. </p>
+
+<div class="note">
+<p><strong>Note</strong>: Il y a quelques limitation pénibles à ces outils. Si vous observez bien la liste des copies pour un ouvrage, vous decouvrirez des copies fantômes sans nom et informations pré-reservées pour de futures instances à enregistrer. Il serait préférable de ne pas les avoir et vous devriez alors appliquer un filtre pour éliminer de l'affichage ces copies. Vous pourriez aussi ajouter une section particulière pour permettre d'ajouter de nouvelles copies dans les rayonnages... La première solution est assez rapide à traiter en utilisant l'attribut <code>extra</code> à 0 dans la définition de l'objet <code>BooksInstanceInline</code> ... essayez !</p>
+</div>
+
+<h2 id="Défi">Défi</h2>
+
+<p>Beaucoup de sujets ont été abordés dans ce chapitre, c'est l'occasion de les mettre en application :</p>
+
+<ol>
+ <li>Améliorer l'affichage des objets <code>BookInstance</code>, ajoutez les éléments nécessaire pour disposer du livre, du statut de la date de fin de prêt et de l'identifiant au lieu du code unique et du titre donné par la méthode <code>__str__()</code> de l'objet.</li>
+ <li>Ajouter une information associée pour disposer du détail des informations sur l'auteur. Appuyez vous sur l'exemple avec les objets <code>Book</code>/<code>BookInstance</code> pour y parvenir.</li>
+</ol>
+
+<ul>
+</ul>
+
+<h2 id="Résumé">Résumé</h2>
+
+<p>Beaucoup de sujets ont été abordés dans ce chapitre... Vous avez acquis les base du site d'administration et à créer un suoper-utilisateur, voius avez aussi navigué dans le site d'admlinistration et vous avez appris à modifier les formulaires de saisie et comment ajouter, modifier ou supprimer des données.</p>
+
+<h2 id="A_voir_aussi">A voir aussi</h2>
+
+<ul>
+ <li><a href="https://docs.djangoproject.com/fr/2.2/intro/tutorial02/#introducing-the-django-admin">Ecrire sa première application Dajngo, 2ème partie</a>  (Django docs)</li>
+ <li><a href="https://docs.djangoproject.com/fr/2.2/ref/contrib/admin/">Le site d'administration de Django</a> (Django Docs)</li>
+</ul>
+
+<p>{{PreviousMenuNext("Learn/Server-side/Django/Models", "Learn/Server-side/Django/Home_page", "Learn/Server-side/Django")}}</p>
+
+<h2 id="In_this_module">In this module</h2>
+
+<ul>
+ <li><a href="/fr/docs/Learn/Server-side/Django/Introduction">Django introduction</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/development_environment">Setting up a Django development environment</a></li>
+ <li><a href="/fr/docs/Learn/Server-side/Django/Tutorial_local_library_website">Django Didactique: Site web "Bibliothèque locale"</a></li>
+ <li><a href="/fr/docs/Learn/Server-side/Django/skeleton_website">Django didactique Section 2: Créer le squelette du site web</a></li>
+ <li><a href="/fr/docs/Learn/Server-side/Django/Models">Django didactique Section 3: Utilisation des modèles de données</a></li>
+ <li><a href="/fr/docs/Learn/Server-side/Django/Admin_site">Django didactique Section 4 : Site d'administration de Django</a></li>
+ <li><a href="/fr/docs/Learn/Server-side/Django/Home_page">Django didactique Section 5: Créer la page d'accueil</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Generic_views">Django Tutorial Part 6: Generic list and detail views</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Sessions">Django Tutorial Part 7: Sessions framework</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Authentication">Django Tutorial Part 8: User authentication and permissions</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Forms">Django Tutorial Part 9: Working with forms</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Testing">Django Tutorial Part 10: Testing a Django web application</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Deployment">Django Tutorial Part 11: Deploying Django to production</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/web_application_security">Django web application security</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/django_assessment_blog">DIY Django mini blog</a> </li>
+</ul>
diff --git a/files/fr/learn/server-side/django/development_environment/index.html b/files/fr/learn/server-side/django/development_environment/index.html
new file mode 100644
index 0000000000..b47662e6ff
--- /dev/null
+++ b/files/fr/learn/server-side/django/development_environment/index.html
@@ -0,0 +1,423 @@
+---
+title: Mettre en place un environnement de développement Django
+slug: Learn/Server-side/Django/development_environment
+translation_of: Learn/Server-side/Django/development_environment
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/Server-side/Django/Introduction", "Learn/Server-side/Django/Tutorial_local_library_website", "Learn/Server-side/Django")}}</div>
+
+<p class="summary">Maintenant que vous savez à quoi sert Django, nous allons vous montrer comment mettre en place et tester un environnement de développement Django sous Windows, Linux (Ubuntu) et macOS — Peu importe votre système d'exploitation, cet article devrait vous fournir de quoi commencer à développer des applications Django.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Prérequis :</th>
+ <td>Connaissances de base sur l'utilisation d'un terminal/invite de commande et comment installer des packages sur l'OS de l'ordinateur que vous utiliserez pour développer.</td>
+ </tr>
+ <tr>
+ <th scope="row">Objectif :</th>
+ <td>Avoir un environnement de développement pour Django (2.0) fonctionnel sur votre ordinateur.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Aperçu_de_lenvironnement_de_développement_Django">Aperçu de l'environnement de développement Django</h2>
+
+<p>Django simplifie le processus de configuration de votre ordinateur pour que vous puissiez rapidement commencer à développer des applications web. Cette section explique ce que vous aurez dans l'environnement de développement, et vous fournit un aperçu de certaines options de configuration et d'installation. Le reste de l'article explique la méthode <em>recommandée </em>pour installer l'environnement de développement Django sur Ubuntu, macOS et Windows, et comment le tester.</p>
+
+<h3 id="Quest-ce_que_lenvironnement_de_développement_Django">Qu'est-ce que l'environnement de développement Django ?</h3>
+
+<p>L'environnement de développement correspond à une installation de Django sur votre ordinateur local que vous pouvez utiliser pour développer et tester des applications Django avant de les déployer sur un environnement de production.</p>
+
+<p>Le principal outil que fournit Django est un ensemble de scripts Python utilisés pour créer et travailler avec des projets Django, ainsi qu'un simple <em>serveur web de développement </em>que vous pouvez utiliser pour tester en local (i.e. sur votre propre ordinateur, pas sur un serveur web externe) des applications web Django dans votre navigateur web.</p>
+
+<p>Il y a plusieurs autres outils annexes, qui font partie de l'environnement de développement, que nous ne couvrirons pas ici. Cela inclut des choses comme un <a href="/en-US/docs/Learn/Common_questions/Available_text_editors">éditeur de texte</a> ou un IDE pour éditer votre code, et un outil de gestion de contrôle de version comme Git pour gérer en toute prudence les différentes versions de votre code. Nous supposerons ici que vous avez déjà un éditeur de texte installé.</p>
+
+<h3 id="Quelles_sont_les_options_dinstallation_de_Django">Quelles sont les options d'installation de Django ?</h3>
+
+<p>Django est extrêmement flexible sur sa manière d'être installé et configuré. Django peut-être :</p>
+
+<ul>
+ <li>Installé sur divers systèmes d'exploitation.</li>
+ <li>Installé depuis la source, avec l'Index des Packages Python (PyPI) et bien souvent depuis l'application de gestion de packages de l'ordinateur hôte.</li>
+ <li>Configuré pour communiquer avec diverses bases de données, qui peuvent aussi avoir besoin d'être configurées et installées séparément.</li>
+ <li>Lancé depuis l'environnement principal de Python ou depuis des environnements virtuels Python séparés.</li>
+</ul>
+
+<p>Chacune de ces options requiert une configuration et une installation légèrement différente. Les sous-sections ci-dessous vous expliquent différents choix. Dans le reste de l'article, nous vous montrerons comment installer Django sur un nombre restreint de systèmes d'exploitation, et nous supposerons que cette installation aura été suivie pour tout le reste du module.</p>
+
+<div class="note">
+<p><strong>Note</strong>: D'autres options d'installation possibles sont traitées dans la documentation officielle de Django. Les liens vers la <a href="https://wiki.developer.mozilla.org/en-US/docs/Learn/Server-side/Django/development_environment$translate?tolocale=fr#">documentation appropriée peuvent-être trouvés ci-dessous</a>.</p>
+</div>
+
+<h4 id="Quels_systèmes_dexploitation_sont_supportés">Quels systèmes d'exploitation sont supportés ?</h4>
+
+<p>Les applications web Django peuvent tourner sous presque n'importe quelle machine pouvant faire fonctionner le langage de programmation Python 3 : Windows, macOS, Linux/Unix, Solaris, pour ne nommer que ceux-là. Quasiment n'importe quel ordinateur devrait avoir les performances nécessaires pour faire fonctionner Django lors de la phase de développement.</p>
+
+<p>Dans cet article, nous vous donnons les instructions pour Windows, macOS et Linux/Unix.</p>
+
+<h4 id="Quelle_version_de_Python_doit-être_utilisée">Quelle version de Python doit-être utilisée ?</h4>
+
+<p>Nous vous recommandons d'utiliser la version la plus récente disponible — au moment de l'écriture de cet article, nous en sommes à la version Python 3.7.2.</p>
+
+<p>Si besoin, les versions de Python 3.5 et ultérieures peuvent être utilisées (le support pour Python 3.5 sera abandonné lors de la sortie des prochaines versions).</p>
+
+<div class="note">
+<p><strong>Note</strong>: Python 2.7 ne peut pas être utilisé avec Django 2.1 (la série Django 1.11.x est la dernière à supporter Python 2.7).</p>
+</div>
+
+<h4 id="Où_peut-on_télécharger_Django">Où peut-on télécharger Django ?</h4>
+
+<p>Il y a trois façons de télécharger Django :</p>
+
+<ul>
+ <li>Le Repository de Packages Python (PyPI), en utilisant l'outil pip. C'est la meilleure façon d'obtenir la dernière version stable de Django.</li>
+ <li>En utilisant la version du gestionnaire de packages de votre ordinateur. Les distributions de Django empaquetées avec les systèmes d'exploitation offrent un mécanisme d'installation plus familier. Veuillez toutefois noter que la version du package peut être datée, et ne pourra alors être installée que dans l'environnement système de Python (ce que vous pourriez ne pas souhaiter).</li>
+ <li>Installation depuis la source : Vous pouvez télécharger et installer la toute dernière version de Django depuis la source. Ce n'est pas recommandé pour les débutants, mais c'est une étape nécessaire si vous souhaitez contribuer à Django lui-même.</li>
+</ul>
+
+<p>Cet article explique comment installer Django depuis PyPI afin d'obtenir la version stable la plus récente.</p>
+
+<h4 id="Quelle_base_de_données">Quelle base de données ?</h4>
+
+<p>Django supporte quatre bases de données principales (PostgreSQL, MySQL, Oracle et SQLite), et des librairies fournies par la communauté offrent différents niveaux de support pour d'autre bases de données SQL et NoSQL populaires. Nous vous recommandons de choisir la même base de données pour la production et le développement (bien que Django puisse abstraire plusieurs différences entre les bases de données en utilisant son Mapper Relationnel-Objet (ORM), il reste tout de même certains <a href="https://docs.djangoproject.com/en/2.1/ref/databases/">problèmes potentiels</a> qu'il vaut mieux éviter).</p>
+
+<p>Dans cet article (et quasiment tout le module), nous utiliserons la base <em>SQLite</em>, qui sauvegarde ses données dans des fichiers. SQLite a été conçu pour être utilisé comme une base de données légère, mais elle ne peut pas supporter un haut niveau de compétition. Elle est cependant un excellent choix pour des applications qui sont prioritairement en lecture seule.</p>
+
+<div class="note">
+<p><strong>Note</strong>: Django est configuré pour utiliser SQLite par défaut lorsque vous démarrez le projet de votre site web en utilisant les outils standards (<em>django-admin</em>). C'est un très bon choix lorsque vous débutez car elle ne requiert aucune configuration ou installation particulière.</p>
+</div>
+
+<h4 id="Installation_globale_ou_dans_un_environnement_virtuel_Python">Installation globale ou dans un environnement virtuel Python ?</h4>
+
+<p>Lorsque vous installez Python3, vous obtenez un environnement global unique partagé par tout le code Python3. Bien que vous puissiez installer n'importe quel package Python souhaité dans cet environnement, vous ne pouvez disposer que d'une seule version d'un package donné à la fois.</p>
+
+<div class="note">
+<p><strong>Note</strong>: Les applications installées dans l'environnement global peuvent potentiellement entrer en conflit avec les autres (i.e. si elles dépendent de versions différentes d'un même package).</p>
+</div>
+
+<p>Si vous installez Django dans l'environnement par défaut/global, vous ne pourrez alors cibler qu'une seule version de Django sur votre machine. Cela peut devenir un problème si vous souhaitez créer de nouveaux sites web (utilisant la dernière version de Django) tout en maintenant d'autres sites web dépendant de versions antérieures.</p>
+
+<p>Ainsi, un développeur Python/Django confirmé lance généralement ses applications Python dans des <em>environnements virtuels Python</em> indépendants. Cela permet d'avoir plusieurs environnements Django sur un seul et même ordinateur. L'équipe de développement de Django elle-même recommande d'utiliser des environnements virtuels Python.</p>
+
+<p>Ce module suppose que vous avez installé Django dans un environnement virtuel, et nous vous montrons comment le faire ci-dessous.</p>
+
+<h2 id="Installer_Python_3">Installer Python 3</h2>
+
+<p>Si vous souhaitez utiliser Django, vous devrez installer Python sur votre système d'exploitation. Si vous utilisez <em>Python 3</em>, vous aurez alors aussi besoin de l'outil <a href="https://pypi.python.org/pypi">Python Package Index</a> — <em>pip3</em> — qui est utilisé pour gérer (installer, mettre à jour, supprimer) les packages/librairies Python qui seront utilisés par Django et vos autres applications Python.</p>
+
+<p>Cette section décrit brièvement comment vérifier quelle version de Python sont disponibles, et comment installer de nouvelles versions si nécessaire, sur Ubuntu Linux 18.04, macOS et Windows 10.</p>
+
+<div class="note">
+<p><strong>Note</strong>: En fonction de votre plateforme, vous aurez probablement aussi besoin d'installer Python/pip depuis le gestionnaire de packages de votre système d'exploitation, ou via d'autre moyens. Pour la plupart des plateformes, vous pouvez télécharger les fichiers d'installation requis depuis <a href="https://www.python.org/downloads/">https://www.python.org/downloads/</a> et les installer en utilisant la méthode appropriée à votre plateforme.</p>
+</div>
+
+<h3 id="Ubuntu_18.04">Ubuntu 18.04</h3>
+
+<p>Ubuntu Linux 18.04 LTS inclut par défaut Python 3.6.6. Vous pouvez vous en assurer en exécutant les commandes suivantes depuis le terminal bash :</p>
+
+<pre class="brush: bash"><span style="line-height: 1.5;">python3 -V
+ Python 3.6.6</span></pre>
+
+<p>Toutefois, l'outil d'Index des Packages Python dont vous aurez besoin pour installer des packages avec Python 3 (y compris Django) n'est <strong>pas </strong>disponible par défaut. Vous pouvez installer pip3 avec le terminal bash avec :</p>
+
+<pre class="brush: bash">sudo apt install python3-pip
+</pre>
+
+<h3 id="macOS">macOS</h3>
+
+<p>macOS "El Capitan"et les versions plus récentes n'incluent pas Python 3. Vous pouvez vous en assurer en exécutant les commandes suivantes dans votre terminal bash :</p>
+
+<pre class="brush: bash"><span style="line-height: 1.5;">python3 -V
+ </span>-bash: python3: command not found</pre>
+
+<p>Vous pouvez facilement installer Python 3 (ainsi que l'outil <em>pip3</em>) sur <a href="https://www.python.org/">python.org</a>:</p>
+
+<ol>
+ <li>Téléchargez l'installeur requis :
+ <ol>
+ <li>Allez sur <a href="https://www.python.org/downloads/">https://www.python.org/downloads/</a></li>
+ <li>Sélectionnez le bouton <strong>Download Python 3.7.2</strong> (le numéro de version mineure peut varier).</li>
+ </ol>
+ </li>
+ <li>Localisez le fichier en utilisant le <em>Finder</em>, puis double-cliquez le fichier package. Suivez les consignes d'installation.</li>
+</ol>
+
+<p>Vous pouvez désormais confirmer la bonne installation en vérifiant votre version de Python 3 comme indiqué ci-dessous :</p>
+
+<pre class="brush: bash"><span style="line-height: 1.5;">python3 -V
+ Python 3.7.2</span>
+</pre>
+
+<p>Vous pouvez aussi vérifier que pip3 est correctement installé en listant les packages disponibles :</p>
+
+<pre class="brush: bash">pip3 list</pre>
+
+<h3 id="Windows_10">Windows 10</h3>
+
+<p>Windows n'inclut pas Python par défaut, mais vous pouvez facilement l'installer (ainsi que l'outil <em>pip3</em>) sur<a href="https://www.python.org/"> python.org</a>:</p>
+
+<ol>
+ <li>Téléchargez l'installeur requis :
+ <ol>
+ <li>Allez sur <a href="https://www.python.org/downloads/">https://www.python.org/downloads/</a></li>
+ <li>Sélectionnez le bouton <strong>Download Python 3.7.2</strong> (le numéro de version mineure peut varier).</li>
+ </ol>
+ </li>
+ <li>Installez Python en double-cliquant sur le fichier télécharger puis en suivant les consignes d'installation</li>
+ <li>Assurez-vous d'avoir coché la case intitulée "Ajouter Python au PATH".</li>
+</ol>
+
+<p>Vous pouvez ensuite vérifier que Python s'est correctement installé en tapant le texte suivant dans votre invite de commande :</p>
+
+<pre class="brush: bash"><span style="line-height: 1.5;">py -3 -V
+ Python 3.7.2</span>
+</pre>
+
+<p>L'installeur Windows inclut <em>pip3</em> (le gestionnaire de packages Python) par défaut. Vous pouvez lister les packages installés de la manière suivante :</p>
+
+<pre class="brush: bash"><span style="line-height: 1.5;">pip3 list</span>
+</pre>
+
+<div class="note">
+<p><strong>Note</strong>: L'installeur devrait configurer tout ce dont vous avez besoin pour que les commandes ci-dessus fonctionnent. Toutefois, si vous obtenez un message vous indiquant que Python ne peut pas être trouvé (Python cannot be found), il est possible que vous ayez oublié de l'ajouter à votre PATH système. Vous pouvez faire cela en réexécutant l'installeur, sélectionnez "Modifier", puis cochez la case intitulée "Ajouter Python aux variables d'environnement" sur le deuxième page.</p>
+</div>
+
+<h2 id="Utiliser_Django_dans_un_environnement_virtuel_Python">Utiliser Django dans un environnement virtuel Python</h2>
+
+<p>Les librairies que nous utiliserons pour créer nos environnements virtuels seront <a href="https://virtualenvwrapper.readthedocs.io/en/latest/index.html">virtualenvwrapper</a> (Linux et macOS) et <a href="https://pypi.python.org/pypi/virtualenvwrapper-win">virtualenvwrapper-win</a> (Windows), , qui à leur tour utilisent l'outil <a href="https://developer.mozilla.org/en-US/docs/Python/Virtualenv">virtualenv</a>. Les outils d'habillage permettent de créer une interface consistante pour gérer les interfaces sur toutes les plateformes.</p>
+
+<h3 id="Installer_lutilitaire_denvironnement_virtuel">Installer l'utilitaire d'environnement virtuel</h3>
+
+<h4 id="Mise_en_place_de_lenvironnement_virtuel_sur_Ubuntu">Mise en place de l'environnement virtuel sur Ubuntu</h4>
+
+<p>Après avoir installé Python et pip vous pouvez installer <em>virtualenvwrapper</em> (qui inclut <em>virtualenv</em>). Le guide d'installation officiel peut être trouvé <a href="http://virtualenvwrapper.readthedocs.io/en/latest/install.html">ici</a>, ou bien vous pouvez suivre les instructions ci-dessous.</p>
+
+<p>Installer l'outil en utilisant <em>pip3</em>:</p>
+
+<pre class="brush: bash"><code>sudo pip3 install virtualenvwrapper</code></pre>
+
+<p>Ajoutez ensuite les lignes suivantes à la fin de votre fichier de configuration shell (le fichier caché <strong>.bashrc</strong> dans votre répertoire home). Elles indiquent les endroits où vos environnements virtuels seront installés, l'emplacement de vos projets de développement, et l'emplacement du script installé avec ce package :</p>
+
+<pre class="brush: bash"><code>export WORKON_HOME=$HOME/.virtualenvs
+export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3
+export VIRTUALENVWRAPPER_VIRTUALENV_ARGS=' -p /usr/bin/python3 '
+export PROJECT_HOME=$HOME/Devel
+source /usr/local/bin/virtualenvwrapper.sh</code>
+</pre>
+
+<div class="note">
+<p><strong>Note</strong>: Les variables <code>VIRTUALENVWRAPPER_PYTHON</code> et <code>VIRTUALENVWRAPPER_VIRTUALENV_ARGS </code>pointent vers l'emplacement d'installation par défaut de Python3, et <code>source /usr/local/bin/virtualenvwrapper.sh</code> pointe vers l'emplacement par défaut du script <code>virtualenvwrapper.sh</code>. Si le <em>virtualenv</em> ne fonctionne pas quand vous le testez, vérifiez que Python et le script sont bien aux emplacements attendus (puis modifiez le fichier de configuration en conséquence).<br>
+ <br>
+ Vous pourrez trouver les bons emplacements de votre système en utilisant les commandes <code>which virtualenvwrapper.sh</code> et <code>which python3</code>.</p>
+</div>
+
+<p>Puis relancez le fichier de configuration en exécutant la commande suivante dans votre terminal :</p>
+
+<pre class="brush: bash"><code>source ~/.bashrc</code></pre>
+
+<p>Vous devriez alors voir apparaître plusieurs lignes de script semblables à celles ci-dessous :</p>
+
+<pre class="brush: bash"><code>virtualenvwrapper.user_scripts creating /home/ubuntu/.virtualenvs/premkproject
+virtualenvwrapper.user_scripts creating /home/ubuntu/.virtualenvs/postmkproject
+...
+virtualenvwrapper.user_scripts creating /home/ubuntu/.virtualenvs/preactivate
+virtualenvwrapper.user_scripts creating /home/ubuntu/.virtualenvs/postactivate
+virtualenvwrapper.user_scripts creating /home/ubuntu/.virtualenvs/get_env_details</code>
+</pre>
+
+<p>Vous pouvez maintenant créer un nouvel environnement virtuel avec la commande <code>mkvirtualenv</code>.</p>
+
+<h4 id="Mise_en_place_de_lenvironnement_virtuel_sur_macOS">Mise en place de l'environnement virtuel sur macOS</h4>
+
+<p>L'installation de <em>virtualenvwrapper</em> on sur macOS est quasiment identique à celle sur Ubuntu (une fois de plus, vous pouvez suivre les instructions du <a href="http://virtualenvwrapper.readthedocs.io/en/latest/install.html">guide officiel d'installation</a> ou suivre les indications ci-dessous).</p>
+
+<p>Installez <em>virtualenvwrapper</em> (ainsi que <em>virtualenv</em>) en utilisant <em>pip</em> comme indiqué ci-dessous.</p>
+
+<pre class="brush: bash"><code>sudo pip3 install virtualenvwrapper</code></pre>
+
+<p>Puis ajoutez les lignes suivantes à la fin de votre fichier de configuration shell.</p>
+
+<pre class="brush: bash"><code>export WORKON_HOME=$HOME/.virtualenvs
+export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3
+export PROJECT_HOME=$HOME/Devel
+source /usr/local/bin/virtualenvwrapper.sh</code></pre>
+
+<div class="note">
+<p><strong>Note</strong>: La variable <code>VIRTUALENVWRAPPER_PYTHON</code> pointe vers l'emplacement d'installation par défaut de Python3, et <code>source /usr/local/bin/virtualenvwrapper.sh</code> pointe vers l'emplacement par défaut du script <code>virtualenvwrapper.sh</code>. Si le <em>virtualenv</em> ne fonctionne pas quand vous le testez, vérifiez que Python et le script sont bien aux emplacements attendus (puis modifiez le fichier de configuration en conséquence).</p>
+
+<p>Par exemple, une installation test sur macOS a résulté en l'ajout des lignes suivantes dans le fichier startup :</p>
+
+<pre class="brush: bash">export WORKON_HOME=$HOME/.virtualenvs
+export VIRTUALENVWRAPPER_PYTHON=/Library/Frameworks/Python.framework/Versions/3.7/bin/python3
+export PROJECT_HOME=$HOME/Devel
+source /Library/Frameworks/Python.framework/Versions/3.7/bin/virtualenvwrapper.sh</pre>
+
+<p>Vous pourrez trouver les bons emplacements de votre système en utilisant les commandes <code>which virtualenvwrapper.sh</code> et <code>which python3</code>.</p>
+</div>
+
+<p>Ce sont les mêmes lignes que pour Ubuntu, mais le nom du fichier de configuration caché du répertoire home est différent : <strong>.bash_profile</strong> dans votre répertoire home.</p>
+
+<div class="note">
+<p><strong>Note</strong>: Si vous n'arrivez pas à trouver le fichier <strong>.bash_profile</strong> depuis le finder, vous pouvez aussi l'ouvrir depuis le terminal en utilisant nano.</p>
+
+<p>La commande sera la suivante :</p>
+
+<pre><code>cd ~ # Naviguer vers le répertoire home
+ls -la # Listez le contenu du répertoire. Vous devriez voir .bash_profile.
+nano .bash_profile # Ouvrez le fichier avec l'éditeur de texte nano, depuis le terminal.
+# Allez à la fin du fichier, puis copiez-collez les lignes ci-dessus.
+# Utilisez Ctrl+X pour quitter nano, sélectionnez Y pour sauvegarder le fichier.</code>
+</pre>
+</div>
+
+<p>Puis relancez le fichier de configuration en appelant la ligne suivante depuis le terminal :</p>
+
+<pre class="brush: bash"><code>source ~/.bash_profile</code></pre>
+
+<p>Vous devriez alors voir apparaître plusieurs lignes de script (les mêmes scripts que ceux présents dans l'installation Ubuntu). Vous devriez maintenant pouvoir créer un nouvel environnement virtuel avec la commande <code>mkvirtualenv</code>.</p>
+
+<h4 id="Mise_en_place_de_lenvironnement_virtuel_sur_Windows_10">Mise en place de l'environnement virtuel sur Windows 10</h4>
+
+<p>Installer <a href="https://pypi.python.org/pypi/virtualenvwrapper-win">virtualenvwrapper-win</a> est encore plus simple qu'installer <em>virtualenvwrapper</em> , parce que vous n'avez pas besoin de configurer là où l'outil enregistre les informations de l'environnement virtuel (il y a des valeurs par défaut). Tout ce que vous avez besoin de faire est de lancer la commande suivante depuis l'invite de commande :</p>
+
+<pre><code>pip3 install virtualenvwrapper-win</code></pre>
+
+<p>Vous pouvez désormais créer un nouvel environnement virtuel avec la commande <code>mkvirtualenv</code></p>
+
+<h3 id="Créer_un_environnement_virtuel">Créer un environnement virtuel</h3>
+
+<p>Maintenant que vous avez installé <em>virtualenvwrapper</em> ou <em>virtualenvwrapper-win</em> , travailler avec des environnements virtuels sera une tâche très similaire entre chaque plateforme.</p>
+
+<p>Vous pouvez désormais créer un nouvel environnement virtuel avec la commande <code>mkvirtualenv</code>. Lors de son exécution, vous pourrez voir l'environnement être configuré (ce que vous verrez changera légèrement en fonction de votre plateforme). Lorsque l'exécution de la commande sera terminée, votre environnement virtuel sera actif — vous pouvez voir au début de la ligne de commande le nom de votre environnement entre parenthèses (nous vous montrons le résultat pour Ubuntu ci-dessous, mais la dernière ligne est similaire sur Windows/macOS).</p>
+
+<pre><code>$ mkvirtualenv my_django_environment
+
+Running virtualenv with interpreter /usr/bin/python3
+...
+virtualenvwrapper.user_scripts creating /home/ubuntu/.virtualenvs/t_env7/bin/get_env_details
+(my_django_environment) ubuntu@ubuntu:~$</code>
+</pre>
+
+<p>Maintenant que vous êtes dans votre environnement virtuel vous pouvez installer Django et commencer à développer.</p>
+
+<div class="note">
+<p><strong>Note</strong>: A partir de ce point dans l'article (et donc dans le module), vous pourrez considérer que toutes les commandes seront exécutées dans un environnement virtuel Python comme celui que nous avons mis en place plus haut.</p>
+</div>
+
+<h3 id="Utiliser_un_environnement_virtuel">Utiliser un environnement virtuel</h3>
+
+<p>Il y a quelques commandes que vous devriez connaître (il y en a davantage dans la documentation de l'outil, mais celles-ci sont celles que vous utiliserez le plus souvent) :</p>
+
+<ul>
+ <li><code>deactivate</code> — Permet de sortir de l'environnement virtuel Python actuel</li>
+ <li><code>workon</code> — Lister tous les environnements virtuels disponibles</li>
+ <li><code>workon name_of_environment</code> — Activer l'environnement virtuel spécifié</li>
+ <li><code>rmvirtualenv name_of_environment</code> — Supprimer l'environnement virtuel spécifié</li>
+</ul>
+
+<h2 id="Installer_Django">Installer Django</h2>
+
+<p>Une fois que vous avez créé votre environnement virtuel, et que vous avez utilisé <code>workon</code> pour y entrer, vous pouvez utiliser <em>pip3 </em>pour installer Django. </p>
+
+<pre class="brush: bash">pip3 install django
+</pre>
+
+<p>Vous pouvez tester l'installation de Django en exécutant la commande suivante (celle-ci ne fait que tester le fait que Python puisse trouver le module Django) :</p>
+
+<pre class="brush: bash"># Linux/macOS
+python3 -m django --version
+ 2.1.5
+
+# Windows
+py -3 -m django --version
+ 2.1.5
+</pre>
+
+<div class="note">
+<p><strong>Note</strong>: Si la commande Windows ci-dessus n'indique aucun module Django présent, essayez :</p>
+
+<pre class="brush: bash">py -m django --version</pre>
+
+<p>Dans Windows, les scripts <em>Python 3</em> sont exécutés en préfixant la commande avec <code>py -3</code>, bien que ceci puisse varier suivant votre installation. Essayer en enlevant le modificateur <code>-3 </code>si vous rencontrez un problème avec la commande. Dans Linux/macOS, la commande est <code>python3.</code></p>
+</div>
+
+<div class="warning">
+<p><strong>Important</strong>: Le reste de ce <strong>module </strong>utilise les commandes <em>Linux</em> pour invoquer Python 3 (<code>python3</code>) . . Si vous travaillez sous <em>Windows </em>, remplacez simplement ce préfixe avec : <code>py -3</code></p>
+</div>
+
+<h2 id="Tester_votre_installation">Tester votre installation</h2>
+
+<p>Les tests ci-dessus fonctionnent, mais ne font rien de très divertissant. Un test plus intéressant consiste à créer un projet squelette et de voir si il fonctionne. Pour ce faire, naviguez tout d'abord dans votre invite/terminal de commande à l'endroit où vous désirez stocker vos applications Django. Créez un dossier pour votre site test et placez-vous dedans.</p>
+
+<pre class="brush: bash">mkdir django_test
+cd django_test
+</pre>
+
+<p>Vous pouvez ensuite créer un nouveau site squelette intitulé "<em>mytestsite</em>" utilisant l'outil <strong>django-admin</strong> omme montré. Après avoir créé le site, vous pouvez naviguer dans le dossier où vous trouverez le script principal pour gérer vos projets, intitulé <strong>manage.py</strong>.</p>
+
+<pre class="brush: bash">django-admin startproject mytestsite
+cd mytestsite</pre>
+
+<p>Nous pouvons lancer le <em>serveur web de développement</em> depuis ce dossier en utilisant <strong>manage.py</strong> et la commande <code>runserver</code> command, comme indiqué ci-dessous.</p>
+
+<pre class="brush: bash">$ python3 manage.py runserver
+Performing system checks...
+
+System check identified no issues (0 silenced).
+
+You have 15 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
+Run 'python manage.py migrate' to apply them.
+
+December 16, 2018 - 07:06:30
+Django version 2.1.5, using settings 'mytestsite.settings'
+Starting development server at http://127.0.0.1:8000/
+Quit the server with CONTROL-C.
+</pre>
+
+<div class="note">
+<p><strong>Note </strong>: La commande ci-dessus montre le résultat de l'exécution sur Linux/macOS. Vous pouvez ignorer les warnings à propos des "15 unapplied migration(s)" à partir de là !</p>
+</div>
+
+<p>Maintenant que votre serveur est lancé, vous pouvez voir le site en naviguant vers l'URL suivante depuis votre navigateur local : <code>http://127.0.0.1:8000/</code>. Vous devriez voir un site ressemblant à celui-ci :<br>
+ <img alt="Django Skeleton App Homepage - Django 2.0" src="https://mdn.mozillademos.org/files/16288/Django_Skeleton_Website_Homepage_2_1.png" style="height: 714px; width: 806px;"></p>
+
+<ul>
+</ul>
+
+<h2 id="Résumé">Résumé</h2>
+
+<p>Vous avez maintenant un environnement de développement Django fonctionnel et opérationnel sur votre ordinateur.</p>
+
+<p>Dans la section test vous avez aussi vu comment créer un nouveau site web Django en utilisant <code>django-admin startproject</code>, et comment aller dessus depuis votre navigateur en utilisant le serveur de développement web (<code>python3 manage.py runserver</code>). Dans le prochain article nous détaillerons ce processus, et créant un application web simple mais complète.</p>
+
+<h2 id="See_also">See also</h2>
+
+<ul>
+ <li><a href="https://docs.djangoproject.com/en/2.1/intro/install/">Quick Install Guide</a> (Django docs)</li>
+ <li><a href="https://docs.djangoproject.com/en/2.1/topics/install/">How to install Django — Complete guide</a> (Django docs) - includes information on how to remove Django</li>
+ <li><a href="https://docs.djangoproject.com/en/2.1/howto/windows/">How to install Django on Windows</a> (Django docs)</li>
+</ul>
+
+<p>{{PreviousMenuNext("Learn/Server-side/Django/Introduction", "Learn/Server-side/Django/Tutorial_local_library_website", "Learn/Server-side/Django")}}</p>
+
+<h2 id="In_this_module">In this module</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Introduction">Django introduction</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/development_environment">Setting up a Django development environment</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">Django Tutorial: The Local Library website</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/skeleton_website">Django Tutorial Part 2: Creating a skeleton website</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Models">Django Tutorial Part 3: Using models</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Admin_site">Django Tutorial Part 4: Django admin site</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Home_page">Django Tutorial Part 5: Creating our home page</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Generic_views">Django Tutorial Part 6: Generic list and detail views</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Sessions">Django Tutorial Part 7: Sessions framework</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Authentication">Django Tutorial Part 8: User authentication and permissions</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Forms">Django Tutorial Part 9: Working with forms</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Testing">Django Tutorial Part 10: Testing a Django web application</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Deployment">Django Tutorial Part 11: Deploying Django to production</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/web_application_security">Django web application security</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/django_assessment_blog">DIY Django mini blog</a></li>
+</ul>
diff --git a/files/fr/learn/server-side/django/forms/index.html b/files/fr/learn/server-side/django/forms/index.html
new file mode 100644
index 0000000000..0c877c8946
--- /dev/null
+++ b/files/fr/learn/server-side/django/forms/index.html
@@ -0,0 +1,651 @@
+---
+title: 'Django Tutorial Part 9: Working with forms'
+slug: Learn/Server-side/Django/Forms
+tags:
+ - Beginner
+ - CodingScripting
+ - DjangoForms
+ - Forms
+ - HTML forms
+ - Learn
+ - Tutorial
+ - django
+ - server side
+translation_of: Learn/Server-side/Django/Forms
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/Server-side/Django/authentication_and_sessions", "Learn/Server-side/Django/Testing", "Learn/Server-side/Django")}}</div>
+
+<p class="summary">Dans cette formation nous allons vous montrer comment travailler avec les formulaires HTML sous Django afin de créer, modifier et supprimer des instances de modèle. Pour illustrer le raisonnement, nous allons étendre le site web <a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">LocalLibrary</a> pour permettre aux bibliothécaires d'utiliser nos formulaires (plutôt que l'application d'administration par défaut) pour prolonger la durée de prêt des livres, et également pour ajouter, mettre à jour et supprimer des auteurs. </p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Prérequis:</th>
+ <td>Avoir terminé les formations précédentes, y compris <a href="/en-US/docs/Learn/Server-side/Django/authentication_and_sessions">Django Tutorial Part 8: User authentication and permissions</a>.</td>
+ </tr>
+ <tr>
+ <th scope="row">Objectifs:</th>
+ <td>Comprendre comment écrire des formulaires pour récupérer des informations de la part des utilisateurs et mettre à jour la base de données. Comprendre commment il est possible de simplifier grandement la création de formulaires si l 'on travaille avec un seul modèle en utilisant les vues génériques de formulaires d'éditions s'appuyant sur des classes.   </td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Vue_densemble">Vue d'ensemble</h2>
+
+<p>Un <a href="/en-US/docs/Web/Guide/HTML/Forms">formulaire HTML</a> regroupe au moins un champ remplissable et des composants élémentaires d'interface web.  Il peut être utilisé pour réunir des saisies de la part des utilisateurs avant envoi vers un serveur. Les formulaires sont souples: ils s'adaptent à plusieurs modes de saisie. En effet, Il existe des composants élementaires d'interfaces graphique pour des  modes de saisie non contrainte avec une zone de saisie de texte, ou resteinte au type date avec un date picker,  la saisie d'un variable optionnelle via une boîte à cocher,  d'un choix à faire parmi plusieurs valeurs possibles avec les boutons radio etc... . Les formulaires permettent de partager des informations avec le serveur de manière relativement sécurisée  car ils permettent d'envoyer des requêtes de  type <code>POST</code> protégeant de la falsification des requêtes inter-site.</p>
+
+<p>Bien que nous n'ayons pas encore créé de formulaire au cours de cette formation, nous en avons déjà rencontré sur l'interface d'administration Django Admin — par exemple la capture d'écran ci-dessous montre un formulaire d'édition  de l'un de nos modèle de <a href="/en-US/docs/Learn/Server-side/Django/Models">Book</a>  (livre), comprenant des composants élémentaires d'interface graphique de chois de valeur parmi une liste proposée,  et des zones des saisie de texte.</p>
+
+<p><img alt="Admin Site - Book Add" src="https://mdn.mozillademos.org/files/13979/admin_book_add.png" style="border-style: solid; border-width: 1px; display: block; margin: 0px auto;"></p>
+
+<p>Travailler avec des formulaires peut s'avérer compliqué ! Les développeurs doivent non seulement écrire le code  HTML pour le formulaire, mais aussi vérifier et corriger sur le serveur les données saisies (et éventuellement aussi dans le navigateur), renvoyer le formulaire avec des messages d'erreur pour informer les usagers de tout champ invalide, prendre en charge les données quand elles passent l'étape de vérification, et finalement renvoyer une information à l'utilisateur d'une manière ou d'une autre pour indiquer ce succès. Les formulaires sous Django enlèvent beaucoup de travail à chacune de ces étapes, grâce à un cadriciel qui permet de déclarer des formulaires et leurs champs à travers un langage de programmation, puis d'utiliser ces objets non seulement pour générer le code HTML, mais aussi une grosse partie de la vérification des données et du retour d'information à l'utilisateur.</p>
+
+<p>Dans cette formation, nous allons vous montrer quelque-unes des manièrs de créer et de travailler avec les formulaires, et en particulier, comment les vues sur les formulaires génériques d'édition peuvent réduire significativement la quantité de travail à fournir pour créer les formulaires de manipulation de vos modèles. En chemin nous allons étendre notre application <em>LocalLibrary</em> en ajoutant un formulaire permettant aux bibliothécaires de prolonger le prêt de libres, et nous allons créer des pages pour créer, modifier et supprimer des livres et des auteurs (reproduisant une version basique du formulaire ci-dessus pour éditer des livres. )</p>
+
+<h2 id="Formulaires_HTML">Formulaires HTML</h2>
+
+<p>D'abord, un premier aperçu des formulaires HTML (<a href="/en-US/docs/Learn/HTML/Forms" style='background-color: rgb(255, 255, 255); font-family: "Open Sans", arial, x-locale-body, sans-serif;'>HTML Forms</a>). <span style='background-color: #ffffff; color: #333333; font-family: "Open Sans",arial,x-locale-body,sans-serif;'>Soit un formulaire HTML simple, composé d'un unique champ de saisie texte , présent pour y entrer le nom d'une "équipe" quelconque, et son sa description dans l'étiquette associée :</span></p>
+
+<p><img alt="Simple name field example in HTML form" src="https://mdn.mozillademos.org/files/14117/form_example_name_field.png" style="border-style: solid; border-width: 1px; display: block; height: 44px; margin: 0px auto; width: 399px;"></p>
+
+<p>Le formulaire est défini en HTML comme une collection d'éléments enfermés entre deux balises &lt;form&gt; ... &lt;/form&gt; contenant au moins une balise &lt;input&gt; dont la valeur d'attribut 'type' doit valoir "submit":</p>
+
+<pre class="brush: html">&lt;form action="/team_name_url/" method="post"&gt;
+    &lt;label for="team_name"&gt;Enter name: &lt;/label&gt;
+    &lt;input id="team_name" type="text" name="name_field" value="Default name for team."&gt;
+    &lt;input type="submit" value="OK"&gt;
+&lt;/form&gt;
+</pre>
+
+<p>Bien qu'ici nous n'ayons qu'un champ de saisie texte destiné à recevoir le nom d'équipe, une formulaire <em>pourrait</em> avoir un nombre quelconque d'autres champs de saisie et leurs étiquettes de description associées. La valeur de l'attribut 'type' définit la sorte de composant élementaire d'interface graphique  affichée. Les attributs 'id' et 'name' permettent d'identifier le champ en JavaScript/CSS/HTML alors que l'attribut 'value' définit la valeur initiale du champ lorsqu'il est affiché pour la première fois. La description associée  est déclarée par la balise &lt;label&gt; (voir "Enter Name" au dessus) , avec un attribut 'for' devant contenir la valeur de l'attribut 'id' du champ imput à laquelle on souhaite l'associer.  </p>
+
+<p>La balise <code>&lt;input&gt;</code> dont l'attribut <code>'type'</code> vaut <code>submit</code> sera affichée (par défaut) comme un bouton  qui peut être cliqué par l'utilisateur pour envoyer vers le serveur les données figurant dans tous les autres éléments de formulaire &lt;input&gt; (dans le cas présent, la valeur actuelle de <code>'team name'</code>. Les attributs de<font face="consolas, Liberation Mono, courier, monospace"> formulaire déterminent d'une part la méthode HTTP (attribut method) utilisée pour envoyer les donnnées et d'autre part la destination des données sur le serveur (attribut <code>action </code>):</font></p>
+
+<ul>
+ <li><code>action</code> :  Il s'agit de la destination (ressource ou URL) où sont envoyées les données lorsque le formulaire est soumis.  Si la valeur de cet attribut n'est pas initialisée (ou la chaine vide est affectée à cet attribut),  alors le formulaire sera renvoyé à l' URL de la page courante.</li>
+ <li><code>method</code> : La méthode HTTP utilisée pour envoyer les données: <em>post</em> ou <em>get</em>.
+ <ul>
+ <li>La méthode <code>POST</code> devrait toujours être utilisée si l'envoi de la donnée va provoquer un changement dan la base de données du serveur, car il peut être rendu plus résistant aux attaques par falsification de requête inter-site (CSRF). </li>
+ <li>La méthode GET ne devrait être utilisée que pour les formulaires ne changeant pas les données utilisateur (p.ex. un formulaire de recherche) . Elle est recommandée lorsque vous souhaitez pouvoir partager l'URL ou la conserver dans vos favoris.  T</li>
+ </ul>
+ </li>
+</ul>
+
+<p>Le rôle du serveur est d'abord de fournir le formulaire sous sa forme initiale  — c'est à dire une série de champs soit vides, soit préremplis avec des valeurs initiales. Après l'impulsion de l'utilisateur sur le bouton submit, le seurveur va recevoir les données du formulaire avec les valeurs saisies dans le navigateur, et va devoir vérifier ces données. Si le formulaire contient des données invalides, le seurveur devrait afficher le formulaire de nouveau, cette fois ci avec les données utilisateur entrées dans les champs "valides" et des messages pour décrire le problème pour les champs invalides. Dès que le serveur reçoit une requête dont tous les données de champs sont valides, il peut effectuer les actions appropriées ( c'est à dire sauver les données, renvoyer le résultat d'une recherche, téléverser un fichier, etc...)  et ensuite notifier l'utilisateur .  </p>
+
+<p>Comme vous pouvez l'imaginer, créer le code HTML, vérifier les données envoyées, réafficher les données entrées avec l'adjonction de rapports sur les erreurs, effectuer les opérations désirées sur les données valides peut représenter pas mal d'efforts de réflexion et d'essais erreur. Django rend cela bien plus facile, en enlevant la nécessité de concevoir une partie de ce code pénible et répétitif!</p>
+
+<h2 id="Les_étapes_de_gestion_dun_formulaire_avec_Django">Les étapes de gestion d'un formulaire avec Django</h2>
+
+<p>Django gère un formulaire en utilisant les mêmes techniques qu'évoquées lors des formations précédentes (pour afficher des informations à propos de nos modèles): La vue reçoit une requête, exécute toute acion nécessaire, incluant la lecture de données depuis les modèles, puis génère une page HTML (à partir d'un squelette à qui nous transmettons un <em>contexte </em>contenant les données à afficher<em> </em>). Ce qui rend les choses plus compliquées, c'est que le serveur a aussi besoin d'être capable de traiter les données fournies par l'utilisateur (pas seulement le contexte) et doit pouvoir réafficher les pages s'il y a une quelconque erreur.</p>
+
+<p>Voici ci-dessous un diagramme représentant les étapes de gestion d'un formulaire de requêtes, commencant par la demande par le navigateur d'une page, dont le code HTML se trouve contenir un formulaire (en vert).</p>
+
+<p><img alt="Updated form handling process doc." src="https://mdn.mozillademos.org/files/14205/Form%20Handling%20-%20Standard.png" style="display: block; height: 569px; margin: 0px auto; width: 800px;"></p>
+
+<p>En se basant sur la lecture du diagramme ci-dessus, les tâches principales dont s'aquitte Django à l'occasion de la gestion d'un formulaire sont : </p>
+
+<ol>
+ <li>Afficher le formulaire sous sa forme par défaut la première fois où il est demandé par l'utilisateur.
+ <ul>
+ <li>Le formulaire peut contenir des champs vides (par exemple si vous créez un nouvel enregistrement ) ou peut être prérempli de valeurs initiales (par exemple si vous modifiez les valeurs d'un enregistrement existant, ou que ces champs ont des valeurs initiales utiles ).</li>
+ <li>Le formulaire est qualifié à cette étape de formulaire libre, parce qu'il n'est associé à aucune donnée entré par l'utilisateur (bien qu'il puisse avoir des valeurs initiales) . </li>
+ </ul>
+ </li>
+ <li>Recevoir des données d'une requete d'envoi de données et les lier au formulaire.
+ <ul>
+ <li>Lier les données au formulaire signifie que les données entrées par l'utilisateur, ainsi que les erreurs éventuelles sont accessibles lorsque nous avons besoin de réafficher le formulaire. </li>
+ </ul>
+ </li>
+ <li>Nettoyer et valider les données
+ <ul>
+ <li>Le nettoyage de données consiste à désinfecter la saisie (par exemple en supprimant les caractères non valides, et qui pourraient être utilisés pour envoyer du contenu malveillant au serveur.) et à convertir ces données en types Python cohérents. </li>
+ <li>La validation vérifie que les valeurs envoyées sont appropriées au champ (par exemple dans le bon intervalle de dates, ni trop long ni trop court, etc.) </li>
+ </ul>
+ </li>
+ <li>Si une donnée n'est pas valide, ré-affiche le formulaire, cette fois-ci avec les données déjà saisies par l'utilisateur et les messages d'erreur pour les champs en erreur.</li>
+ <li>Si toutes les données sont conformes, effectue les actions demandées (e.g. sauvegarde les données, envoyer un mail, renvoie le résultat d'une recherche, télécharge un fichier etc.)</li>
+ <li>Une fois toutes ces actions accomplies, redirige l'utilisateur vers une autre page.</li>
+</ol>
+
+<p>Django fournit une multitude d'outils et de méthodes pour vous assister dans les tâches mentionnées ci-dessus. Parmi eux la plus importante, la classe <code>Form</code>, qui simplifie à la fois la production de formulaire HTML mais aussi la validation de donnée. In the next section we describe how forms work using the practical example of a page to allow librarians to renew books.</p>
+
+<div class="note">
+<p><strong>Note :</strong> Comprendre l'utilisation de <code>Form</code> vous aidera quand nous parlerons des classes de formulaires de Django plus complexes. </p>
+</div>
+
+<h2 id="Formulaire_de_renouvellement_de_livre_par_lutilisation_de_vue_Form">Formulaire de renouvellement de livre par l'utilisation de vue Form</h2>
+
+<p>Nous allons maintenant créer une page qui permettra aux bibliothécaires de renouveler les livres empruntés (les rendre disponible à nouveau). Pour cela nous allons créer un formulaire qui permet aux utilisateurs de saisir une valeur de type Date. Considérons le champ avec une valeur initiale égale à la date du jour plus 3 semaines (la période normale d'emprunt d'un livre), et ajouter une validation pour s'assurer que le bibliothécaire ne peut pas saisir une date dans le passé ou une date trop éloignée dans le futur. Quand une date valide a été entrée, nous l'enregistrons dans le champ <code>BookInstance.due_back</code> de l'enregistrement courant.</p>
+
+<p>L'exemple va utiliser une vue basée sur une fonction et une classe <code>Form</code>. Les sections suivantes expliquent comment les formulaires fonctionnent, et les changements que vous devez faire à notre projet en cours <em>LocalLibrary</em>.</p>
+
+<h3 id="Formulaire">Formulaire</h3>
+
+<p>La classe <code>Form</code> est le cœur du système de gestion des formulaires de Django. Elle spécifie les champs présents dans le formulaire, affiche les widgets, les labels, les valeurs initiales, les valeurs valides et (après validation) les messages d'erreur associés aux champs invalides. Cette classe fournit également des méthodes pour se restituer elle-même dans les templates en utilisant des formats prédéfinis (tables, listes etc.) ou pour obtenir la valeur de chaque élément de formulaire (permettant un rendu manuel fin).</p>
+
+<h4 id="Déclarer_un_formulaire">Déclarer un formulaire</h4>
+
+<p>La syntaxe de déclaration pour un <code>Form</code> est très semblable à celle utilisée pour déclarer un <code>Model</code>, et partage les mêmes types de champs (et des paramètres similaires). Cela est logique, puisque dans les deux cas nous avons besoin de nous assurer que chaque champ gère le bon type de donnée, est contraint lors de la validation des données, et a une description pour l'affichage/la documentation.</p>
+
+<p>Les données de formulaire sont stockées dans un fichier application forms.py, à l'intérieur du répertoire de l'application. Créez et ouvrez le fichier <strong>locallibrary/catalog/forms.py</strong>. Pour créer un <code>Form</code>, nous importons la bibliothèque <code>forms</code>, dérivons une classe de la classe <code>Form</code>, et déclarons les champs du formulaire. Une classe très basique de formulaire pour notre formulaire de renouvellement de livre dans notre bibliothèque est montrée ci-dessous :</p>
+
+<pre class="brush: python">from django import forms
+
+class RenewBookForm(forms.Form):
+    renewal_date = forms.DateField(help_text="Enter a date between now and 4 weeks (default 3).")
+</pre>
+
+<h4 id="Champs_de_formulaire">Champs de formulaire</h4>
+
+<p>Dans ce cas, nous avons un unique champ <code><a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#datefield">DateField</a></code> pour entrer la date du renouvellement, qui sera rendue en HTML avec une valeur vide, le label par défaut "<em>Renewal date:</em>", et un texte utilitaire indiquant comment s'en servir : "<em>Enter a date between now and 4 weeks (default 3 weeks).</em>" Comme aucun des autres arguments optionnels ne sont spécifiés, le champ acceptera des dates en utilisant les <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#django.forms.DateField.input_formats">input_formats</a> suivants : YYYY-MM-DD (2016-11-06), MM/DD/YYYY (02/26/2016), MM/DD/YY (10/25/16), et sera rendu en utilisant le <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#widget">widget</a> par défaut : <a href="https://docs.djangoproject.com/en/1.10/ref/forms/widgets/#django.forms.DateInput">DateInput</a>.</p>
+
+<p>Il y a beaucoup d'autres types de champs, que vous reconnaîtrez sans peine en raison de leur ressemblance avec les classes de champs équivalentes pour les modèles : <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#booleanfield"><code>BooleanField</code></a>, <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#charfield"><code>CharField</code></a>, <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#choicefield"><code>ChoiceField</code></a>, <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#typedchoicefield"><code>TypedChoiceField</code></a>, <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#datefield"><code>DateField</code></a>, <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#datetimefield"><code>DateTimeField</code></a>, <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#decimalfield"><code>DecimalField</code></a>, <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#durationfield"><code>DurationField</code></a>, <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#emailfield"><code>EmailField</code></a>, <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#filefield"><code>FileField</code></a>, <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#filepathfield"><code>FilePathField</code></a>, <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#floatfield"><code>FloatField</code></a>, <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#imagefield"><code>ImageField</code></a>, <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#integerfield"><code>IntegerField</code></a>, <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#genericipaddressfield"><code>GenericIPAddressField</code></a>, <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#multiplechoicefield"><code>MultipleChoiceField</code></a>, <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#typedmultiplechoicefield"><code>TypedMultipleChoiceField</code></a>, <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#nullbooleanfield"><code>NullBooleanField</code></a>, <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#regexfield"><code>RegexField</code></a>, <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#slugfield"><code>SlugField</code></a>, <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#timefield"><code>TimeField</code></a>, <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#urlfield"><code>URLField</code></a>, <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#uuidfield"><code>UUIDField</code></a>, <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#combofield"><code>ComboField</code></a>, <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#multivaluefield"><code>MultiValueField</code></a>, <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#splitdatetimefield"><code>SplitDateTimeField</code></a>, <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#modelmultiplechoicefield"><code>ModelMultipleChoiceField</code></a>, <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#modelchoicefield"><code>ModelChoiceField</code></a>​​​​.</p>
+
+<p>Les arguments communs de la plupart des champs sont listés ci-dessous (ils ont les valeurs les plus communes par défaut) :</p>
+
+<ul>
+ <li><a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#required">required</a>: Si <code>True</code>, le champ ne peut être laissé vide ou recevoir une valeur <code>None</code>. Les champs sont requis par défaut, aussi devez-vous préciser <code>required=False</code> pour autoriser des valeurs vides dans le formulaire.</li>
+ <li><a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#label">label</a>: Le label à utiliser au moment de rendre le champ en HTML. Si <a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#label">label</a> n'est pas précisé, alors Django en créera un à partir du nom du champ concerné, en mettant en majuscule la première lettre et en remplaçant les tirets bas par des espaces (p. ex. <em>Renewal date</em>).</li>
+ <li><a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#label-suffix">label_suffix</a>: Par défaut, un double point est affiché après le label (p. ex. Renewal date<strong>:</strong>). Cet argument vous permet de préciser un suffixe différent contenant un ou plusieurs autres caractère(s).</li>
+ <li><a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#initial">initial</a>: La valeur intiale pour le champ lorsque le formulaire est affiché.</li>
+ <li><a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#widget">widget</a>: Le widget d'affichage à utiliser.</li>
+ <li><a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#help-text">help_text</a> (comme dans l'exemple ci-dessus): Un texte supplémentaire qui peut être affiché dans les formulaires pour expliquer comment utiliser le champ.</li>
+ <li><a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#error-messages">error_messages</a>: Une liste des messages d'erreur pour le champ. Vous pouvez remplacer les messages par défaut par vos propres messages si besoin.</li>
+ <li><a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#validators">validators</a>: Une liste de fonctions qui seront appelées quand le champ sera validé.</li>
+ <li><a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#localize">localize</a>: Autorise la forme locale des données de formulaire (voyez le lien pour information).</li>
+ <li><a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/#disabled">disabled</a>: Si <code>True</code>, le champ est affiché, mais sa valeur ne peut être modifiée. <code>False</code> par défaut.</li>
+</ul>
+
+<h4 id="Validation">Validation</h4>
+
+<p>Django fournit un grand nombre d'endroits pour valider vos données. La façon la plus simple de valider un champ unique est de remplacer la méthode <code>clean_<strong>&lt;fieldname&gt;</strong>()</code> pour le champ à vérifier. Ainsi, par exemple, nous pouvons vérifier que les valeurs entrées pour le champ <code>renewal_date</code> sont entre maintenant et dans 4 semaines, en implémentant la méthode <code>clean_<strong>renewal_date</strong>()</code> comme montré ci-après.</p>
+
+<p>Mettez à jour votre fichier forms.py, de telle sorte qu'il ressemble à cela :</p>
+
+<pre class="brush: python">from django import forms
+
+<strong>from django.core.exceptions import ValidationError
+from django.utils.translation import ugettext_lazy as _
+import datetime #for checking renewal date range.
+</strong>
+class RenewBookForm(forms.Form):
+    renewal_date = forms.DateField(help_text="Enter a date between now and 4 weeks (default 3).")
+
+<strong>    def clean_renewal_date(self):
+        data = self.cleaned_data['renewal_date']
+
+        #Check date is not in past.
+        if data &lt; datetime.date.today():
+            raise ValidationError(_('Invalid date - renewal in past'))
+
+        #Check date is in range librarian allowed to change (+4 weeks).
+        if data &gt; datetime.date.today() + datetime.timedelta(weeks=4):
+            raise ValidationError(_('Invalid date - renewal more than 4 weeks ahead'))
+
+        # Remember to always return the cleaned data.
+        return data</strong></pre>
+
+<p>Il y a deux choses importantes à noter. La première est que nous accédons à nos données en utilisant <code>self.cleaned_data['renewal_date']</code>, et que nous retournons ces données, que nous les ayons changées ou non, à la fin de la fonction. Cette étape nous donne des données "nettoyées", purgées de valeurs potentiellement dangereuses en utilisant les validateurs par défaut, et converties en type standard correct pour les données considérées (dans ce cas un objet Python <code>datetime.datetime</code>).</p>
+
+<p>Le deuxième point est que, si une valeur tombe en dehors de l'intervalle que nous avons autorisé, nous levons une <code>ValidationError</code>, en spécifiant le texte d'erreur que nous voulons afficher dans la zone du formulaire prévue pour le cas où l'utilisateur entre une valeur incorrecte. L'exemple ci-dessus enveloppe aussi ce texte dans <code>ugettext_lazy()</code> (importée comme <code>_()</code>), une des <a class="external" href="https://docs.djangoproject.com/en/2.1/topics/i18n/translation/" rel="noopener">fonctions de traduction Django</a>, ce qui est une bonne pratique si vous voulez traduire votre site plus tard.</p>
+
+<div class="note">
+<p><strong>Note :</strong> Il y a un grand nombre d'autres méthodes et exemples au sujet de la validation des formulaires dans <a class="external" href="https://docs.djangoproject.com/en/2.1/ref/forms/validation/" rel="noopener">Form and field validation</a> (Django Docs). Par exemple, au cas où vous avez plusieurs champs dépendants les uns des autres, vous pouvez réécrire la fonction <a class="external" href="https://docs.djangoproject.com/en/2.1/ref/forms/api/#django.forms.Form.clean" rel="noopener">Form.clean()</a>, et lever de nouveau une <code>ValidationError</code>.</p>
+</div>
+
+<p>C'est tout ce dont nous avons besoin pour notre formulaire dans cet exemple.</p>
+
+<h3 id="Configuration_dURL">Configuration d'URL</h3>
+
+<p>Avant de créer notre vue, ajoutons une configuration d'URL pour la page <em>renew-books</em>. Copiez la configuration suivante à la fin de <strong>locallibrary/catalog/urls.py</strong>.</p>
+
+<pre class="brush: python">urlpatterns += [
+ url(r'^book/(?P&lt;pk&gt;[-\w]+)/renew/$', views.renew_book_librarian, name='renew-book-librarian'),
+]</pre>
+
+<p>La configuration d'URL va rediriger les URLs ayant le format <strong>/catalog/book/<em>&lt;bookinstance id&gt;</em>/renew/</strong> vers la fonction appelée <code>renew_book_librarian()</code> dans <strong>views.py</strong>, et envoyer l'id de <code>BookInstance</code> comme paramètre sous le nom <code>pk</code>. Le pattern ne fonctionnera que si <code>pk</code> est un <code>uuid</code> correctement formaté.</p>
+
+<div class="note">
+<p><strong>Note </strong>: Nous pouvons appeler comme bon nous semble la donnée d'URL "<code>pk</code>" que nous avons capturée, car nous contrôlons complètement la fonction de notre <em>view</em> (nous n'utilisons pas une vue générique <em>detail</em>, laquelle attendrait des paramètres avec un certain nom). Cependant, le raccourci <code>pk</code>, pour "primary key", est une convention qu'il est raisonnable d'utiliser !</p>
+</div>
+
+<h3 id="Vue">Vue</h3>
+
+<p>Comme nous l'avons expliqué ci-dessus dans <a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Forms#django_form_handling_process">Django form handling process</a>, la vue doit retourner le formulaire par défaut s'il est appelé pour la première fois, et ensuite soit le retourner à nouveau avec les messages d'erreur si les données sont invalides, soit gérer les données et rediriger vers une nouvelle page si elles sont valides. Pour effectuer ces différentes actions, la vue doit être en mesure de savoir si elle est appelée pour la première fois (et retourner le formulaire par défaut) ou pour la deuxième fois ou plus (et valider les données).</p>
+
+<p>Pour les formulaires qui utilisent une requête <code>POST</code> pour envoyer une information au serveur, la manière la plus commune de procéder pour la vue est de tester le type de requête <code>POST</code> (<code>if request.method == 'POST':</code>) pour repérer des requêtes de type validation de formulaire, et <code>GET</code> (en utilisant une condition <code>else</code>) pour identifer une requête initiale de création de formulaire. Si vous voulez utiliser une requête <code>GET</code> pour envoyer vos données, alors une approche classique pour savoir si la vue est invoquée pour la première fois ou non est de lire les données du formulaire (p. ex. lire une valeur cachée dans le formulaire).</p>
+
+<p>Le processus de renouvellement de livre va écrire dans notre base de données, aussi, par convention, nous utiliserons le type de requête <code>POST</code>. Le bout de code ci-dessous montre le procédé (très classique) pour cette sorte de vue basée sur des fonctions.</p>
+
+<pre class="brush: python">import datetime
+
+from django.shortcuts import get_object_or_404
+from django.http import HttpResponseRedirect
+from django.core.urlresolvers import reverse
+
+from .forms import RenewBookForm
+
+def renew_book_librarian(request, pk):
+    book_inst=get_object_or_404(BookInstance, pk = pk)
+
+    # If this is a POST request then process the Form data
+<strong>    if request.method == 'POST':</strong>
+
+        # Create a form instance and populate it with data from the request (binding):
+        form = RenewBookForm(request.POST)
+
+        # Check if the form is valid:
+        <strong>if form.is_valid():</strong>
+            # process the data in form.cleaned_data as required (here we just write it to the model due_back field)
+            book_inst.due_back = form.cleaned_data['renewal_date']
+            book_inst.save()
+
+            # redirect to a new URL:
+            return HttpResponseRedirect(reverse('all-borrowed') )
+
+    # If this is a GET (or any other method) create the default form.
+<strong>    else:</strong>
+        proposed_renewal_date = datetime.date.today() + datetime.timedelta(weeks=3)
+        form = RenewBookForm(initial={'renewal_date': proposed_renewal_date,})
+
+    return render(request, 'catalog/book_renew_librarian.html', {'form': form, 'bookinst':book_inst})</pre>
+
+<p>Nous importons tout d'abord notre formulaire (<code>RenewBookForm</code>) et un certain nombre d'autres objets/méthodes utiles, dont nous nous servons dans le corps de la fonction de notre vue :</p>
+
+<ul>
+ <li><code><a href="https://docs.djangoproject.com/en/1.10/topics/http/shortcuts/#get-object-or-404">get_object_or_404()</a></code> : Retourne un certain objet depuis un modèle, en se basant sur sa valeur "primary key", et lève une exception <code>Http404</code> (<em>not found</em>) si l'enregistrement n'existe pas.</li>
+ <li><code><a href="https://docs.djangoproject.com/en/1.10/ref/request-response/#django.http.HttpResponseRedirect">HttpResponseRedirect</a></code> : Cette méthode crée une redirection vers une certaine URL (code de statut HTTP 302).</li>
+ <li><code><a href="https://docs.djangoproject.com/en/1.10/ref/urlresolvers/#django.urls.reverse">reverse()</a></code> : Cette méthode génère une URL à partir d'un nom trouvé dans la configuration d'URL et un ensemble d'arguments. C'est l'équivalent Python du tag <code>url</code> que nous avons utilisé dans nos templates.</li>
+ <li><code><a href="https://docs.python.org/3/library/datetime.html">datetime</a></code> : Une bibliothèque Python pour manipuler des dates et des heures.</li>
+</ul>
+
+<p>Dans la vue, nous utilisons d'abord l'argument <code>pk</code> dans la fonction <code>get_object_or_404()</code>, afin d'obtenir la <code>BookInstance</code> courante (si cette instance n'existe pas, la vue se termine immédiatement et la page va afficher une erreur ). Si ce n'est <em>pas</em> une requête <code>POST</code> (cas géré par la clause <code>else</code>), alors nous créons le formulaire par défaut en lui passant une valeur <code>initial</code> pour le champ <code>renewal_date</code> (comme montré en gras ci-dessous, c'est la date actuelle plus 3 semaines).</p>
+
+<pre class="brush: python"> book_inst=get_object_or_404(BookInstance, pk = pk)
+
+    # If this is a GET (or any other method) create the default form
+    <strong>else:</strong>
+        proposed_renewal_date = datetime.date.today() + datetime.timedelta(<strong>weeks=3</strong>)
+        <strong>form = RenewBookForm(initial={'</strong>renewal_date<strong>': </strong>proposed_renewal_date<strong>,})</strong>
+
+    return render(request, 'catalog/book_renew_librarian.html', {'form': form, 'bookinst':book_inst})</pre>
+
+<p>Après création du formulaire, nous appelons la fonction <code>render()</code> pour créer la page HTML, en précisant le template et un contexte qui contient notre formulaire. Dans ce cas, le contexte contient aussi notre <code>BookInstance</code>, que nous allons utiliser dans le template pour fournir des informations à propos du livre que nous sommes en train de renouveler.</p>
+
+<p>En revanche, s'il s'agit d'une requête <code>POST</code>, alors nous créons notre objet <code>form</code> et le peuplons avec des données récupérées dans la requête. Ce processus est appelé "binding" (liaison) et nous permet de valider le formulaire. Ensuite nous vérifions que le formulaire est valide, ce qui déclenche tout le code de validation sur tous les champs - ce qui inclut à la fois le code générique vérifiant que notre champ date est effectivement une date valide, et notre fonction <code>clean_renewal_date()</code>, spécifique à notre formulaire, pour vérifier que la date est dans le bon intervalle.</p>
+
+<pre class="brush: python">    book_inst=get_object_or_404(BookInstance, pk = pk)
+
+    # If this is a POST request then process the Form data
+    if request.method == 'POST':
+
+        # Create a form instance and populate it with data from the request (binding):
+<strong>        form = RenewBookForm(request.POST)</strong>
+
+        # Check if the form is valid:
+        if form.is_valid():
+            # process the data in form.cleaned_data as required (here we just write it to the model due_back field)
+            book_inst.due_back = form.cleaned_data['renewal_date']
+            book_inst.save()
+
+            # redirect to a new URL:
+            return HttpResponseRedirect(reverse('all-borrowed') )
+
+    return render(request, 'catalog/book_renew_librarian.html', {'form': form, 'bookinst':book_inst})</pre>
+
+<p>Si le formulaire n'est pas valide, nous appelons aussi la fonction <code>render()</code>, mais cette fois les valeurs passées dans le contexte vont inclure les messages d'erreur.</p>
+
+<p>Si le formulaire est valide, alors nous pouvons commencer à utiliser les données, en y accédant à travers l'attribut <code>form.cleaned_data</code> (p. ex. <code>data = form.cleaned_data['renewal_date']</code>). Ici nous ne faisons que sauvegarder dans la valeur <code>due_back</code> de l'objet <code>BookInstance</code> associé les données reçues.</p>
+
+<div class="warning">
+<p><strong>Important </strong>: Alors que vous pouvez accéder aussi aux données de formulaire directement à travers la requête (par exemple <code>request.POST['renewal_date']</code>, ou <code>request.GET['renewal_date']</code> si vous utilisez une requête GET), ce n'est PAS recommandé. Les données nettoyées sont assainies, validées et converties en types standard Python.</p>
+</div>
+
+<p>L'étape finale dans la partie "gestion de formulaire" de la vue est de rediriger vers une autre page, habituellement une page "success". Dans ce cas, nous utilisons <code>HttpResponseRedirect</code> et <code>reverse()</code> pour rediriger vers la vue appelée <code>'all-borrowed'</code> (qui a été créée dans la partie "challenge" de <a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/authentication_and_sessions#Challenge_yourself">Django Tutorial Part 8: User authentication and permissions</a>. Si vous n'avez pas créé cette page, vous pouvez rediriger vers la page d'accueil à l'URL '/').</p>
+
+<p>C'est tout ce qui est requis pour la gestion du formulaire lui-même, mais il nous faut encore restreindre l'accès à la vue aux seuls libraires. Nous devrions sans doute créer un nouveau réglage de permission dans <code>BookInstance</code> ("<code>can_renew</code>"), mais, pour ne pour ne pas compliquer les choses ici, nous allons simplement utiliser le décorateur de fonction <code>@permission_required</code> avec notre permission existante <code>can_mark_returned</code>.</p>
+
+<p>Le résultat final de la vue est donc comme indiqué ci-dessous. Veuillez copier ceci en bas de <strong>locallibrary/catalog/views.py</strong>.</p>
+
+<pre><strong>from django.contrib.auth.decorators import permission_required</strong>
+
+from django.shortcuts import get_object_or_404
+from django.http import HttpResponseRedirect
+from django.core.urlresolvers import reverse
+import datetime
+
+from .forms import RenewBookForm
+
+<strong>@permission_required('catalog.<code>can_mark_returned</code>')</strong>
+def renew_book_librarian(request, pk):
+    """
+    View function for renewing a specific BookInstance by librarian
+    """
+    book_inst=get_object_or_404(BookInstance, pk = pk)
+
+    # If this is a POST request then process the Form data
+    if request.method == 'POST':
+
+        # Create a form instance and populate it with data from the request (binding):
+        form = RenewBookForm(request.POST)
+
+        # Check if the form is valid:
+        if form.is_valid():
+            # process the data in form.cleaned_data as required (here we just write it to the model due_back field)
+            book_inst.due_back = form.cleaned_data['renewal_date']
+            book_inst.save()
+
+            # redirect to a new URL:
+            return HttpResponseRedirect(reverse('all-borrowed') )
+
+    # If this is a GET (or any other method) create the default form.
+    else:
+        proposed_renewal_date = datetime.date.today() + datetime.timedelta(weeks=3)
+        form = RenewBookForm(initial={'renewal_date': proposed_renewal_date,})
+
+    return render(request, 'catalog/book_renew_librarian.html', {'form': form, 'bookinst':book_inst})
+</pre>
+
+<h3 id="Le_template">Le template</h3>
+
+<p>Créez le template référencé dans la vue (<strong>/catalog/templates/catalog/book_renew_librarian.html</strong>) et copiez-y le code suivant :</p>
+
+<pre class="brush: html">{% extends "base_generic.html" %}
+{% block content %}
+
+ &lt;h1&gt;Renew: \{{bookinst.book.title}}&lt;/h1&gt;
+ &lt;p&gt;Borrower: \{{bookinst.borrower}}&lt;/p&gt;
+ &lt;p{% if bookinst.is_overdue %} class="text-danger"{% endif %}&gt;Due date: \{{bookinst.due_back}}&lt;/p&gt;
+
+<strong> &lt;form action="" method="post"&gt;
+ {% csrf_token %}
+ &lt;table&gt;
+ \{{ form }}
+  &lt;/table&gt;
+ &lt;input type="submit" value="Submit" /&gt;
+ &lt;/form&gt;</strong>
+
+{% endblock %}</pre>
+
+<p>La majeure partie de ce code devrait vous être familière si vous avez suivi les tutoriels précédents. Nous étendons le template de base et ensuite redéfinissons le block "content". Nous sommes en mesure de référencer <code>\{{ book_instance }}</code> (et ses variables), puisqu'il a été passé dans l'objet context par la fonction <code>render()</code>, et nous utilisons tout cela pour lister le titre du livre, son emprunteur et la date originale de retour.</p>
+
+<p>Le code du formulaire est relativement simple. Nous déclarons d'abord les tags <code>form</code>, en précisant où le formulaire doit être adressé (<code>action</code>) et la <code>method</code> utilisée pour soumettre les donées (ici un "HTTP POST"). Si vous vous rappelez ce qui a été dit en haut de cette page (aperçu sur les <a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Forms#HTML_forms">HTML Forms</a>), une <code>action</code> vide comme ici signifie que les données de formulaire seront postées à nouveau à l'URL actuelle (ce qui est le comportement que nous voulons !). À l'intérieur des tags, nous définissons le bouton , sur lequel l'utilisateur peut appuyer pour envoyer les données. Le <code>{% csrf_token %}</code> ajouté juste à l'intérieur des tags "form" est un des éléments de protection utilisés par Django contre les "cross-site forgery".</p>
+
+<div class="note">
+<p><strong>Note :</strong> Ajoutez le <code>{% csrf_token %}</code> à tout template Django que vous créeez et qui utilise <code>POST</code> pour soumettre les données. Cela réduira les risques qu'un utilisateur mal intentionné pirate vos formulaires.</p>
+</div>
+
+<p>Tout ce qui reste est la variable de template <code>\{{ form }}</code>, que nous avons passée au template dans le dictionnaire de contexte. Peut-être sans surprise, quand il est utilisé comme indiqué, il fournit le rendu par défaut de tous les champs de formulaire, y compris leurs labels, widgets et textes d'aide. Voici le rendu :</p>
+
+<pre class="brush: html">&lt;tr&gt;
+  &lt;th&gt;&lt;label for="id_renewal_date"&gt;Renewal date:&lt;/label&gt;&lt;/th&gt;
+  &lt;td&gt;
+  &lt;input id="id_renewal_date" name="renewal_date" type="text" value="2016-11-08" required /&gt;
+  &lt;br /&gt;
+  &lt;span class="helptext"&gt;Enter date between now and 4 weeks (default 3 weeks).&lt;/span&gt;
+  &lt;/td&gt;
+&lt;/tr&gt;
+</pre>
+
+<div class="note">
+<p><strong>Note :</strong> Ce n'est peut-être pas évident, car nous n'avons qu'un seul champ, mais, par défaut, chaque champ est défini dans sa propre ligne de tableau. Ce même rendu est fourni si vous référencez la variable de template <code>\{{ form.as_table }}</code>.</p>
+</div>
+
+<p>Si vous aviez entré une date invalide, vous obtiendriez en plus sur la page une liste des erreurs (indiquées en gras ci-dessous).</p>
+
+<pre class="brush: html">&lt;tr&gt;
+  &lt;th&gt;&lt;label for="id_renewal_date"&gt;Renewal date:&lt;/label&gt;&lt;/th&gt;
+  &lt;td&gt;
+<strong>  &lt;ul class="errorlist"&gt;
+  &lt;li&gt;Invalid date - renewal in past&lt;/li&gt;
+  &lt;/ul&gt;</strong>
+  &lt;input id="id_renewal_date" name="renewal_date" type="text" value="2015-11-08" required /&gt;
+  &lt;br /&gt;
+  &lt;span class="helptext"&gt;Enter date between now and 4 weeks (default 3 weeks).&lt;/span&gt;
+ &lt;/td&gt;
+&lt;/tr&gt;</pre>
+
+<h4 id="Autres_façons_dutiliser_la_variable_de_template_du_formulaire">Autres façons d'utiliser la variable de template du formulaire</h4>
+
+<p>Si vous utilisez <code>\{{ form.as_table }}</code> comme indiqué ci-dessus, chaque champ est rendu comme une ligne de tableau. Vous pouvez également rendre chaque champ comme un élément de liste (en utilisant <code>\{{ form.as_ul }}</code>) ou comme un paragraphe (en utilisant <code>\{{ form.as_p }}</code>).</p>
+
+<p>Il est également possible d'avoir un contrôle complet sur le rendu de chaque partie du formulaire, en indexant ses propriétés grâce à la notation pointée. Ainsi, par exemple, nous pouvons accéder un certain nombre d'éléments distincts pour notre champ <code>renewal_date</code> :</p>
+
+<ul>
+ <li><code>\{{form.renewal_date}}</code>  : Le champ complet.</li>
+ <li><code>\{{form.renewal_date.errors}}</code> : La liste des erreurs.</li>
+ <li><code>\{{form.renewal_date.id_for_label}}</code> : L'id du label.</li>
+ <li><code>\{{form.renewal_date.help_text}}</code> : Le texte d'aide du champ.</li>
+ <li>etc !</li>
+</ul>
+
+<p>Pour plus d'exemples sur la manière de rendre manuellement des formulaires dans des templates, et boucler de manière dynamique sur les champs du template, voyez <a href="https://docs.djangoproject.com/en/1.10/topics/forms/#rendering-fields-manually">Working with forms &gt; Rendering fields manually</a> (Django docs).</p>
+
+<h3 id="Tester_la_page">Tester la page</h3>
+
+<p>Si vous avez accepté le "challenge" dans <a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/authentication_and_sessions#Challenge_yourself">Django Tutorial Part 8: User authentication and permissions</a>, vous avez une liste de tous les livres empruntés dans la bibliothèque, ce qui n'est visible que pour le staff de la bibliothèque. Nous pouvons ajouter un lien vers notre page de renouvellement après chaque élément, en utilisant le code de template suivant.</p>
+
+<pre class="brush: html">{% if perms.catalog.can_mark_returned %}- &lt;a href="{% url 'renew-book-librarian' bookinst.id %}"&gt;Renew&lt;/a&gt; {% endif %}</pre>
+
+<div class="note">
+<p><strong>Note </strong>: Souvenez-vous que votre login de test devra avoir la permission "<code>catalog.can_mark_returned</code>" pour pouvoir accéder la page de renouvellement de livre (utilisez peut-être votre compte superuser).</p>
+</div>
+
+<p>Vous pouvez aussi construire manuellement une URL de test comme ceci : <a class="external" href="http://127.0.0.1:8000/catalog/book/&lt;bookinstance id>/renew/" rel="noopener">http://127.0.0.1:8000/catalog/book/<em>&lt;bookinstance_id&gt;</em>/renew/</a> (un id de bookinstance valide peut être obtenu en navigant vers une page de détail de livre dans votre bibliothèque, et en copiant le champ <code>id</code>).</p>
+
+<h3 id="À_quoi_cela_ressemble-t-il">À quoi cela ressemble-t-il ?</h3>
+
+<p>Si tout a bien marché, le formulaire par défaut ressemblera à ceci :</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/14209/forms_example_renew_default.png" style="border-style: solid; border-width: 1px; display: block; height: 292px; margin: 0px auto; width: 680px;"></p>
+
+<p>Le formulaire avec valeur erronée ressemblera à ceci :</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/14211/forms_example_renew_invalid.png" style="border-style: solid; border-width: 1px; display: block; height: 290px; margin: 0px auto; width: 658px;"></p>
+
+<p>La liste de tous les livres avec les liens vers le renouvellement ressemblera à ceci :</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/14207/forms_example_renew_allbooks.png" style="border-style: solid; border-width: 1px; display: block; height: 256px; margin: 0px auto; width: 613px;"></p>
+
+<h2 id="ModelForms">ModelForms</h2>
+
+<p>Créer une classe  en utilisant l'approche décrite ci-dessus est très flexible et vous autorise à créer le type de page de formulaire que vous voulez, et à l'associer à tout type de modèle(s).</p>
+
+<p>Cependant, si vous avez seulement besoin d'un formulaire qui répertorie les champs d'un modèle unique, alors votre modèle définira déjà la plupart des informations requises dans votre formulaire : champs, labels, texte d'aide etc. Plutôt que de créer à nouveau les définitions du modèle dans votre formulaire, il est plus facile d'utiliser la classe d'aide <a class="external" href="https://docs.djangoproject.com/en/2.1/topics/forms/modelforms/" rel="noopener">ModelForm</a> pour créer le formulaire d'après votre modèle. Ce <code>ModelForm</code> peut dès lors être utilisé à l'intérieur de vos vues exactement de la même manière qu'un <code>Form</code> ordinaire.</p>
+
+<p>Un <code>ModelForm</code> basique, contenant le même champ que notre <code>RenewBookForm</code> d'origine, est montré ci-dessous. Tout ce que vous avez à faire pour créer le formulaire, c'est ajouter <code>class Meta</code> avec le <code>model</code> (<code>BookInstance</code>) associé, et une liste des <code>fields</code> du modèle à inclure dans le formulaire (vous pouvez inclure tous les champs en utilisant <code>fields = '__all__'</code>, ou bien utiliser <code>exclude</code> (au lieu de <code>fields</code>) pour préciser les champs à ne <em>pas</em> importer du modèle).</p>
+
+<pre class="brush: python">from django.forms import ModelForm
+from .models import BookInstance
+
+class RenewBookModelForm(ModelForm):
+<strong> class Meta:
+ model = BookInstance
+ fields = ['due_back',]</strong>
+</pre>
+
+<div class="note">
+<p><strong>Note </strong>: Cela peut ne pas sembler beaucoup plus simple que d'utiliser un simple <code>Form</code>, et ça ne l'est effectivement pas dans ce cas, parce que nous n'avons qu'un seul champ. Cependant, si vous avez beaucoup de champs, cela peut réduire notablement la quantité de code !</p>
+</div>
+
+<p>Le reste de l'information vient des définitions de champ données par le modèle (par ex. les labels, les widgets, le texte d'aide, les messages d'erreur). S'ils ne sont pas suffisamment satisfaisants, nous pouvons les réécrire dans notre <code>class Meta</code>, en précisant un dictionnaire contenant le champ à modifier et sa nouvelle valeur. Par exemple, dans ce formulaire, nous pourrions souhaiter, pour notre champ, un label tel que "<em>Renewal date</em>" (plutôt que celui par défaut, basé sur le nom du champ : <em>Due Back</em>), et nous voulons aussi que notre texte d'aide soit spécifique à ce cas d'utilisation. La classe <code>Meta</code> ci-dessous vous montre comment réécrire ces champs, et vous pouvez pareillement définir <code>widgets</code> et <code>error_messages</code> si les valeurs par défaut ne sont pas suffisantes.</p>
+
+<pre class="brush: python">class Meta:
+ model = BookInstance
+ fields = ['due_back',]
+<strong> labels = { 'due_back': _('Renewal date'), }
+ help_texts = { 'due_back': _('Enter a date between now and 4 weeks (default 3).'), } </strong>
+</pre>
+
+<p>Pour ajouter une validation, vous pouvez utiliser la même approche que pour un <code>Form</code> normal : vous définissez une fonction appelée <code>clean_<em>field_name</em>()</code>, et vous levez des exceptions de type <code>ValidationError</code> pour les valeurs non valides. La seule différence par rapport à notre formulaire original, c'est que le champ de modèle est appelé <code>due_back</code> et non "<code>renewal_date</code>". Ce changement est nécessaire, dans la mesure où le champ correspondant dans <code>BookInstance</code> est appelé <code>due_back</code>.</p>
+
+<pre class="brush: python">from django.forms import ModelForm
+from .models import BookInstance
+
+class RenewBookModelForm(ModelForm):
+<strong>    def clean_due_back(self):
+       data = self.cleaned_data['due_back']
+
+  #Check date is not in past.
+       if data &lt; datetime.date.today():
+           raise ValidationError(_('Invalid date - renewal in past'))
+
+       #Check date is in range librarian allowed to change (+4 weeks)
+       if data &gt; datetime.date.today() + datetime.timedelta(weeks=4):
+           raise ValidationError(_('Invalid date - renewal more than 4 weeks ahead'))
+
+       # Remember to always return the cleaned data.
+       return data
+</strong>
+ class Meta:
+ model = BookInstance
+ fields = ['due_back',]
+ labels = { 'due_back': _('Renewal date'), }
+ help_texts = { 'due_back': _('Enter a date between now and 4 weeks (default 3).'), }
+</pre>
+
+<p>La classe <code>RenewBookModelForm</code> ci-dessus est maintenant fonctionnellement équivalente à notre <code>RenewBookForm</code> d'origine. Vous pourriez l'importer et l'utiliser partout où vous utilisez <code>RenewBookForm</code>, du moment que vous changez aussi de <code>renewal_date</code> en <code>due_back</code> le nom de variable du formulaire correspondant, comme dans la deuxième déclaration du formulaire : <code>RenewBookModelForm(initial={'due_back': proposed_renewal_date}</code>.</p>
+
+<h2 id="Vues_génériques_dédition">Vues génériques d'édition</h2>
+
+<p>L'algorithme de gestion des formulaires que nous avons utilisé ci-dessus dans notre exemple de vue basée sur une fonction, représente un processus extrêmement commun dans vues destinées à éditer un formulaire. Django abstrait pour vous la plus grande partie de ce processus répétitif ("boilerplate") en proposant des <a class="external" href="https://docs.djangoproject.com/en/2.1/ref/class-based-views/generic-editing/" rel="noopener">generic editing views</a> pour les vues de création, éditition et suppression basées sur des modèles. Ces vues génériques non seulement assument le comportement d'une vue, mais elles créent automatiquement la classe de formulaire (un <code>ModelForm</code>) pour vous à partir du modèle.</p>
+
+<div class="note">
+<p><strong>Note : </strong>En plus des vues d'édition décrites ici, il existe aussi une classe <a class="external" href="https://docs.djangoproject.com/en/2.1/ref/class-based-views/generic-editing/#formview" rel="noopener">FormView</a>, qui se tient, en termes de rapport "flexibilité"/"effort codage", à mi-chemin entre notre vue basée sur une fonction et les autres vues génériques. En utilisant <code>FormView</code>, vous avez encore besoin de créer votre <code>Form</code>, mais vous n'avez pas besoin d'implémenter tous les éléments d'une gestion standard de formulaire. À la place, vous n'avez qu'à fournir une implémentation de la fonction qui sera appelée une fois que les données envoyées sont reconnues valides.</p>
+</div>
+
+<p>Dans cette section, nous allons utiliser des vues génériques d'édition pour créer des pages afin de pouvoir ajouter les fonctionnalités de création, d'édition et de suppression des enregistrements de type <code>Author</code> de notre bibliothèque, en fournissant efficacement une réimplémentation basique de certaines parties du site Admin (cela peut être intéressant si vous avez besoin d'offrir une fonctionnalité admin d'une manière plus flexible que ce qui peut être présenté par le site admin).</p>
+
+<h3 id="Vues">Vues</h3>
+
+<p>Ouvrez le fichier vue (<strong>locallibrary/catalog/views.py</strong>) et ajoutez le bloc de code suivant à la fin :</p>
+
+<pre class="brush: python">from django.views.generic.edit import CreateView, UpdateView, DeleteView
+from django.urls import reverse_lazy
+from .models import Author
+
+class AuthorCreate(CreateView):
+ model = Author
+ fields = '__all__'
+ initial={'date_of_death':'12/10/2016',}
+
+class AuthorUpdate(UpdateView):
+ model = Author
+ fields = ['first_name','last_name','date_of_birth','date_of_death']
+
+class AuthorDelete(DeleteView):
+ model = Author
+ success_url = reverse_lazy('authors')</pre>
+
+<p>Comme vous pouvez le voir, pour les vues "créer", "modifier" et "supprimer", vous avez besoin de dériver respectivement des vues génériques <code>CreateView</code>, <code>UpdateView</code>, et <code>DeleteView</code>, et de définir ensuite le modèle associé.</p>
+
+<p>Pour les cas "créer" et "modifier", vous devez aussi préciser les champs à afficher dans le formulaire (en utilisant la même syntaxe que pour la classe <code>ModelForm</code>). Dans ce cas, nous montrons à la fois la syntaxe pour afficher "tous" les champs, et comment vous pouvez les lister un par un. Vous pouvez aussi spécifier les valeurs initiales pour chacun des champs, en utilisant un dictionnaire de paires <em>nom_du_champ/valeur</em> (ici nous définissons arbitrairement la date de mort, uniquement dans un but de démonstration - sans doute voudrez-vous l'enlever !). Par défaut, ces vues vont rediriger en cas de succès vers une page affichant l'élément nouvellement créé ou modifié, ce qui, dans notre cas, sera la vue "détail" d'un auteur, créée dans un précédent tutoriel. Vous pouvez spécifier un autre lieu de redirection en déclarant explicitement le paramètre <code>success_url</code> (comme indiqué dans la classe <code>AuthorDelete</code>).</p>
+
+<p>La classe  ne requiert pas l'affichage d'aucun champ, aussi n'ont-ils pas besoin d'être précisés. Par contre il vous faut bien spécifier la <code>success_url</code>, car Django n'a pas de valeur par défaut pour cela. Dans ce cas, nous utilisons la fonction  pour rediriger vers notre liste d'auteurs après qu'un auteur ait été supprimé. <code>reverse_lazy()</code> est une version de <code>reverse()</code> exécutée mollement ("lazily"), que nous utilisons ici parce que nous fournissons une URL à un attribut de vue basée sur classe.</p>
+
+<h3 id="Templates">Templates</h3>
+
+<p>Les vues "créer" et "modifier" utilisent le même template par défaut, lequel sera nommé d'après votre modèle : <em>model_name</em><strong>_form.html</strong> (vous pouvez changer le suffixe en autre chose que <strong>_form</strong> en utilisant le champ <code>template_name_suffix</code> dans votre vue, par exemple <code>template_name_suffix = '_other_suffix'</code>).</p>
+
+<p>Créez le fichier de template <strong>locallibrary/catalog/templates/catalog/author_form.html</strong>, et copiez-y le texte suivant.</p>
+
+<pre class="brush: html">{% extends "base_generic.html" %}
+
+{% block content %}
+
+&lt;form action="" method="post"&gt;
+ {% csrf_token %}
+ &lt;table&gt;
+ \{{ form.as_table }}
+ &lt;/table&gt;
+ &lt;input type="submit" value="Submit" /&gt;
+
+&lt;/form&gt;
+{% endblock %}</pre>
+
+<p>Ce formulaire est semblable à nos formulaires précédents et affiche les champs en utilisant un tableau. Notez aussi comment nous déclarons à nouveau le <code>{% csrf_token %}</code> pour nous assurer que nos formulaires résisteront à d'éventuelles attaques par CSRF (Cross Site Request Forgery).</p>
+
+<p>La vue "supprimer" s'attend à trouver un template avec un nom au format <em>model_name</em><strong>_confirm_delete.html</strong> (de nouveau, vous pouvez changer le suffixe en utilisant <code>template_name_suffix</code> dans votre vue). Créez le fichier de template <strong>locallibrary/catalog/templates/catalog/author_confirm_delete</strong><strong>.html</strong>, et copiez-y le texte suivant.</p>
+
+<pre class="brush: html">{% extends "base_generic.html" %}
+
+{% block content %}
+
+&lt;h1&gt;Delete Author&lt;/h1&gt;
+
+&lt;p&gt;Are you sure you want to delete the author: \{{ author }}?&lt;/p&gt;
+
+&lt;form action="" method="POST"&gt;
+ {% csrf_token %}
+ &lt;input type="submit" action="" value="Yes, delete." /&gt;
+&lt;/form&gt;
+
+{% endblock %}
+</pre>
+
+<h3 id="Configurations_dURL">Configurations d'URL</h3>
+
+<p>Ouvrez votre fichier de configuration d'URL (<strong>locallibrary/catalog/urls.py</strong>) et ajoutez-y à la fin la configuration suivante :</p>
+
+<pre class="brush: python">urlpatterns += [
+ url(r'^author/create/$', views.AuthorCreate.as_view(), name='author_create'),
+ url(r'^author/(?P&lt;pk&gt;\d+)/update/$', views.AuthorUpdate.as_view(), name='author_update'),
+ url(r'^author/(?P&lt;pk&gt;\d+)/delete/$', views.AuthorDelete.as_view(), name='author_delete'),
+]</pre>
+
+<p>Il n'y a rien de particulièrement nouveau ici ! Vous pouvez voir que les vues sont des classes, et doivent dès lors être appelée via <code>.as_view()</code>, et vous devriez être capable de reconnaître les patterns d'URL dans chaque cas. Nous devons utiliser <code>pk</code> comme nom pour la valeur de nos clés primaires capturées, car c'est le nom de paramètre attendu par les classes de vue.</p>
+
+<p>Les pages de création, modification et suppression d'auteur sont maintenant prêtes à être testées (nous ne nous mettons pas en peine pour cette fois, bien que vous puissiez le faire si vous le souhaiter, de les accrocher dans la barre latérale du site).</p>
+
+<div class="note">
+<p><strong>Note </strong>: Les utilisateurs observateurs auront remarqué que nous n'avons rien fait pour empêcher les utilisateurs non autorisés d'accéder ces pages ! Nous laissons cela comme exercice pour vous (suggestion : vous pourriez utiliser le <code>PermissionRequiredMixin</code>, et soit créer une nouvelle permission, soit réutiliser notre permission<code>can_mark_returned</code> ).</p>
+</div>
+
+<h3 id="Test_de_la_page">Test de la page</h3>
+
+<p>Tout d'abord, connectez-vous au site avec un compte ayant les permissions que vous avez définies comme nécessaires pour accéder aux pages d'édition d'auteur.</p>
+
+<p>Ensuite naviguez à la page de création d'auteur : <a class="external" href="http://127.0.0.1:8000/catalog/author/create/" rel="noopener">http://127.0.0.1:8000/catalog/author/create/</a>, ce qui devrait ressembler à la capture d'écran ci-dessous.</p>
+
+<p><img alt="Form Example: Create Author" src="https://mdn.mozillademos.org/files/14223/forms_example_create_author.png" style="border-style: solid; border-width: 1px; display: block; height: 184px; margin: 0px auto; width: 645px;"></p>
+
+<p>Entrez des valeurs pour les champs et ensuite cliquez sur <strong>Submit</strong> pour sauvegarder l'enregistrement de cet auteur. Vous devriez maintenant être conduit à une vue "détail" pour votre nouvel auteur, avec une URL du genre <em>http://127.0.0.1:8000/catalog/author/10</em>.</p>
+
+<p>Vous pouvez tester l'édition d'un enregistrement en ajoutant <em>/update/</em> à la fin de l'URL "détail" (par exemple <em>http://127.0.0.1:8000/catalog/author/10/update/</em>). Nous ne mettons pas de capture d'écran, car c'est à peu près la même chose que la page "create".</p>
+
+<p>Enfin, nous pouvons effacer l'enregistrement en ajoutant "delete" à la fin de l'URL de détail (par exemple <em>http://127.0.0.1:8000/catalog/author/10/delete/</em>). Django devrait vous afficher la page de suppression montrée ci-dessous. Cliquez sur "<strong>Yes, delete</strong>" pour supprimer l'enregistrement et être reconduit à la liste des auteurs.</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/14221/forms_example_delete_author.png" style="border-style: solid; border-width: 1px; display: block; height: 194px; margin: 0px auto; width: 561px;"></p>
+
+<h2 id="Mettez-vous_au_défi">Mettez-vous au défi</h2>
+
+<p>Créez des formulaires pour créer, modifier et effacer des enregistrements de type <code>Book</code>. Vous pouvez utiliser exactement la même structure que pour les <code>Authors</code>. Si votre template <strong>book_form.html</strong> est simplement copié-renommé à partir du template <strong>author_form.html</strong>, alors la nouvelle page "create book" va ressembler à quelque chose comme ceci :</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/14225/forms_example_create_book.png" style="border-style: solid; border-width: 1px; display: block; height: 521px; margin: 0px auto; width: 595px;"></p>
+
+<ul>
+</ul>
+
+<h2 id="Résumé">Résumé</h2>
+
+<p>Créer et gérer des formulaires peut être un processus compliqué ! Django le rend bien plus aisé en fournissant des mécanismes de programmation pour déclarer, rendre et valider des formulaires. Django fournit de plus des vues génériques d'édition de formulaires, qui peuvent faire presque tout le travail si vous voulez définir des pages pour créer, modifier et supprimer des enregistrements associés à une instance d'un modèle unique.</p>
+
+<p>Il y a bien d'autres choses qui peuvent être faites avec les formulaires (regardez notre liste <a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Forms#See_also">See also</a> ci-dessous), mais vous devez être maintenant en mesure de comprendre comment ajouter des formulaires basiques et un code de gestion de formulaire à vos propres sites web.</p>
+
+<h2 id="See_also">See also</h2>
+
+<ul>
+ <li><a href="https://docs.djangoproject.com/en/1.10/topics/forms/">Working with forms</a> (Django docs)</li>
+ <li><a href="https://docs.djangoproject.com/en/1.10/intro/tutorial04/#write-a-simple-form">Writing your first Django app, part 4 &gt; Writing a simple form</a> (Django docs)</li>
+ <li><a href="https://docs.djangoproject.com/en/1.10/ref/forms/api/">The Forms API</a> (Django docs)</li>
+ <li><a href="https://docs.djangoproject.com/en/1.10/ref/forms/fields/">Form fields</a> (Django docs) </li>
+ <li><a href="https://docs.djangoproject.com/en/1.10/ref/forms/validation/">Form and field validation</a> (Django docs)</li>
+ <li><a href="https://docs.djangoproject.com/en/1.10/topics/class-based-views/generic-editing/">Form handling with class-based views</a> (Django docs)</li>
+ <li><a href="https://docs.djangoproject.com/en/1.10/topics/forms/modelforms/">Creating forms from models</a> (Django docs)</li>
+ <li><a href="https://docs.djangoproject.com/en/1.10/ref/class-based-views/generic-editing/">Generic editing views</a> (Django docs)</li>
+</ul>
+
+<p>{{PreviousMenuNext("Learn/Server-side/Django/authentication_and_sessions", "Learn/Server-side/Django/Testing", "Learn/Server-side/Django")}}</p>
diff --git a/files/fr/learn/server-side/django/home_page/index.html b/files/fr/learn/server-side/django/home_page/index.html
new file mode 100644
index 0000000000..91f6ef16bf
--- /dev/null
+++ b/files/fr/learn/server-side/django/home_page/index.html
@@ -0,0 +1,429 @@
+---
+title: 'Django didactique Section 5: Créer la page d''accueil'
+slug: Learn/Server-side/Django/Home_page
+tags:
+ - Article
+ - Cadriciel
+ - Code
+ - Didactique
+ - Django (Vues)
+ - Django (gabarits)
+ - Débutant
+ - Programmation
+ - Python
+ - django
+translation_of: Learn/Server-side/Django/Home_page
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/Server-side/Django/Admin_site", "Learn/Server-side/Django/Generic_views", "Learn/Server-side/Django")}}</div>
+
+<p class="summary">Le travail préparatoire pour nous permettre de créer une page d'accueil pour le site web de <a href="/fr/docs/Learn/Server-side/Django/Tutorial_local_library_website">la bibliothèque locale</a> est réalisé. La page d'accueil montera le nombre d'enregistrements pour chacun des objets décrits dans la base et les liens à l'aide d'une barre latérale de navigation. Dans la progression de l'article, nous apprendrons à gérer les vues et à présenter les données à l'aide de gabarits.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Pré-requis:</th>
+ <td>L'<a href="/fr/docs/Learn/Server-side/Django/Introduction">introduction</a> à cette série didactique et les sections précédentes y compris celle sur <a href="/fr/docs/Learn/Server-side/Django/Admin_site">le site d'administration</a> du site web.</td>
+ </tr>
+ <tr>
+ <th scope="row">Objective:</th>
+ <td>Apprendre à construire un routage d'URL et les pages de publication des vues (où les données ne sont pas encodées dans l'url). Obtenir et publier des données via les objets du modèle de données et les publier à l'aide de gabarits.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Survol">Survol</h2>
+
+<p>Dans les sections précédentes, nous avons défini <a href="/fr/docs/Learn/Server-side/Django/Models">le modèle de données et les objets Dajngo à manipuler</a>, puis nous avons commencé à peupler <a href="/fr/docs/Learn/Server-side/Django/Admin_site">des enregistrements à l'aide du site d'administration</a>. Désormais, nous allons œuvrer à la présentation des données et développer le code nécessaire à l'information des utilisateurs. La première étape essentielle est de déterminer les informations que nous souhaitons publier dans nos différentes pages et, par conséquent, identifier les URL qui pourvoiront à la publication de ces informations. Nous serons alors en capacité de construire les routage d'URL, les vues et gabarits qui répondront aux exigences définies.</p>
+
+<p>Le diagramme ci-dessous est important à comprendre car il est au cœur du fonctionnement du cadriciel Django. Il décrit les flux de données et les composants sollicités pour traiter et répondre à une requête HTTP. Nous avons déjà travaillé le modèle de données (à gauche du diagramme), nous allons désormais nous atteler à :</p>
+
+<ul>
+ <li>détailler le routage des URL pour associer les vues adaptées aux requêtes HTTP que le site devra traiter (y compris avec des informations encodées dans les URL).</li>
+ <li>définir les fonctions de visualisation et créer les pages HTML qui vont permettre de publier les informations à destination des utilisateurs du site.</li>
+ <li>créer les gabarits qui vont permettre de publier les données dans les vues.</li>
+</ul>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/13931/basic-django.png" style="display: block; margin: 0px auto;"></p>
+
+<p>Nous aurons à créer 5 pages web pour publier les informations à destination des utilisateurs. Cela fait beaucoup d'éléments à maîtriser dans une seule section d'apprentissage de l'outils. Nous avons donc opté pour ne traiter dans cette section que de la page d'accueil et de traiter les autres pages dans une autre section du didacticiel. Cela permet, en outre, de mieux appréhender les composants comme le routage d'URL ou les vues et d'une manière générale le fonctionnement du modèle de Django.</p>
+
+<h2 id="Identifier_les_URLs_des_ressources">Identifier les URLs des ressources</h2>
+
+<p>Le site web de la bibliothèque locale est essentiellement un site de consultation pour les adhérents de la bibliothèque, nous aurons donc, par conséquent, besoin uniquement de pages pour les vues de détail de chacun des livres (ouvrages, auteur, etc.) de la bibliothèque et d'une page d'accueil.</p>
+
+<p>La liste des URLs dont nous aurons besoin se résume à :</p>
+
+<ul>
+ <li><code>catalog/</code> — Pour la page d'accueil.</li>
+ <li><code>catalog/books/</code> — Pour la liste des livres.</li>
+ <li><code>catalog/authors/</code> — Pour la liste des auteurs.</li>
+ <li><code>catalog/book/<em>&lt;id&gt;</em></code> — Pour disposer du détails de chacun des livres mis en prêt et identifiés par identifiants <code><em>&lt;id&gt;</em></code> unique (le troisième livre enregistré est consultable dans le détail via l'url <code>/catalog/book/3</code>).</li>
+ <li><code>catalog/author/<em>&lt;id&gt;</em></code><em> </em>— De la même manière, le détail de chacun des auteurs enregistrés, identifié de la la même manière par sa clé primaire <em><code>&lt;id&gt;</code></em>.</li>
+</ul>
+
+<p>Bien que les données dépendent du contenu de la base de données, les trois premières URLs retournent les résultats de requêtes sans informations supplémentaires ; c'est le cas de la page d'accueil qui donnera des décomptes de contenus et des pages sur la listes des livres ou des auteurs.</p>
+
+<p>En revanche, les pages concernant le détails d'un livre ou d'un auteur nécessiteront de traiter l'identifiant d'un  objet. Il sera nécessaire d'extraire de la requête HTTP l'information encodé de cet identifiant pour obtenir ensuite le détail depuis la base de données. Pour cela nous utiliserons un seul jeu de vue et de gabarit pour publier les informations sur les livres (et auteurs).</p>
+
+<div class="note">
+<p><strong>Note</strong>: Avec le cadriciel Django, vous pouvez élaborer vos URLs comme bon vous semble — Vous pouvez avoir une approche comme celle présentée ci-dessus, ou de faire un appel de la méthode <code>GET</code> avec un passage de paramètres (<code>/book/?id=6</code>). Cependant, quelque soit l'approche pour laquelle vous opterez, garder en mémoire d'avoir des URLs claires, logique et compréhensibles comme cela est  <a href="https://www.w3.org/Provider/Style/URI">recommandé par le W3C</a>.</p>
+
+<p>La documentation de Django recommande aussi de coder les informations dans le corps des URLs pour avoir une meilleure conception de ces URLs.</p>
+</div>
+
+<p>La suite de cette section s'intéresse à la conception de la page d'accueil.</p>
+
+<h2 id="Création_de_la_page_d'accueil">Création de la page d'accueil</h2>
+
+<p>La toute première page à créer est la page d'accueil (<code>catalog/</code>). Cette page d'index est globalement une page statique contenant le décompte des différents enregistrements de la base de données. Pour faire cela, il sera nécessaire de créer un routage d'URL, une vue et un gabarit. </p>
+
+<div class="note">
+<p><strong>Note</strong>: Cette section est essentielle, et cela vaut vraiment la peine d'être attentif aux concepts déployés dans celle-ci. La plupart des éléments aborder ici seront ré-utilisés par la suite.</p>
+</div>
+
+<h3 id="Routage_d'URL">Routage d'URL</h3>
+
+<p>Quand nous avons créé <a href="/fr/docs/Learn/Server-side/Django/skeleton_website">le squelette du site</a>, nous avons mis à jour les routage des urls dans le fichier <strong>locallibrary/urls.py</strong> afin de nous assurer que toutes les requêtes démarrant par <code>catalog/</code>  seront traités par le configurateur <em>URLConf du module</em> <code>catalog.urls</code> qui traitera la sous-chaîne restante.</p>
+
+<p>L'extrait du code ci-dessous permet d'intégrer dans <strong>locallibrary/urls.py </strong>le configurateur d'url du module <code><em>catalog</em></code> :</p>
+
+<pre>urlpatterns += [
+    path('catalog/', include('catalog.urls')),
+]
+</pre>
+
+<p>Il est désormais nécessaire de créer un configurateur d'URL du module <code>catalog</code> (<em>URLConf </em>du module est nommé <strong>/catalog/urls.py</strong>). Ajoutez le chemin ci-dessous :</p>
+
+<pre class="brush: python">urlpatterns = [
+<strong> path('', views.index, name='index'),</strong>
+]</pre>
+
+<p>La fonction <code>path()</code> sert à définir les éléments suivants :</p>
+
+<ul>
+ <li>Un modèle d'URL qui, dans le cas présent, est une chaîne vide : <code>''</code>. Nous évoquerons ultérieurement les modèles d'URL plus en détail quand nous travaillerons les autres vues.</li>
+ <li>Une fonction du vue, ici <code>views.index</code>, qui sera sollicitée quand le modèle d'URL sera détecté et une fonction Python qui sera appelée pour traiter l'appel d'URL est présent dans le fichier <strong>views.py </strong>du module <code>catalog</code>.</li>
+</ul>
+
+<p>La paramètre <code>name</code> utilisé dans la fonction <code>path()</code> permet aussi de définir un identifiant unique qui sert à lier les pages vers celle-ci au sein de l'application. Vous pouvez alors l'utiliser à l'envers en routant dynamiquement des pages en lien vers cette ressource :</p>
+
+<pre class="brush: html">&lt;a href="<strong>{% url 'index' %}</strong>"&gt;Home&lt;/a&gt;.</pre>
+
+<div class="note">
+<p><strong>Note</strong>: Vus pourriez bien évidemment coder en dur l'accès à la page d'accueil de cette manaière <code>&lt;a href="<strong>/catalog/</strong>"&gt;Home&lt;/a&gt;</code>), mais si nous changions le modèle d'URL, par exemple en <code>/catalog/index</code>, alors le gabarit ne fonctionnerait plus correctement et présenterait un lien mort. L'utilisation des noms et des routage inversés est plus robuste et adapté aux évolutions de l'application.</p>
+</div>
+
+<h3 id="Vue_(View_function-based)">Vue (<em>View function-based</em>)</h3>
+
+<p>Une vue est une fonction qui traite une requête HTTP, extrait des données de la base de données et les restitue dans une page HTML à l'aide d'une réponse HTTPA que le navigateur mettra en forme pour l'utilisateur. La fonction <code>index()</code> suit ce modèle de traitement de l'information : elle extrait les informations sur le nombre de livres, d'ouvrage en rayon ou en prêt et d'auteur enregistrés dans la base de données et à l'aide d'un gabarit les publie.</p>
+
+<p>Editer le fichier <strong>catalog/views.py</strong>.Vous constaterez l'import de la fonction <a href="https://docs.djangoproject.com/en/2.1/topics/http/shortcuts/#django.shortcuts.render">render()</a> qui traite de la génération HTML en utilisat des garabits et des données : </p>
+
+<pre class="brush: python">from django.shortcuts import render
+
+# Create your views here.
+</pre>
+
+<p>Copiez les lignes ci-dessous dans le fichier :</p>
+
+<pre class="brush: python">from catalog.models import Book, Author, BookInstance, Genre
+
+def index(request):
+ """View function for home page of site."""
+
+ # Generate counts of some of the main objects
+ num_books = Book.objects.all().count()
+ num_instances = BookInstance.objects.all().count()
+
+ # Available books (status = 'a')
+ num_instances_available = BookInstance.objects.filter(status__exact='a').count()
+
+ # The 'all()' is implied by default.
+ num_authors = Author.objects.count()
+
+ context = {
+ 'num_books': num_books,
+ 'num_instances': num_instances,
+ 'num_instances_available': num_instances_available,
+ 'num_authors': num_authors,
+ }
+
+ # Render the HTML template index.html with the data in the context variable
+ return render(request, 'index.html', context=context)</pre>
+
+<p>La première ligne de code permet d'importer les modèles de données du catalogue décrites dans le module <code>catalog</code>.</p>
+
+<p>La première section de la fonction index() permet à l'aide de requêtes, par l'intermédiaire des objets de modèle de données, d'obtenir les nombres d'enregistrements. Pour cela, nous utilisons la méthode d'objet <em>models</em> <code>objects.all()</code> sur les objets <code>Book</code> et <code>BookInstance</code>. En sus, nous recherchons les ouvrages disponibles, ce qui revient à faire une requête avec un filtre sur l'attribut status de l'objet <code>BookInstance</code> ayant la valeur 'a' (Available). Si vous avez un oubli, vous pouvez consulter <a href="/fr/docs/Learn/Server-side/Django/Models#Rechercher_des_enregistrements">La section 3 de Django didactique : utilisation du modèle de données &gt; Chercher des enregistrements</a>.</p>
+
+<p>La dernière ligne de cette fonction est l'appel de la fonction <code>render()</code> dont l'objet est de constituer une page HTML et la transmettre comme une réponse. Cette fonction encapsule plusieurs autres fonctions du cadriciel ce qui permet de simplifier le processus de restitution des informations. La fonction <code>render()</code> utilise les paramètres :</p>
+
+<ul>
+ <li>La requête HTTP initiale <code>request</code> qui est un objet de type <code>HttpRequest</code>.</li>
+ <li>Un gabarit de page HTML avec des zones prédéfinies pour les données.</li>
+ <li>Un contexte de variables (<code>context)</code> qui est dictionnaire en Python, contenant les données à insérer dans le gabarit pour publier la page HTML. </li>
+</ul>
+
+<p>Nous aborderons plus en détail les aspects de gabarit et de contexte des variables dans le section suivante du didacticiel. Pour le moment, construisons un premier gabarit sans plus de précisions.</p>
+
+<h3 id="Gabarit_(Template)">Gabarit (<em>Template</em>)</h3>
+
+<p>Un gabarit est un fichier texte qui décrit la structure ou la mise en page d'un document (comme une page HTML) et qui utilise des emplacements réservés pour y insérer des informations issues de la base de données.</p>
+
+<p>La cadriciel Django va rechercher automatiquement ces gabarits dans un répertoire nommé '<strong>templates</strong>' dans le dossier de l'application. Si vous reprenez la dernière ligne de la de fonctions <code>index()</code> dans l'exemple ci-dessus, la fonction <code>render()</code> a besoin du fichier <em><strong>index.html</strong></em> qui devrait être placé dans le dossier<em> </em><strong>/locallibrary/catalog/templates/</strong>. Dans le cas contraire, cela génère une erreur car le fichier est considéré comme absent.</p>
+
+<p>Vous pouvez en faire l'expérience dès à présent, après avoir redémarré votre serveur local, en accédant à l'URL <code>127.0.0.1:8000</code> de votre navigateur. Une page d'erreur explicite s'affiche en indiquant un message du type : "<code>TemplateDoesNotExist at /catalog/</code>", ainsi que de nombreux détails sur l'enchaînement des fonctions aboutissant à cette erreur.</p>
+
+<div class="note">
+<p><strong>Note</strong>: En fonction du paramétrage de votre projet - le fichier settings.py de votre projet - Django va chercher pour des gabarits dans différents répertoires et dans ceux de votre application par défaut. Si vous souhaitez approfondir ce sujet vous pouvez consulter la <a href="https://docs.djangoproject.com/fr/2.2/topics/templates/">documentation Django relative aux gabarit</a>.</p>
+</div>
+
+<h4 id="Concevoir_les_gabarits">Concevoir les gabarits</h4>
+
+<p>Django utilise un langage de pour les gabarit qui permet de résoudre certains sujets liés au page HTML. En l'occurrence, dans le site web de la bibliothèque nous aurons des bandeaux de navigateur et autres codes d'en-tête à réutiliser. Dans une vision classique, il faudrait récrire dans chaque page le même code pour obtenir le même rendu. Si cela peut se concevoir pour quelques pages, ce procédé devient vite inopérant voir risqué avec un site dynamique complet.</p>
+
+<p>Le langage de gabarit de Django permet de définir un modèle de base puis de l'étendre ensuite. L'extrait de code ci-dessous vient du fichier de gabarit <strong>base_generic.html</strong>, vous constaterez qu'il s'y mélange du code HTML et des sections nommées contenu dans entre des marqueurs <code>block</code> et <code>endblock</code> qui peut contenir ou non des données.</p>
+
+<div class="note">
+<p><strong>Note</strong>: <span class="tlid-translation translation" lang="fr"><span title="">Les marqueurs de gabarits sont des fonctions que vous pouvez utiliser dans un modèle pour parcourir des listes, effectuer des opérations conditionnelles en fonction de la valeur d'une variable, etc.</span> <span title="">Outre les balises de modèle, la syntaxe de gabarit vous permet de référencer les variables qui sont transmises au modèle à partir de la vue et d'utiliser des filtres de gabarit pour mettre en forme les variables (par exemple, pour convertir une chaîne en minuscule).</span></span></p>
+</div>
+
+<p>Dans l'extrait ci-dessous vous avec trois sections nommées qui pourront être remplacés par la suite :</p>
+
+<ul>
+ <li>title : qui contiendra le titre (par défaut Bibliothèque locale)</li>
+ <li>sidebar : une barre de navigation latérale à gauche</li>
+ <li>content : le contenu de la page</li>
+</ul>
+
+<pre class="brush: html">&lt;!DOCTYPE html&gt;
+&lt;html lang="fr"&gt;
+&lt;head&gt;
+ <strong>{% block title %}</strong>&lt;title&gt;Bibliothèque locale&lt;/title&gt;<strong>{% endblock %}</strong>
+&lt;/head&gt;
+&lt;body&gt;
+ <strong>{% block sidebar %}</strong>&lt;!-- insert default navigation text for every page --&gt;<strong>{% endblock %}</strong>
+ <strong>{% block content %}</strong>&lt;!-- default content text (typically empty) --&gt;<strong>{% endblock %}</strong>
+&lt;/body&gt;
+&lt;/html&gt;
+</pre>
+
+<p>Lorsque l'on définit un gabarit pour une vue particulière, il convient de définir une base de gabarit et d'utiliser la balise <code>extends</code> dans une page complémentaire comme dans l'exemple ci-dessous.  Ensuite, il est nécessaire de préciser les sections qui seront modifiées en utilisant les balises <code>block</code>/<code>endblock</code> qui définissent le début et la fin de section.</p>
+
+<p>A titre indicatif, l'extrait ci-dessous présente la manière d'activer à l'aide de la balise <code>extends</code> le remplacement de la section <code>content</code>. La page HTML générée inclura la structure de la page définit plus haute et le code généré à la fois pour la section <code>title</code>, mais avec les éléments nouveaux, ci-dessous, pour la section <code>content</code>.</p>
+
+<pre class="brush: html">{% extends "base_generic.html" %}
+
+{% block content %}
+ &lt;h1&gt;Accueil de la bibliothèque locale&lt;/h1&gt;
+ &lt;p&gt;Bienvenue sur la bibliothèque locale, un site web développé par &lt;em&gt;Mozilla Developer Network&lt;/em&gt;!&lt;/p&gt;
+{% endblock %}</pre>
+
+<h4 id="Le_gabarit_de_base_de_la_bibliothèque">Le gabarit de base de la bibliothèque</h4>
+
+<p>Nous allons nous appuyer sur le gabarit ci-dessous pour constuire la page de base de la bibliothèque locale. Vous le constatez, il contient des éléments HTML et des blocs dédiés Django pour spécifier trois sections <code>title</code>, <code>sidebar</code>, et <code>content</code>. La section <code>title</code> contient un titre par défaut. De même la section <code>sidebar</code> contient un liens vers la liste des livres et des auteurs qui pourra être modifié ensuite.</p>
+
+<div class="note">
+<p><strong>Note</strong>: Il y a aussi deux balises supplémentaires : <code>url</code> et <code>load static</code>. Elles seront étudiées dans le chapitre suivant.</p>
+</div>
+
+<p>Créez un nouveau fichier nommé <strong><em>base_generic.html </em></strong>dans le dossier <strong>/locallibrary/catalog/templates/</strong> (à créer aussi) et copiez-y le texte ci-dessous :</p>
+
+<pre class="brush: html">&lt;!DOCTYPE html&gt;
+&lt;html lang="en"&gt;
+&lt;head&gt;
+ {% block title %}&lt;title&gt;Bibliothèque locale&lt;/title&gt;{% endblock %}
+ &lt;meta charset="utf-8"&gt;
+ &lt;meta name="viewport" content="width=device-width, initial-scale=1"&gt;
+ &lt;link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous"&gt;
+ &lt;!-- Add additional CSS in static file --&gt;
+ {% load static %}
+ &lt;link rel="stylesheet" href="{% static 'css/styles.css' %}"&gt;
+&lt;/head&gt;
+&lt;body&gt;
+ &lt;div class="container-fluid"&gt;
+ &lt;div class="row"&gt;
+ &lt;div class="col-sm-2"&gt;
+ {% block sidebar %}
+ &lt;ul class="sidebar-nav"&gt;
+ &lt;li&gt;&lt;a href="{% url 'index' %}"&gt;Home&lt;/a&gt;&lt;/li&gt;
+ &lt;li&gt;&lt;a href=""&gt;Tous les livres&lt;/a&gt;&lt;/li&gt;
+ &lt;li&gt;&lt;a href=""&gt;Tous les auteurs&lt;/a&gt;&lt;/li&gt;
+ &lt;/ul&gt;
+ {% endblock %}
+ &lt;/div&gt;
+ &lt;div class="col-sm-10 "&gt;
+ {% block content %}
+ {% endblock %}
+ &lt;/div&gt;
+ &lt;/div&gt;
+ &lt;/div&gt;
+&lt;/body&gt;
+&lt;/html&gt;</pre>
+
+<p>Ce gabarit fait appel - <em>en ligne 7</em> - à la bibliothèque de style <a href="http://getbootstrap.com/">Bootstrap</a> afin d'améliorer la présentation de la page. L'utilisation de Bootstrap (ou de tout autre cadriciel pour les pages web) est un moyen rapide de créer des pages bien organisées et qui s'affiche très bien sur les différents navigateurs.</p>
+
+<p>De même, ce gabarit fait appel à une feuille de style - <em>en ligne 10</em> - locale pour ajouter ou adapter des styles. Créez le fichier <strong>styles.css </strong>dans le répertoire <strong>/locallibrary/catalog/static/css/</strong> (à créer aussi) et copiez le contenu ci-dessous :</p>
+
+<pre class="brush: css">.sidebar-nav {
+ margin-top: 20px;
+ padding: 0;
+ list-style: none;
+}</pre>
+
+<h4 id="La_page_d'accueil">La page d'accueil</h4>
+
+<p>Maintenant créez le fichier HTML <strong><em>index.html</em></strong> dans le dossier <strong>/locallibrary/catalog/templates/</strong> et copiez-y le code ci-dessous. This code extends our base template on the first line, and then replaces the default <code>content</code> block for the template. </p>
+
+<pre class="brush: html line-numbers language-html"><code class="language-html">{% extends "base_generic.html" %}
+
+{% block content %}
+ <span class="tag token"><span class="tag token"><span class="punctuation token">&lt;</span>h1</span><span class="punctuation token">&gt;</span></span>Accueil de la bibliothèque locale<span class="tag token"><span class="tag token"><span class="punctuation token">&lt;/</span>h1</span><span class="punctuation token">&gt;</span></span>
+ <span class="tag token"><span class="tag token"><span class="punctuation token">&lt;</span>p</span><span class="punctuation token">&gt;</span><span class="tag token"><span class="punctuation token">Bienvenue à la bibliothèque locale, un site web développé par </span></span></span></code><code class="language-html"><span class="tag token"><span class="tag token"><span class="punctuation token">&lt;</span>em</span><span class="punctuation token">&gt;</span></span>Mozilla Developer Network<span class="tag token"><span class="tag token"><span class="punctuation token">&lt;/</span>em</span><span class="punctuation token">&gt;</span></span>!</code><code class="language-html"><span class="tag token"><span class="tag token"><span class="punctuation token">&lt;/</span>p</span><span class="punctuation token">&gt;</span></span>
+ <span class="tag token"><span class="tag token"><span class="punctuation token">&lt;</span>h2</span><span class="punctuation token">&gt;</span></span>Contenu dynamique<span class="tag token"><span class="tag token"><span class="punctuation token">&lt;/</span>h2</span><span class="punctuation token">&gt;</span></span>
+ <span class="tag token"><span class="tag token"><span class="punctuation token">&lt;</span>p</span><span class="punctuation token">&gt;</span></span>La bibliothèque dispose des enregistrements suivants:<span class="tag token"><span class="tag token"><span class="punctuation token">&lt;/</span>p</span><span class="punctuation token">&gt;</span></span>
+ <span class="tag token"><span class="tag token"><span class="punctuation token">&lt;</span>ul</span><span class="punctuation token">&gt;</span></span>
+ <span class="tag token"><span class="tag token"><span class="punctuation token">&lt;</span>li</span><span class="punctuation token">&gt;</span></span><span class="tag token"><span class="tag token"><span class="punctuation token">&lt;</span>strong</span><span class="punctuation token">&gt;Livres</span></span>:<span class="tag token"><span class="tag token"><span class="punctuation token">&lt;/</span>strong</span><span class="punctuation token">&gt;</span></span> <strong>\{{ num_books }}</strong><span class="tag token"><span class="tag token"><span class="punctuation token">&lt;/</span>li</span><span class="punctuation token">&gt;</span></span>
+ <span class="tag token"><span class="tag token"><span class="punctuation token">&lt;</span>li</span><span class="punctuation token">&gt;</span></span><span class="tag token"><span class="tag token"><span class="punctuation token">&lt;</span>strong</span><span class="punctuation token">&gt;</span></span>Copies:<span class="tag token"><span class="tag token"><span class="punctuation token">&lt;/</span>strong</span><span class="punctuation token">&gt;</span></span> <strong>\{{ num_instances }}</strong><span class="tag token"><span class="tag token"><span class="punctuation token">&lt;/</span>li</span><span class="punctuation token">&gt;</span></span>
+ <span class="tag token"><span class="tag token"><span class="punctuation token">&lt;</span>li</span><span class="punctuation token">&gt;</span></span><span class="tag token"><span class="tag token"><span class="punctuation token">&lt;</span>strong</span><span class="punctuation token">&gt;</span></span>Copies disponibles:<span class="tag token"><span class="tag token"><span class="punctuation token">&lt;/</span>strong</span><span class="punctuation token">&gt;</span></span> <strong>\{{ num_instances_available }}</strong><span class="tag token"><span class="tag token"><span class="punctuation token">&lt;/</span>li</span><span class="punctuation token">&gt;</span></span>
+ <span class="tag token"><span class="tag token"><span class="punctuation token">&lt;</span>li</span><span class="punctuation token">&gt;</span></span><span class="tag token"><span class="tag token"><span class="punctuation token">&lt;</span>strong</span><span class="punctuation token">&gt;</span></span>Auteurs:<span class="tag token"><span class="tag token"><span class="punctuation token">&lt;/</span>strong</span><span class="punctuation token">&gt;</span></span> <strong>\{{ num_authors }}</strong><span class="tag token"><span class="tag token"><span class="punctuation token">&lt;/</span>li</span><span class="punctuation token">&gt;</span></span>
+ <span class="tag token"><span class="tag token"><span class="punctuation token">&lt;/</span>ul</span><span class="punctuation token">&gt;</span></span>
+{% endblock %}</code></pre>
+
+<p>Dans la section cont'enu dynamique, des emplacements réservés sont définis pour pouvoir y insérer le contenu de variable qui sont identifiées à l'intérieur de doubles accolades (ouvrantes et fermantes). Pour une meilleure visibilité ces emplacements et les variables nommées sont identifiées en caractères gras dans l'extrait de code ci-dessus. </p>
+
+<div class="note">
+<p><strong>Note:</strong> Vous pouvez constatez simplement que les balises de gabarit (fonctions) et les baslises de variables sont entre accolades ; double accolades pour uen variable (<code>\{{ num_books }}</code>), et simple accolade avec le pourcentage (<code>{% extends "base_generic.html" %}</code>) pour les balises.</p>
+</div>
+
+<p>Gardez en mémoire que les variables utilisées dans les gabarits sont des clés d'un dictionnaires <code>context</code> transmis à la fonction <code>render()</code> de la vue (revenez à l'exemple plus haut, ou l'extrait ci-dessous). La fonction <code>render()</code> traitera le dictionnaire pour restituer uen page HTML où les variables nommées auront été remplacées par leur valeur dans le dictionnaire.</p>
+
+<pre class="brush: python">context = {
+ '<strong>num_books</strong>': num_books,
+ '<strong>num_instances</strong>': num_instances,
+ '<strong>num_instances_available</strong>': num_instances_available,
+ '<strong>num_authors</strong>': num_authors,
+}
+
+return render(request, 'index.html', context=context)</pre>
+
+<h4 id="Traiter_les_fichiers_statiques_dans_les_gabarits">Traiter les fichiers statiques dans les gabarits</h4>
+
+<p>Vos projets utiliserons probablement de fichiers statiques, par exemple des images, des fichiers de styles CSS ou des fonctions javascripts. L'emplacement de ces fichiers n'est pas connu a priori ou peut changer en fonction de l'emplacement dans un projet Django. Pour cela, Django vous permet de spécifier les emplacements dans les gabarits par rapport à la variable globale du projet <code>STATIC_URL</code>. Le paramétrage par défaut du site web définit la variable <code>STATIC_URL</code> à '<code>/static/</code>', mais vous pouvez choisir d'heberger ailleurs.</p>
+
+<p>Au sein du gabarit, vous ferrez appel à la balise <code>load</code> en précisant "static" pour faire votre ajout, comme décrits dans l'extrait ci-dessous. Vous utilisez la balise <code>static</code> et vous spécifiez ensuite l'URL pour accéder au fichier nécessaire.</p>
+
+<pre class="brush: html">&lt;!-- Add additional CSS in static file --&gt;
+{% load static %}
+&lt;link rel="stylesheet" href="{% static 'css/styles.css' %}"&gt;</pre>
+
+<p>De la même manière, vous pouvez par exemple :</p>
+
+<pre class="brush: html">{% load static %}
+&lt;img src="{% static 'catalog/images/local_library_model_uml.png' %}" alt="UML diagram" style="width:555px;height:540px;"&gt;
+</pre>
+
+<div class="note">
+<p><strong>Note</strong>: Les exemples ci-dessus indiquent où se trouvent les fichiers, mais le cadriciel ne travail pas ainsi par défaut. Nous avons configuré le serveur web de développement en modifiant le routage des URL (<strong>/locallibrary/locallibrary/urls.py</strong>) à <a href="/fr/docs/Learn/Server-side/Django/skeleton_website">la création du squelette du site</a>. Cependant nous devrons travailler plus tard la mise en production.</p>
+</div>
+
+<p>Pour plus de détails sur les fichiers statiques vous pouvez consulter la documentation Django sur <a href="https://docs.djangoproject.com/fr/2.2/howto/static-files/">la gestion des fichiers statiques</a>.</p>
+
+<h4 id="Associer_des_URL">Associer des URL</h4>
+
+<p>L'exemple ci-dessous introduit l'utilisation de la balise de gabarit <code>url</code>.</p>
+
+<pre class="brush: python">&lt;li&gt;&lt;a href="{% url 'index' %}"&gt;Home&lt;/a&gt;&lt;/li&gt;
+</pre>
+
+<p>Cette balise accepte des référence enregistrées par la fonction <code>path()</code> appelée dans les fichiers  <strong>urls.py</strong> ainsi que les valeurs pour chacun des arguments associés à une vue. Elle retourne une URL qui peut être utilisée pour lier une ressource.</p>
+
+<h4 id="Où_trouver_les_gabarits...">Où trouver les gabarits...</h4>
+
+<p>Par défaut Django ne sait pas où sont vos gabarits, vous devez lui indiquer où les trouver. Pour faire cela, vous allez ajouter le répertoire des gabarits (templates) à la variable d'environnemet du projet TEMPLATES en éditant le fichier <strong>settings.py</strong> comme indiqué en gras ci-dessous :</p>
+
+<pre class="brush: python">TEMPLATES = [
+    {
+        'BACKEND': 'django.template.backends.django.DjangoTemplates',
+        'DIRS': [
+<strong>            os.path.join(BASE_DIR, 'templates'),
+</strong>        ],
+        'APP_DIRS': True,
+        'OPTIONS': {
+            'context_processors': [
+                'django.template.context_processors.debug',
+                'django.template.context_processors.request',
+                'django.contrib.auth.context_processors.auth',
+                'django.contrib.messages.context_processors.messages',
+            ],
+        },
+    },
+]</pre>
+
+<h2 id="A_quoi_cela_devrait-il_ressembler">A quoi cela devrait-il ressembler ?</h2>
+
+<p>A ce niveau, nous avons créé l'ensemble des ressources nécessaires à l'affichage de la page d'accueil. Démarrez le serveur (<code>python3 manage.py runserver</code>) et accédez avec votre navigateur à la page d'accueil du site web <a href="http://127.0.0.1:8000/">http://127.0.0.1:8000/</a>. Si tout va bien, vous devriez avoir une page qui ressemble à celle ci-dessous.</p>
+
+<p><img alt="Page d'accueil en Français" src="https://mdn.mozillademos.org/files/16794/index_fr_page_ok.png" style="height: 1050px; width: 1872px;"></p>
+
+<div class="note">
+<p><strong>Note:</strong> Toutes les ressources n'ayant pas été encore créées les liens vers Tous les livres et Tous les auteurs ne fonctionnent pas encore.</p>
+</div>
+
+<h2 id="Défi">Défi</h2>
+
+<p>Voici deux suggestion pour tester votre connaissance de Django et des requêtes, vues et gabarits :</p>
+
+<ol>
+ <li>La bibliothèque locale dispose d'un gabarit d'origine qui inclu une section <code>title</code>. Surchargez cette section dans le gabarit index et créer un nouveau titre.
+
+ <div class="note">
+ <p><strong>Hint:</strong> La section Concevoir un gabarit détaille la manière de modifier une section.</p>
+ </div>
+ </li>
+ <li>Modifiez la vue pour disposer de décomptes pour les genres et les titres de livre qui contiennent un mot (en repectant la casse) et transmettez cela via le  <code>context.</code> Pour faire cela utilisez les variables <code>num_books</code> et <code>num_instances_available</code>. Ensuite vous pourrez mettre à jour le gabarit de la page d'accueil.<br>
+  </li>
+</ol>
+
+<ul>
+</ul>
+
+<h2 id="Résumé">Résumé</h2>
+
+<p>Dans ce chapitre, nous avons créé la page d'accueil pour notre site — une page web dynamique qui affiche le décompte d'enregistrements issus de la base de données et des liens vers des pages encire à créer. Au cours des étapes de création, nous avons appris et découvert des concept fondamentaux à propos du routage d'url, des vues des requêtes à la base de données et le passage de données vers les gabarits ainsi que leur conception.</p>
+
+<p>Nous allons nous appuyer sur ces éléments pour concevoir dans le prochain chapitres les 4 pages qui manquent.</p>
+
+<h2 id="À_voir_aussi">À voir aussi</h2>
+
+<ul>
+ <li><a href="https://docs.djangoproject.com/fr/2.2/intro/tutorial03/">Ecrire sa première application Django, 3ème partie</a>  (Django docs)</li>
+ <li><a href="https://docs.djangoproject.com/fr/2.2/topics/http/urls/">Distribution des URL</a> (Django docs)</li>
+ <li><a href="https://docs.djangoproject.com/fr/2.2/topics/http/views/">Ecriture des vues</a> (DJango docs)</li>
+ <li><a href="https://docs.djangoproject.com/fr/2.é/topics/templates/">Gabarits</a> (Django docs)</li>
+ <li><a href="https://docs.djangoproject.com/fr/2.2/howto/static-files/">Gestion des fichiers statiques</a> (Django docs)</li>
+ <li><a href="https://docs.djangoproject.com/fr/2.2/topics/http/shortcuts/#django.shortcuts.render">Fonctions raccourcis de Django</a> (Django docs)</li>
+</ul>
+
+<p>{{PreviousMenuNext("Learn/Server-side/Django/Admin_site", "Learn/Server-side/Django/Generic_views", "Learn/Server-side/Django")}}</p>
+
+<h2 id="Dans_ce_module">Dans ce module</h2>
+
+<ul>
+ <li><a href="/fr/docs/Learn/Server-side/Django/Introduction">Django introduction</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/development_environment">Setting up a Django development environment</a></li>
+ <li><a href="/fr/docs/Learn/Server-side/Django/Tutorial_local_library_website">Django Didactique: Site web "Bibliothèque locale"</a></li>
+ <li><a href="/fr/docs/Learn/Server-side/Django/skeleton_website">Django didactique Section 2: Créer le squelette du site web</a></li>
+ <li><a href="/fr/docs/Learn/Server-side/Django/Models">Django didactique Section 3: Utilisation des modèles de données</a></li>
+ <li><a href="/fr/docs/Learn/Server-side/Django/Admin_site">Django didactique Section 4 : Site d'administration de Django</a></li>
+ <li><a href="/fr/docs/Learn/Server-side/Django/Home_page">Django didactique Section 5: Créer la page d'accueil</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Generic_views">Django Tutorial Part 6: Generic list and detail views</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Sessions">Django Tutorial Part 7: Sessions framework</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Authentication">Django Tutorial Part 8: User authentication and permissions</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Forms">Django Tutorial Part 9: Working with forms</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Testing">Django Tutorial Part 10: Testing a Django web application</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Deployment">Django Tutorial Part 11: Deploying Django to production</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/web_application_security">Django web application security</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/django_assessment_blog">DIY Django mini blog</a></li>
+</ul>
diff --git a/files/fr/learn/server-side/django/index.html b/files/fr/learn/server-side/django/index.html
new file mode 100644
index 0000000000..c613f07883
--- /dev/null
+++ b/files/fr/learn/server-side/django/index.html
@@ -0,0 +1,65 @@
+---
+title: Django Web Framework (Python)
+slug: Learn/Server-side/Django
+tags:
+ - Apprendre
+ - Débutant
+ - Python
+ - django
+translation_of: Learn/Server-side/Django
+---
+<div>{{LearnSidebar}}</div>
+
+<p>Django est une infrastructure d'application (aussi appelé framework) côté serveur extremement populaire et dotée de beaucoup de fonctionnalités, écrite en Python. Ce module vous montrera pourquoi Django fait partie des frameworks web les plus populaires ainsi que comment l'installer, le mettre en place, et s'en servir afin de créer vos propres applications web.</p>
+
+<h2 id="Prerequis">Prerequis</h2>
+
+<p>Aucune connaissance sur ce framework n'est requise. Il vous faudra seulement comprendre ce qu'est la programmation web côté serveur ainsi que les frameworks web, notamment en lisant les sujets sur notre <a href="https://developer.mozilla.org/fr/docs/Learn/Server-side/First_steps">module d'initiation à la programmation web coté serveur</a>.</p>
+
+<p>Une connaissance générale en programmation et plus précisement en <a href="https://developer.mozilla.org/fr/docs/Glossaire/Python">Python</a> est recommandée, mais pas nécessaire pour comprendre la majeure partie de ce module.</p>
+
+<div class="note">
+<p><strong>Note</strong>: Python est un des languages les plus faciles à apprendre, lire et comprendre pour les novices. Ceci dit, si vous voulez mieux comprendre ce module, il existe beaucoup de livres gratuits et de tutoriaux sur internet (les nouveaux programmeurs pourraient être intéressés par la page du<a href="https://wiki.python.org/moin/BeginnersGuide/NonProgrammers"> Python pour les non-programmeurs</a> <sub><strong>(anglais)</strong></sub> dans la documentation sur le site officiel de Python: python.org).</p>
+</div>
+
+<h2 id="Guides">Guides</h2>
+
+<dl>
+ <dt><a href="/en-US/docs/Learn/Server-side/Django/Introduction">Introduction à Django<sub><strong> </strong></sub></a><sub><strong>(anglais)</strong></sub></dt>
+ <dd>Dans ce premier article, nous répondrons aux questions "qu'est ce que Django ?" et vous donner un aperçu rapide de ce qu'un framework peut vous apporter. Nous survolerons les fonctionnalités principales ainsi que quelques fonctionnalités avancées que nous ne pouvons pas détailler en l'espace d'un seul module.  Nous vous montrerons aussi les blocs principaux de Django ce qui vous donnera un aperçu de ce qui est faisable avant de commencer.</dd>
+ <dt><a href="/en-US/docs/Learn/Server-side/Django/development_environment">Installer un environnement de développement pour Django </a><sub><strong>(anglais)</strong></sub></dt>
+ <dd>Maintenant que vous savez ce qu'est Django, nous allons nous attaquer à la partie installation, comment l'installer sous Windows, Linux(Ubuntu),  et Mac OS X — tant que vous utilisez un système d'exploitation commun, cet article devrait vous donner le nécessaire afin de commencer à développer des applications avec Django.</dd>
+ <dt><a href="/fr/docs/Learn/Server-side/Django/Tutorial_local_library_website">Tutoriel Django: Le site web d'une librairie</a></dt>
+ <dd>Le premier article de cette série de tutoriels explique ce que vous aurez à apprendre autour d'un site que nous allons programmer pour une bibliothèque, site web dans lequel nous allons travailler et évoluer à travers plusieurs articles.</dd>
+ <dt><a href="/fr/docs/Learn/Server-side/Django/skeleton_website">Tutoriel Django Partie 2: Créer un squelette d'un site web</a></dt>
+ <dd>Cet article vous montrera comment créer le "squelette" d'un site web auquel vous pourrez ajouter de quoi le personnaliser avec des paramètres spécifiques, des URLs, des modèles et des templates.</dd>
+ <dt><a href="/fr/docs/Learn/Server-side/Django/Models">Tutoriel Django Partie 3: Utilisation des modèles</a></dt>
+ <dd>Cet article montre comment définir des modèles pour le site web que nous appelleront <em>LocalLibrary </em> — les modèles représentent la façon dont sont structurées nos données dans nos applications, nous autoriserons aussi Django à stocker des données dans une base de données pour nous (et modifier cela plus tard). Cet article explique en somme ce qu'un modèle est, comment le déclarer et les champs principaux. Il décrit aussi brièvement comment accéder aux données d'un modèle.</dd>
+ <dt><a href="/fr/docs/Learn/Server-side/Django/Admin_site">Tutoriel Django Partie 4: L'administration d'un site sous Django</a></dt>
+ <dd>Maintenant que nous avons créé quelques modèles pour le site web <em>LocalLibrary </em>, nous allons utiliser Django Admin afin d'ajouter quelques "réelles" tables de données. Premièrement, nous allons vous montrer comment enregistrer des modèles avec la partie Admin, ensuite nous allons vous montrer comment se connecter et créer des informations. A la fin, nous allons vous montrer quelques moyens d'améliorer la présentation de la partie Admin.</dd>
+ <dt><a href="/en-US/docs/Learn/Server-side/Django/Home_page">Tutoriel Django Partie 5: Céez votre page d'accueil. </a><sub><strong>(anglais)</strong></sub></dt>
+ <dd>Nous sommes fin prêts à ajouter le code afin d'afficher notre première page entièremement — une page d'accueil pour le site web <em>LocalLibrary </em>qui montre combien d'enregistrements nous avons de chaque types de modèles et fournis une barre de navigation avec des liens menant à d'autres pages. Au fur et à mesure, nous gagnerons de l'expérience en écrivant du mapping d'URLs, en obtenant des enregistrements de la base de données et en utilisant des templates.</dd>
+ <dt><a href="/en-US/docs/Learn/Server-side/Django/Generic_views">Tutoriel Django Partie 6: Listes génériques et détails des pages </a><sub><strong>(anglais)</strong></sub></dt>
+ <dd>Ce tutoriel viens étendre notre site <em>LocaLibrary</em> en y ajoutant des listes et des détails pour les auteurs et les livres. Ici nous allons tout vous apprendre sur les classes et vous montrer comment elles peuvent réduire la quantité de code que vous avez à écrire dans des situations communes. Nous allons aussi vous apprendre comment manipuler les URL plus en détail, ainsi que la réalisation basique d'un moteur de recherche.</dd>
+ <dt><a href="/en-US/docs/Learn/Server-side/Django/Sessions">Tutoriel Django Partie 7: Les sessions de framework </a><sub><strong>(anglais)</strong></sub></dt>
+ <dd>Ce tutoriel viens compléter le site <em>LocalLibrary</em>, en ajoutant un compteur de visiteurs basé sur un principe de session sur la page principale C'est un exemple relativement simple, mais il vous permettra de vous apprendre comment utiliser le système de session en fournissant un comportement persistant aux utilisateurs anonyme de votre site.</dd>
+ <dt><a href="/en-US/docs/Learn/Server-side/Django/Authentication">Tutoriel Django Partie 8: L'authentification de l'utilisateur ainsi que les permissions </a><sub><strong>(anglais)</strong></sub></dt>
+ <dd>Dans ce tutoriel, nous allons vous montrer comment autoriser les utilisateurs à se connecter à votre site avec leurs propres comptes, et comment contrôler ce qu'ils peuvent faire et voir en fonction des <em>permissions</em> accordées et de s'ils sont connectés ou non. Comme partie de cette démonstration, nous allons étendre le site <em>LocalLibrary</em> en ajoutant une page de connexion, de déconnexion et d'utilisateur - ainsi que des pages dédiées aux membres de la librairie afin de voir quel livre a été emprunté.</dd>
+ <dt><a href="/en-US/docs/Learn/Server-side/Django/Forms">Tutoriel Django Partie 9: Travailler avec les formulaires </a><sub><strong>(anglais)</strong></sub></dt>
+ <dd>Dans ce tutoriel, nous allons vous montrer comment travailler avec <a href="https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Forms">les formulaires en HTML</a> avec Django, et plus particulièrement la façon la plus facile d'écrire, créer, mettre à jour et supprimer les formulaires. Pour cela, nous allons devoir étendre le site <em>LocalLibrary</em> afin que les libraires puissent changer les livres, et créer, mettre à jour, et supprimer les auteurs en utilisant nos propres formulaires (au lieu de passer par Django Admin).</dd>
+ <dt><a href="/en-US/docs/Learn/Server-side/Django/Testing">Tutoriel Django Partie 10: Tester une application Django </a><sub><strong>(anglais)</strong></sub></dt>
+ <dd>Plus les sites s'agrandissent, plus il devient dur de les tester manuellement — pas seulement parce que il y a plus de contenu à tester mais aussi parce que les intéractions entre les éléments deviennent plus complexes, un petit changement dans une partie du site peut nécessiter de nombreux tests afin de vérifier que ce changement n'a pas impacté les autres parties du site. La solution à ce problème est de programmer des tests automatiques, qui peuvent facilement et fiablement être executés à chaque changements. Ce tutoriel montre comment automatiser vos tests sur votre site web en utilisant le module de test du framework Django.</dd>
+ <dt><a href="/en-US/docs/Learn/Server-side/Django/Deployment">Tutoriel Django Partie 11: Déployer son site fait avec Django </a><sub><strong>(anglais)</strong></sub></dt>
+ <dd>Vous avez créé (et testé) un incroyable site web <em>LocalLibray</em>, vous allez maintenant l'installer sur un serveur public ce qui le rendra accessible aux membres de la librairie à travers internet. Cet article fournis un aperçu de comment vous pourriez trouver un hébergeur pour déployer votre site et de ce dont vous avez besoin pour rendre votre site pleinement fonctionnel.</dd>
+ <dt><a href="/en-US/docs/Learn/Server-side/Django/web_application_security">Le module de sécurité de Django </a><sub><strong>(anglais)</strong></sub></dt>
+ <dd>Protéger les données de l'utilisateur est essentiel dans la conception d'un site web, nous avons précédemment expliqué quel pouvaient être les menaces principales dans l'article sur la <a href="https://developer.mozilla.org/en-US/docs/Web/Security">sécurité web</a>  — cet article fournis une démonstration pratique des réaction des protections incluse de Django face à ce genre de menaces ainsi que la façon dont elles sont traitées.</dd>
+</dl>
+
+<h2 id="Evaluation">Evaluation</h2>
+
+<p>L'évaluation suivante va tester votre compréhension à créer un site web avec Django comme décris dans la liste des guides ci-dessous.</p>
+
+<dl>
+ <dt><a href="/en-US/docs/Learn/Server-side/Django/django_assessment_blog">Mini blog avec Django </a><sub><strong>(anglais)</strong></sub></dt>
+ <dd>Dans ce devoir, vous utiliserez les connaissances que vous venez d'acquérir, afin de créer votre propre blog.</dd>
+</dl>
diff --git a/files/fr/learn/server-side/django/introduction/index.html b/files/fr/learn/server-side/django/introduction/index.html
new file mode 100644
index 0000000000..d4938e0610
--- /dev/null
+++ b/files/fr/learn/server-side/django/introduction/index.html
@@ -0,0 +1,277 @@
+---
+title: Introduction à Django
+slug: Learn/Server-side/Django/Introduction
+tags:
+ - Débutant
+ - Python
+ - django
+translation_of: Learn/Server-side/Django/Introduction
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{NextMenu("Learn/Server-side/Django/development_environment", "Learn/Server-side/Django")}}</div>
+
+<p class="summary"><span class="seoSummary">Dans ce premier article sur Django, nous allons répondre à la question suivante "Qu'est ce que Django ?", et nous vous montrerons en quoi cette infrastructure d'application (aussi appelée framework) est spéciale. Nous allons ensuite voir les principales fonctionnalités, mais aussi quelques fonctionnalités avancées que nous n'aurons malheureusement pas le temps de voir en détails dans ce module. Nous allons aussi vous montrer comment fonctionne une application Django (bien que nous n'ayons pas d'environnement où le tester) </span>.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Prérequis:</th>
+ <td>Connaissances basiques de programmation. Une compréhension générale de la <a href="https://developer.mozilla.org/fr/docs/Learn/Server-side/First_steps">programmation coté serveur</a> ainsi qu'une <a href="/en-US/docs/Learn/Server-side/First_steps/Client-Server_overview">compréhension des interactions client-serveur dans les sites web</a> <strong><sub>(anglais)</sub></strong>.</td>
+ </tr>
+ <tr>
+ <th scope="row">Objectif:</th>
+ <td>Se familiariser avec Django en comprenant ce que c'est, les fonctionnalités qu'il fournit ainsi que les blocs de construction principaux d'une application Django.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Quest_ce_que_Django">Qu'est ce que Django?</h2>
+
+<p>Django est un framework Python de haut niveau, permettant un développement rapide de sites internet, sécurisés, et maintenables. Créé par des développeurs experimentés, Django prend en charge la plupart des tracas du développement web, vous pouvez donc vous concentrer sur l'écriture de votre application sans avoir besoin de réinventer la roue. Il est gratuit, open source, a une communauté active, une bonne documentation, et plusieurs options pour du support gratuit ou non. </p>
+
+<p>Django vous aide à écrire une application qui est:</p>
+
+<dl>
+ <dt>Complète</dt>
+ <dd>Django suit la philosophie "Piles incluses" et fournit presque tout ce que les développeurs pourraient vouloir faire. Comme tout ce dont vous avez besoin est une partie de ce "produit", tout fonctionne parfaitement ensemble, suivant des principes de conception cohérents, il possède également une <a href="https://docs.djangoproject.com/en/2.0/">documentation complète </a>et à jour.</dd>
+ <dt>Polyvalent</dt>
+ <dd>Django peut être (et a été) utilisé pour créer presque tous les genres de sites — du gestionnaire de données aux wikis, jusqu'aux réseaux sociaux et aux sites d'actualités. Il peut fonctionner avec n'importe quelle infrastructure côté client, et peut renvoyer des données dans quasiment n'importe quel format (notamment HTML, RSS, JSON, XML, etc). Le site sur lequel vous lisez en ce moment est basé sur Django!<br>
+ <br>
+ Tandis qu'il fournit presque toutes les fonctionnalités dont vous pourriez avoir besoin (comme des base de données populaires, des moteurs de modélisation, etc.), il peut tout de même être étendu pour utiliser d'autres composants si besoin.</dd>
+ <dt>Sécurisé</dt>
+ <dd>Django aide les développeurs à éviter les erreurs de sécurité classique en fournissant une infrastructure conçue pour "faire ce qu'il faut" pour protéger les sites internet automatiquement. Par exemple, Django fournit un moyen sécurisé pour gérer les comptes des utilisateurs ainsi que leurs mots de passe, évitant les erreurs classiques comme mettre des informations sur la session dans des cookies, où elles sont vulnérables (à la place les cookies contiennent seulement une clé, et les données sont stockées dans la base de données), ou directement stocker des mots de passe, au lieu de mot de passe hachés.<br>
+ <br>
+ <em>Un mot de passé haché est une valeur dont la longueur est fixée, créée en envoyant le mot de passe à travers une <a href="https://en.wikipedia.org/wiki/Cryptographic_hash_function">fonction de hachage cryptographique</a>. Django peut vérifier si un mot de passe entré est correct en l'envoyant dans la fonction de hachage et en comparant le retour avec la valeur stockée dans la base de données. De ce fait, la nature unidirectionnelle de la fonction rend difficile pour un attaquant de retrouver le mot de passe d'origine, même si la valeur hachée est compromise.</em><br>
+ <br>
+ Django active par défaut la protection contre beaucoup de vulnérabilités, comme les injections SQL, le cross-site scripting, le cross-site request forgery et le clickjacking (voir <a href="/en-US/docs/Learn/Server-side/First_steps/Website_security">Website security</a> pour plus de détails sur ce genre d'attaques).</dd>
+ <dt>Scalable</dt>
+ <dd>Django utilise une architecture composite "shared-nothing" (chaque composant de l'architecture est indépendant des autres, et peut ainsi être remplacé ou changé si besoin). En ayant des séparations nettes entres les différentes parties, Django peut se scaler lors d'une hausse de trafic en ajoutant du hardware à tous les niveaux : serveurs cache, serveurs de base de données, serveurs d'application. Certains des sites les plus fréquentés ont réussi à scaler Django pour répondre à leur demande (par exemple, Instagram et Disqus pour ne nommer qu'eux deux).</dd>
+ <dt>Maintenable</dt>
+ <dd>Les principes de design du code Django encouragent la création d'un code simple à maintenir et réutilisable. Il fait notamment appel à la philosophie du Ne Vous Répétez Pas (DRY pour Don't Repeat Yourself en anglais), afin d'éviter toute duplication superflue, réduisant la taille de votre code. Django promeut aussi le regroupement de fonctionnalités reliées entre elles en "applications" réutilisables et, à un plus bas niveau, regroupe des lignes de code dépendantes entre elles en modules (suivant les lignes du motif d'architecture Modèle-vue-contrôleur (MVC)).</dd>
+ <dt>Portable</dt>
+ <dd>Django est écrit en Python, qui fonctionne sous diverses plateformes. Cela veut dire que vous ne serez plus contraint par une plateforme en particulier, et vous pourrez faire fonctionner vos applications sous autant de versions de Linux, Windows et Mac OS X que vous le souhaitez. De plus, Django est très bien supporté par plusieurs fournisseurs d'hébergement web, qui offrent souvent des infrastructures et de la documentation spécifiques pour héberger des sites Django.</dd>
+</dl>
+
+<h2 id="Doù_vient-il">D'où vient-il ?</h2>
+
+<p>À l'origine, Django fut développé entre 2003 et 2005 par une équipe web responsable de la création et de la maintenance de sites journalistiques. Après avoir créé un certain nombre de sites, l'équipe commença à exclure et à réutiliser des codes récurrents et des schémas d'architecture. Ce code récurrent finit par évoluer en un framework générique de développement web, qui fut mis à disposition en open-source sous le projet "Django" en Juillet 2005.</p>
+
+<p>Django a continué à se développer et à s'améliorer, depuis sa première sortie (1.0) en Septembre 2008 jusqu'à la version 2.0 récemment sortie (2017). Chaque sortie a ajouté son lot de nouvelles fonctionnalités et de corrections de bugs, allant du support de nouveaux types de bases de données, de moteurs de templates et de cache, à l'addition de fonctions et de classes de vues 'génériques' (qui réduisent la quantité de code que doivent écrire les développeurs pour tout un tas de tâches de programmation). </p>
+
+<div class="note">
+<p><strong>Note </strong>: Consultez les<span style="line-height: 1.5;"> <a href="https://docs.djangoproject.com/en/1.10/releases/">notes de publication</a> sur le site web de Django pour voir les changements apportés dans les versions récentes, ainsi que tout le travail accompli pour améliorer Django.</span></p>
+</div>
+
+<p>Désormais, Django est un projet open-source collaboratif florissant, avec plusieurs milliers d'utilisateurs et de contributeurs. Bien que plusieurs fonctionnalités reflètent encore ses origines, Django a évolué en un framework versatile capable de développer n'importe quel type de site web.<span style="line-height: 1.5;"> </span></p>
+
+<h2 id="À_quel_point_Django_est-il_populaire">À quel point Django est-il populaire ?</h2>
+
+<p>Il n'y a pas encore de mesure toute prête et définitive de la popularité des frameworks orientés serveur (bien que des sites comme <a href="http://hotframeworks.com/">Hot Frameworks</a> tentent d'estimer cette popularité en utilisant des moyens comme le comptage de projets GitHub et de questions sur StackOverflow pour chaque plateforme). Une meilleure question serait plutôt est-ce que Django est "suffisamment populaire" pour éviter les problèmes des plateformes moins populaires. Va-t-il continuer d'évoluer ? Pourrez-vous obtenir de l'aide si vous en avez besoin ? Aurez-vous des opportunités d'emploi si vous apprenez Django ? </p>
+
+<p>Si l'on se base sur la quantité de sites web reconnus qui utilisent Django, la quantité de personnes contribuant à son code source, et la quantité de personnes fournissant du support libre ou payant, alors oui, Django est un framework populaire !</p>
+
+<p>Parmi les sites web qui utilisent Django, on retrouve : Disqus, Instagram, la Knight Foundation, la MacArthur Foundation, Mozilla, National Geographic, l'Open Knowledge Foundation, Pinterest et Open Stack (source : <a href="https://www.djangoproject.com/">Page d'accueil de Django</a>).</p>
+
+<h2 id="Django_est-il_restrictif">Django est-il restrictif ?</h2>
+
+<p>Les frameworks web sont souvent qualifiés de "restrictifs" ou de "non-restrictifs".</p>
+
+<p>Les frameworks restrictifs sont ceux vous donnant une "bonne façon" de réaliser une tâche particulière. Ils sous-tendent souvent un développement rapide <em>dans un domaine particulier </em>(résoudre des problèmes d'un type particulier), car cette bonne façon de faire est souvent bien comprise et bien documentée. Cependant, ils peuvent être moins flexibles dans leurs capacités à résoudre des problèmes en dehors de leur domaine, et offrent souvent moins de choix sur les composants et approches utilisables.</p>
+
+<p>En contraste, les frameworks non-restrictifs ont moins de restrictions sur la meilleure façon d'assembler des composants ensemble pour achever un but, voire même sur quels composants utiliser. Ils simplifient la tâche des développeurs en leur permettant d'utiliser les outils les mieux adaptés à la réalisation d'une tâche particulière, au coût toutefois du besoin du développeur de trouver ces composants.<br>
+ <br>
+ Django est "plus ou moins restrictif", et offre ainsi le "meilleur de chaque approche". Il fournit un ensemble de composants pour gérer la plupart des tâches de développement web ainsi qu'une (ou deux) approches préférées sur leur utilisation. Toutefois, l'architecture découplée de Django implique que vous pouvez généralement choisir parmi un certain nombre d'options différentes, ou bien fournir un support pour des approches complètement nouvelles si vous le désirez.</p>
+
+<h2 id="À_quoi_ressemble_le_code_Django">À quoi ressemble le code Django ?</h2>
+
+<p>Dans un site web traditionnel orienté-données, une application web attend une requête HTTP d'un navigateur web (ou tout autre client). Quand une requête est reçue, l'application en comprend les besoins d'après l'URL et parfois d'après les informations en <code>POST</code> data ou <code>GET</code> data. En fonction de ce qui est attendu, elle peut ensuite lire ou écrire l'information dans une base de données ou réaliser une autre tâche requise pour satisfaire la requête. L'application renvoie ensuite une réponse au navigateur web, créant souvent en dynamique une page HTML affichée dans le navigateur où les données récupérées sont insérées dans les balises d'un modèle HTML.</p>
+
+<p>Les applications web Django regroupent généralement le code qui gère chacune de ces étapes dans des fichiers séparés :</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/13931/basic-django.png" style="border-style: solid; border-width: 1px; display: block; margin: 0px auto;"></p>
+
+<ul>
+ <li><strong>URLs : </strong> Bien qu'il soit possible de traiter les requêtes de chaque URL via une fonction unique, il est bien plus viable d'écrire une fonction de vue isolée qui gèrera chaque ressource. Un mapper URL est utilisé pour rediriger les requêtes HTTP à la vue appropriée d'après l'URL de requête. Le mapper URL peut aussi faire la correspondance entre des patterns de chaînes de caractères ou de nombres qui apparaissent dans une URL et passer ces derniers comme données dans une fonction de vue.</li>
+ <li><strong>Vues :</strong> Une vue est une fonction de gestion des requêtes, qui reçoit des requêtes HTTP et renvoie des réponses HTTP. Les vues accèdent aux données requises pour satisfaire des requêtes via des <em>modèles</em>, et délèguent le formatage des réponses aux <em>templates</em>.</li>
+ <li><strong>Modèles :</strong> Les modèles sont des objets Python, qui définissent la structure des données d'une application, et fournissent des mécanismes de gestion (ajout, modification, suppression) et requêtent les enregistrements d'une base de données. </li>
+ <li><strong>Templates:</strong> Un template est un fichier texte qui définit la structure ou la mise en page d'un fichier (comme une page HTML), avec des balises utilisées pour représenter le contenu. Une <em>vue </em>peut créer une page HTML en dynamique en utilisant un template HTML, en la peuplant avec les données d'un <em>modèle</em>. Un template peut-être utilisé pour définir la structure de n'importe quel type de fichier; il n'est pas obligatoire que ce dernier soit un HTML !</li>
+</ul>
+
+<div class="note">
+<p><strong>Note</strong>: Django mentionne cette organisation sous le nom d'architecture "Modèle Vue Template". Elle a plusieurs similarités avec l'architecture <a href="/en-US/docs/Web/Apps/Fundamentals/Modern_web_app_architecture/MVC_architecture">Modèle Vue Contrôleur</a>.</p>
+</div>
+
+<ul>
+</ul>
+
+<p>Les sections ci-dessous vous donneront une idée de ce à quoi ressemble ces différentes parties d'une application Django (nous verrons plus de détails plus tard dans le jeu, une fois que nous aurons configuré l'environnement de développement).</p>
+
+<h3 id="Envoyer_la_requête_à_la_bonne_vue_urls.py">Envoyer la requête à la bonne vue (urls.py)</h3>
+
+<p>Le mapper URL est généralement stocké dans un fichier nommé <strong>urls.py</strong>. Dans l'exemple ci-dessous, le mapper (<code>urlpatterns</code>) définit une liste de mappings entre des <em>routes</em> (des <em>patterns </em>d'URL spécifiques<em>) </em>et leur fonction de vue correspondante. Si une requête HTTP est reçue dont l'URL correspond à un pattern spécifié, la fonction vue associée sera alors appelée et passée dans la requête.</p>
+
+<pre>urlpatterns = [
+ <strong>path('admin/', admin.site.urls),
+  </strong>path('book/&lt;int:id&gt;/', views.book-detail, name='book-detail'),
+ path('catalog/', include('catalog.urls')),
+ re_path(r'^([0-9]+)/$', views.best),
+]
+</pre>
+
+<p>L'objet <code>urlpatterns</code> est une liste de fonctions <code>path()</code> et/ou <code>re_path()</code>(les listes en Python sont définies en utilisant des crochets), où des éléments sont séparés par des virgules et peuvent avoir une <a href="https://docs.python.org/2/faq/design.html#why-does-python-allow-commas-at-the-end-of-lists-and-tuples">virgule de traîne optionnelle</a>. Par exemple : <code>[item1, item2, item3,]</code>).</p>
+
+<p>Le premier argument de chaque méthode est une route (pattern) qui sera reconnu.<br>
+ La méthode <code>path()</code> utilise des chevrons pour définir les parties de l'URL qui seront capturées et passées dans les fonctions vues comme arguments nommés. La fonction <code>re_path()</code> utilise une approche de correspondance de pattern flexible, connue sous le nom d'expression régulière. Nous parlerons de ces dernières dans un prochain article !</p>
+
+<p>Le second argument est une autre fonction qui sera appelée quand le pattern sera reconnu. La notation <code>views.book-detail</code> indique que la fonction s'appelle <code>book-detail()</code> , et qu'elle se trouve dans un module appelé <code>views</code> (i.e. dans un fichier intitulé <code>views.py</code>)</p>
+
+<h3 id="Traiter_la_requête_views.py">Traiter la requête (views.py)</h3>
+
+<p>Les vues sont le coeur des applications web. Elles reçoivent des requêtes HTTP de clients web et renvoient des réponses HTTP. Entretemps, elles mobilisent les autres ressources du framework pour accéder aux bases de données, préparer le rendu des templates, etc.</p>
+
+<p>L'exemple ci-dessous montre une fonction vue minimale <code>index()</code>, qui pourrait être appelée par notre mapper URL de la section précédente. Comme toutes les fonctions vues, elle reçoit un objet  <code>HttpRequest</code> comme paramètre (<code>request</code>) et renvoie un objet <code>HttpResponse</code>. Dans notre cas on ne fait rien de spécial avec la requête; et notre réponse ne renvoie qu'une chaîne de caractères brute. Nous vons montrerons une requête plus intéressante dans une autre section.</p>
+
+<pre class="brush: python">## nom du fichier : view.py (fonction vue Django)
+
+from django.http import HttpResponse
+
+def index(request):
+ # Reçoit une HttpRequest - le paramètre request
+ # réalise des opérations en utilisant les informations de la requête
+ # Renvoie HttpResponse
+ return HttpResponse('Hello from Django!')
+</pre>
+
+<div class="note">
+<p><strong>Note</strong>: Un peu de Python :</p>
+
+<ul>
+ <li>Les <a href="https://docs.python.org/3/tutorial/modules.html">modules Python</a> sont des librairies de fonctions, stockés dans des fichiers séparés que l'on peut vouloir utiliser dans notre code. Ici, nous importons l'objet  <code>HttpResponse</code> du module <code>django.http</code> pour qu'on puisse l'utiliser dans notre vue : <code>from django.http import HttpResponse</code> . Il y a d'autres façons d'importer quelques objets (ou tous les objets) d'un module.</li>
+ <li>Les fonctions sont déclarées en utilisant le mot-clé <code>def</code> comme indiqué ci-dessus, avec des paramètres nommés listés entre parenthèses après le nom de la fonction; la ligne se termine ensuite par deux points. Notez que les lignes suivantes sont <strong>indentées</strong>.  L'indentation est importante, car elle spécifie que les lignes de code sont contenues dans un bloc particulier (l'indentation obligatoire est un élément clé de Python, et une des raisons pour lesquelles le code Python est si simple à lire).</li>
+</ul>
+</div>
+
+<ul>
+</ul>
+
+<p>Les vues sont généralement stockées dans un fichier nommé <strong>views.py</strong>.</p>
+
+<h3 id="Définir_les_modèles_de_données_models.py">Définir les modèles de données (models.py)</h3>
+
+<p>Les applications web Django gèrent et requêtent les données via des objets Python appelés modèles. Les modèles définissent la structure des données stockées, ce qui inclut le champ <em>types</em> ainsi qu'au besoin leur taille maximum, les valeurs par défaut, les options de listes pouvant être sélectionnées, le texte d'aide pour la documentation — vous pouvez choisir ce dont vous avez besoin par rapport aux spécifications de votre projet. Une fois que vous avez choisi la base de données que vous souhaitez utiliser, vous n'avez pas du tout besoin de communiquer avec elle directement — vous n'avez qu'à écrire la structure de votre modèle, Django s'occupe du sale boulot de la communication avec la base de données pour vous.</p>
+
+<p>L'extrait de code ci-dessous montre un modèle Django très simple pour un objet <code>Team</code>. La classe <code>Team</code> est dérivée de la classe Django <code>models.Model</code>. Elle définit le nom et le niveau de l'équipe comme des chaînes de caractères et elle spécifie le nombre maximum de caractères pouvant être stockés pour chaque enregistrement. Le champ <code>team_level</code> peut avoir plusieurs valeurs, donc nous le définissons comme une liste de choix, puis on fournit à la classe un mapping entre les choix qui seront affichés et les données stockées, avec une valeur par défaut. </p>
+
+<pre class="brush: python"># nom du fichier : models.py
+
+from django.db import models
+
+class Team(models.Model):
+  team_name = models.CharField(max_length=40)
+
+    TEAM_LEVELS = (
+        ('U09', 'Under 09s'),
+        ('U10', 'Under 10s'),
+        ('U11', 'Under 11s'),
+  ... # lister les autres niveaux d'équipes
+    )
+    team_level = models.CharField(max_length=3,choices=TEAM_LEVELS,default='U11')
+</pre>
+
+<div class="note">
+<p><strong>Note</strong>: Un peu de Python :</p>
+
+<ul>
+ <li>Python supporte la "programmation orientée-objet", un type de programmation où l'on organise notre code en objets, ce qui inclut les données et fonctions liées qui agiront sur les données. Les objets peuvent être hérités/étendus/dérivés d'autres objets, ce qui permet à ces objets de partager un comportement commun. En Python, on utilise le mot-clé <code>class</code> pour définir le "squelette" d'un objet. On peut créer plusieurs <em>instances</em> spécifiques de ce type d'objet d'après le modèle d'une classe.<br>
+ <br>
+ Ainsi par exemple, nous avons ici une classe <code>Team</code>, dérivée de la classe <code>Model</code>.  Cela signifie que c'est un modèle, et qu'elle contiendra toutes les méthodes d'un modèle, mais qu'on peut aussi lui donner des caractéristiques spécifiques. Dans notre modèle, nous définissons les champs dont aura besoin notre base de données, en leur donnant des noms spécifiques. Django utilisera ces définitions, ce qui inclut aussi le nom des champs, pour créer la base de données sous-jacente.</li>
+</ul>
+</div>
+
+<h3 id="Requêter_les_données_views.py">Requêter les données (views.py)</h3>
+
+<p>Le modèle Django fournit une API de requête simplifiée qui nous permet de faire des recherches dans une base de données. Cette API peut inclure plusieurs champs à la fois en supportant plusieurs critères (e.g. exactement, insensible à la casse, supérieur à, etc.), et peut supporter des déclarations complexes (par exemple, vous pouvez spécifier une recherche sur les équipes U11 ayant un nom d'équipe commençant par "Fr" ou se terminant par "al"). </p>
+
+<p>L'extrait de code ci-dessous montre une fonction vue (gestionnaire de ressources) affichant toutes nos équipes U09. La ligne en gras montre comment on peut utiliser l'API de requête pour filtrer tous les enregistrements où le champ <code>team_level</code> comprend strictement le texte 'U09' (notez comment ce critère est passé dans la fonction <code>filter()</code> comme argument, où le nom du champ et le type de correspondance sont séparés par un double underscore : <strong>team_level__exact</strong>).</p>
+
+<pre class="brush: python">## nom du fichier : views.py
+
+from django.shortcuts import render
+from .models import Team
+
+def index(request):
+    <strong>list_teams = Team.objects.filter(team_level__exact="U09")</strong>
+    context = {'youngest_teams': list_teams}
+    return render(request, '/best/index.html', context)
+</pre>
+
+<dl>
+</dl>
+
+<p>Cette fonction utilise la fonction <code>render()</code> pour créer la <code>HttpResponse</code> qui est renvoyée au navigateur. Cette fonction est un <em>raccourci</em>; elle créée un fichier HTML en combinant un template HTML spécifique et des données à insérer dans le template (fournies dans la variable appelée "<code>context</code>"). Dans la prochaine section, nous vous montrons comment des données sont insérées dans le template pour générer le HTML.</p>
+
+<h3 id="Renvoyer_les_données_templates_HTML">Renvoyer les données (templates HTML)</h3>
+
+<p>Les systèmes template vous permettent de spécifier la structure d'un document en output, en utilisant des paramètres fictifs qui seront substitués par les données lorsque la page est générée. Les templates sont souvent utilisées pour créer du HTML, mais ils peuvent aussi être utilisées pour créer d'autres types de documents. Django supporte à la fois son système natif de template ainsi qu'une autre librairie Python populaire prête à l'emploi appelée Jinja2 (il peut aussi supporter d'autres systèmes au besoin). </p>
+
+<p>L'extrait de code ci-dessous montre à quoi pourrait ressembler le template HTML de la section précédente une fois appelé par la fonction <code>render().</code> Ce template a été écrit avec l'hypothèse qu'il aurait accès à une liste de variables appelées <code>youngest_teams</code> lorsqu'il est généré (contenu dans la variable <code>context</code> dans la fonction <code>render()</code> ci-dessus). Dans le squelette HTML nous avons une expression qui vérifie tout d'abord que la variable <code>youngest_teams</code> existe, puis itère dessus dans une boucle <code>for</code> . À chaque itération, le template affiche la valeur du <code>team_name</code> de chaque équipe dans un élément {{htmlelement("li")}}.</p>
+
+<pre class="brush: python">## nom du fichier : best/templates/best/index.html
+
+&lt;!DOCTYPE html&gt;
+&lt;html lang="en"&gt;
+&lt;body&gt;
+
+ {% if youngest_teams %}
+    &lt;ul&gt;
+    {% for team in youngest_teams %}
+        &lt;li&gt;\{\{ team.team_name \}\}&lt;/li&gt;
+    {% endfor %}
+    &lt;/ul&gt;
+{% else %}
+    &lt;p&gt;No teams are available.&lt;/p&gt;
+{% endif %}
+
+&lt;/body&gt;
+&lt;/html&gt;</pre>
+
+<h2 id="Que_pouvez-vous_faire_dautre">Que pouvez-vous faire d'autre ?</h2>
+
+<p>Les sections précédentes présentent les caractéristiques principales que vous utiliserez dans presque toutes vos applications web : mapping URL, vues, modèles et templates. Parmi les autres caractéristiques offertes par Django, on peut aussi trouver :</p>
+
+<ul>
+ <li><strong>Formulaires </strong>: Les formulaires HTML sont utilisés pour collecter des données utilisateurs qui seront traitées sur le serveur. Django simplifie la création, la validation et le traitement des formulaires.</li>
+ <li><strong>Authentification et permissions des utilisateurs</strong>: Django inclut un système d'authentification utilisateur et de gestion des permissions robuste créé avec la sécurité comme priorité lors de sa conception. </li>
+ <li><strong>Cache </strong>: Générer du contenu en dynamique demande bien plus de ressources computationnelles (et est plus lent) que de servir du contenu statique. Django fournit un système de cache flexible qui vous permet de stocker toute ou une partie d'une page afin qu'elle ne soit re-générée que lorsque c'est nécessaire.</li>
+ <li><strong>Administration du site </strong>: L'administration du site avec Django est incluse par défaut lorsque vous créez une application en utilisant le squelette de base. Django permet de créer très simplement une page d'administration où les administrateurs peuvent créer, éditer et voir n'importe quel modèle de données sur votre site.</li>
+ <li><strong>Sérialisation des données </strong>: Django permet de simplifier la sérialisation et de servir vos données en XML ou en JSON. Cela peut être utile si vous créez un service web (un site web dont le seul but est de servir des données qui seront utilisées par d'autres applications ou sites, mais n'affiche rien par lui-même), ou quand vous créez un site web où le code côté client s'occupe d'afficher les données.</li>
+</ul>
+
+<h2 id="Sommaire">Sommaire</h2>
+
+<p>Félicitations, vous avez atteint la première étape dans votre voyage avec Django ! Vous devriez désormais comprendre les principaux bénéfices de Django, en savoir un peu plus sur son histoire, et grossièrement à quoi ressemblent chaque partie de votre application Django. Vous devriez aussi avoir appris 2-3 choses à propos du langage de programmation Python, ce qui inclut la syntaxe des listes, fonctions et classes.</p>
+
+<p>Vous avez déjà vu un peu de vrai code Django ci-dessus, mais à la différence du code côté client, vous aurez besoin de configurer un environnement de développement pour l'utiliser. C'est notre prochaine étape.</p>
+
+<div>{{NextMenu("Learn/Server-side/Django/development_environment", "Learn/Server-side/Django")}}</div>
+
+<h2 id="In_this_module">In this module</h2>
+
+<ul>
+ <li><a href="/fr/docs/Learn/Server-side/Django/Introduction">Django introduction</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/development_environment">Setting up a Django development environment</a></li>
+ <li><a href="/fr/docs/Learn/Server-side/Django/Tutorial_local_library_website">Django Didactique: Site web "Bibliothèque locale"</a></li>
+ <li><a href="/fr/docs/Learn/Server-side/Django/skeleton_website">Django didactique Section 2: Créer le squelette du site web</a></li>
+ <li><a href="/fr/docs/Learn/Server-side/Django/Models">Django didactique Section 3: Utilisation des modèles de données</a></li>
+ <li><a href="/fr/docs/Learn/Server-side/Django/Admin_site">Django didactique Section 4 : Site d'administration de Django</a></li>
+ <li><a href="/fr/docs/Learn/Server-side/Django/Home_page">Django didactique Section 5: Créer la page d'accueil</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Generic_views">Django Tutorial Part 6: Generic list and detail views</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Sessions">Django Tutorial Part 7: Sessions framework</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Authentication">Django Tutorial Part 8: User authentication and permissions</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Forms">Django Tutorial Part 9: Working with forms</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Testing">Django Tutorial Part 10: Testing a Django web application</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Deployment">Django Tutorial Part 11: Deploying Django to production</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/web_application_security">Django web application security</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/django_assessment_blog">DIY Django mini blog</a></li>
+</ul>
diff --git a/files/fr/learn/server-side/django/models/index.html b/files/fr/learn/server-side/django/models/index.html
new file mode 100644
index 0000000000..298da70eff
--- /dev/null
+++ b/files/fr/learn/server-side/django/models/index.html
@@ -0,0 +1,468 @@
+---
+title: 'Django didactique Section 3: Utilisation des modèles de données'
+slug: Learn/Server-side/Django/Models
+translation_of: Learn/Server-side/Django/Models
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/Server-side/Django/skeleton_website", "Learn/Server-side/Django/Admin_site", "Learn/Server-side/Django")}}</div>
+
+<p class="summary">Ce troisième article est consacré aux modèles de données pour les sites web générés avec Django. Après une définition et une présentation de la notion de modèle de données, il explique comment les déclarer, choisir le type de champs et quelques méthodes d'accès au modèle de données via Django.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Pré-requis:</th>
+ <td>
+ <p><a href="/fr/docs/Learn/Server-side/Django/skeleton_website">Django didactique Section 2: Créer le squelette du site web.</a></p>
+ </td>
+ </tr>
+ <tr>
+ <th scope="row">Objectif:</th>
+ <td>
+ <p>Concevoir et créer vos propres modèles de données et choisir les attributs idoines.</p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Survol">Survol</h2>
+
+<p>Les applications web Django donnent accès aux données enregistrées dans une base à l'aide d'une classe d'objets <em>models</em>. Une classe d'objet héritée de <em>models</em> définit une <em>structure de données</em> ainsi que le type, la taille et la nature des champs de cette structure de données. Cela inclut aussi la valeur par défaut, les options ou listes d'option, les informations pour l'aide en ligne ou la définition des étiquettes des champs des formulaires. La définition du modèle de données est une abstraction indépendante du gestionnaire de base de données associé ; une fois choisi le gestionnaire est sollicité par le biais des objets Python/Django et vous n'interagissez pas directement avec lui. Votre rôle est alors de décrire le modèle de données par le biais d'objets appropriés et Django prend en charge les communications avec la base de données.</p>
+
+<p>Ce chapitre vous montre sur la base du <a href="/fr/docs/Learn/Server-side/Django/Tutorial_local_library_website">site web d'une bibliothèque locale</a> comment concevoir, créer et manipuler les données par l'intermédiaire du modèle de données.</p>
+
+<h2 id="Concevoir_le_modèle_de_données_de_la_bibliothèque_locale">Concevoir le modèle de données de la bibliothèque locale</h2>
+
+<p>Une étape préliminaire à la phase de développement est de réfléchir aux données (et donc aux structures de données) nécessaires et utiles pour le projet et aux relations entre-elles.</p>
+
+<p>Nous aurons besoin de conserver des données sur des livres (titre, résumé, auteur, version original, catégorie, ISBN), le nombre disponible en stock (donc un identifiant unique par livre et le statut du prêt). Nous aurons probablement besoin d'enregistrer des informations sur les auteurs qui ne seront pas uniquement le nom ainsi que gérer l'homonymie. Enfin, il sera nécessaire d'ordonner et de trier ces informations par titre, auteur, langue ou catégorie.</p>
+
+<p>En conception, il est judicieux et recommandé de décrire chacun des objets séparément. Dans le cas présent, il nous faudra un objet pour les livres, les copies des livres et les auteurs.</p>
+
+<p>Vous pourriez aussi utiliser les modèles pour définir des listes d'options (comme une liste déroulante pour un choix), plutôt que d'avoir à implémenter avec le code du site web ces choix. C'est d'ailleurs une recommandation à considérer si les options ne sont pas parfaitement connues à l'avance. Ce sera typiquement le cas des catégories de livres (science fiction, poésie, littérature étrangère, etc.) ou des langues des version originales (Français, Anglais, Espagnol, etc.).</p>
+
+<p>Le choix du modèle étant posé, nous avons à considérer les relations entre les objets. Django permet d'établir trois types de relation : les relations un à un qui mettent en relation un et un seul objet avec un autre (<code>OneToOneField</code>), les relations un à n qui partage l'appartenance d'un objet à avec d'autres (<code>ForeignKey</code>) et les relations n à n qui associent des groupes d'objets entre-eux (<code>ManyToManyField</code>).</p>
+
+<p>Avec ces éléments présents à l'esprit, le diagramme  de classes UML ci-dessous décrit les objets de la bibliothèque.</p>
+
+<p><img alt="LocalLibrary Model UML" src="https://mdn.mozillademos.org/files/16479/local_library_model_uml.png" style="height: 660px; width: 977px;"></p>
+
+<p>Le modèle ainsi créé, décrit l'objet livre - <em>Book</em> - avec une description générique d'un livre, la copie d'un livre - <em>BookInstance</em> - avec l'état d'un copie physique d'un livre et de sa disponibilité, et l'objet auteur - <em>Author</em>. Les genres des collections pouvant varier, il est plus élégant de concevoir une classe d'objets dédiée comme pour les langues. Considérant que le statut de prêt ne changera pas, il est décidé que le traiter dans le code - <code>BookInstance:status</code> sera géré dans le code Django <code>LOAN_STATUS</code>. Dans le diagramme de classe, les caractéristiques de chacun des attributs et méthodes sont précisées pour plus de clarté du travail à réaliser.</p>
+
+<p>Le diagramme met aussi en évidence les relations entre les objets et la cardinalité des relations. La cardinalité est représentée par les nombres entre crochet avec, si nécessaire, un minimum et un maximum. Par exemple, un ouvrage a, au moins un genre ([1..*]) alors qu'un genre peut ne pas référencer un livre ([0..*]) ce qui se traduira en définition des objets dans models.py.</p>
+
+<div class="note">
+<p><strong>Note</strong>: La section ci-dessous est une introduction générale à la modélisation des objets pour les modèles de données dans Django. Gardez à l'esprit la bibliothèque locale et imaginez comment devraient être décrits les objets pour cette bibliothèque.</p>
+</div>
+
+<h2 id="Introduction_au_modèle_de_données">Introduction au modèle de données</h2>
+
+<p>Cette section fournit une rapide introduction à la définition des objets de conception du modèle de données. </p>
+
+<h3 id="Spécification">Spécification</h3>
+
+<p>Les objets sont <strong>toujours</strong> définis dans le fichier <strong>models.py</strong> de chaque application. Ils sont conçus comme sous-classe de <code>django.db.models.Model</code>, et sont caractérisés par des attributs ou champs, des méthodes et des métadonnées. L'extrait ci-dessous définit donc la classe <code>MyModelName</code>:</p>
+
+<pre class="notranslate">from django.db import models
+
+class MyModelName(models.Model):
+    """A typical class defining a model, derived from the Model class."""
+
+  # Fields
+    my_field_name = models.CharField(max_length=20, help_text='Enter field documentation')
+  ...
+
+  # Metadata
+ class Meta:
+  ordering = ['-my_field_name']
+
+  # Methods
+    def get_absolute_url(self):
+        """Returns the url to access a particular instance of MyModelName."""
+        return reverse('model-detail-view', args=[str(self.id)])
+
+    def __str__(self):
+        """String for representing the MyModelName object (in Admin site etc.)."""
+        return self.my_field_name</pre>
+
+<p>Détaillons ce qu'il en retourne :</p>
+
+<h4 id="Champs_ou_attributs">Champs ou attributs</h4>
+
+<p>Chaque objet peut contenir autant d'attributs que de besoin et de quelque type qu'il soit. Chaque attribut correspondra à une colonne - <em>ou champ</em> - dans une table de la base de données. Chaque enregistrement, ou ligne dans la table, correspondra à une instance de la classe d'objet et chaque champ sera évalué. Un champ est de la forme :</p>
+
+<pre class="brush: js notranslate">my_field_name = models.CharField(max_length=20, help_text='Enter field documentation')</pre>
+
+<p>Dans l'exemple ci-dessus, le champs est une chaîne de caractères — de type <code>models.CharField</code> —  dont le nom est <code>my_field_name</code>. Les champs ont des types pré-définis représentés par une classe d'objet Django qui va permettre de caractériser une champ du modèle de données. Cela permet aussi de valider les données qui seront fournies via les formulaires du site web décrits avec le langage HTML. Les classes caractérisant les type de champs peuvent accepter des paramètres pour préciser les contraintes appliquées à ce champ. Dans cet exemple, deux arguments sont indiqués :</p>
+
+<ul>
+ <li><code>max_length=20</code> — Défini que ce champs fait au plus 20 caractères.</li>
+ <li><code>help_text='Enter field documentation'</code> — attribue un label par défaut qui sera affiché dans la page web par le navigateur.</li>
+</ul>
+
+<p>Le nom du champs sera utilisé dans les requêtes et les gabarits. Ces champs peuvent avoir une étiquette à l'aide d'un argument de définition (<code>verbose_name</code>) ou ils seront déduits à l'aide d'un changement de casse ou le remplacement des espaces par des soulignés (comme par exemple <code>my_field_name</code> serait l'étiquette par défaut du champs <em>My field name</em>).</p>
+
+<p>L'ordre dans lequel est défini un attribut de la classe d'objet va définir la position de la colonne dans le modèle physique de la base de données ce qui affectera, même la présentation est modifiable, la présentation par défaut des champs dans les formulaires ; c'est notamment le cas pour la partie administration du site web.</p>
+
+<h5 id="Les_arguments_courants_des_champs">Les arguments courants des champs</h5>
+
+<p>Vous trouverez ci-dessous les arguments les plus utilisés dans la définition des champs :</p>
+
+<ul>
+ <li><a href="https://docs.djangoproject.com/fr/2.2/ref/models/fields/#help-text">help_text</a>: définit l'étiquette du champ qui apparaîtra par défaut dans les formulaires HTML (notamment sur la section Administration du site).</li>
+ <li><a href="https://docs.djangoproject.com/fr/2.2/ref/models/fields/#verbose-name">verbose_name</a>: définit un nom vernaculaire du champs technique qui sera alors utilisé comme étiquette. Si ce nom n'est pas défini alors Django va le déduire du nom technique.</li>
+ <li><a href="https://docs.djangoproject.com/fr/2.2/ref/models/fields/#default">default</a>: définit la valeur par défaut du champs. Ce peut être une valeur alphanumérique mais aussi un objet créé appelable qui sera sollicité à chaque création d'un objet appelant.</li>
+ <li><a href="https://docs.djangoproject.com/fr/2.2/ref/models/fields/#null">null</a>: définit si le champs peut ne pas être remplit dans la base de données ; s'il est à vrai ( <code>True</code>), alors Django considère qu'une valeur <code>NULL</code> peut être correctement enregistrée - pour une chaîne de caractère de type <code>CharField</code> il s'agira d'une chaîne vide. La valeur par défaut de cet attribut est à faux (<code>False</code>) c'est-à-dire qu'il est nécessaire d'avoir une donnée non vide à l'enregistrement par défaut.</li>
+ <li><a href="https://docs.djangoproject.com/fr/2.2/ref/models/fields/#blank">blank</a>: définit si un champ d'un formulaire peut ne pas être saisi ; s'il est à vrai (<code>True</code>), le champs peut être laissé vide dans le formulaire. Par défaut ce paramètre est à faux (<code>False</code>), ce qui traduit que Django exigera une saisie d'une information dans le champs. Ce paramètre est utilisé en complément de la valeur <code>null=True</code>, car si vous acceptez une valeur vide dans la base de données, il est inutile d'en obliger la saisie dans un formulaire web.</li>
+ <li><a href="https://docs.djangoproject.com/fr/2.2/ref/models/fields/#choices">choices</a>: définit une liste de choix possible pour un champs et sera traduit par un composant d'interface de type liste de choix.</li>
+ <li><a href="https://docs.djangoproject.com/fr/2.2/ref/models/fields/#primary-key">primary_key</a>: S'il est à <code>True</code>, il définit le champ comme une clé primaire, c'est-à-dire qui permet d'identifier de manière unique un enregistrement dans la table de la base de données, pour le modèle de données. S'il n'y a pas de clé primaire, Django en affectera une d'office.</li>
+</ul>
+
+<p>L'ensemble <a href="https://docs.djangoproject.com/fr/2.2/ref/models/fields/#field-options">des options de champs</a> peut être consulté sur le site Django.</p>
+
+<h5 id="Les_types_courrants_de_champs">Les types courrants de champs</h5>
+
+<p>Vous trouverez ci-dessous les arguments les principaux type de champs :</p>
+
+<ul>
+ <li><a href="https://docs.djangoproject.com/fr/2.2/ref/models/fields/#django.db.models.CharField">CharField</a> caractérise un champ de type chaîne de caractères de taille maximale fixe. Ce champ nécessite l'option obligatoire <code>max_length</code> pour définir la taille maximale de la chaîne de caractère.</li>
+ <li><a href="https://docs.djangoproject.com/fr/2.2/ref/models/fields/#django.db.models.TextField">TextField</a> caractérise un champs texte (de longeur non définit dans la base de données). Si l'option <code>max_length</code> est utilisé, celui-ci précisera la taille du champs texte des formulaires web mais n'aura pas d'impact dans la définition du champs en base de données.</li>
+ <li><a href="https://docs.djangoproject.com/fr/2.2/ref/models/fields/#django.db.models.IntegerField" title="django.db.models.IntegerField">IntegerField</a> caractérise un champs de type nombre entier.</li>
+ <li><a href="https://docs.djangoproject.com/fr/2.2/ref/models/fields/#datefield">DateField</a> et <a href="https://docs.djangoproject.com/fr/2.2/ref/models/fields/#datetimefield">DateTimeField</a> sont des type utilisées pour caractériser une date et une heure comme les objets <code>datetime.date</code> et <code>datetime.datetime</code> en Python. Les options (incompatibles ensemble) les plus courantes pour ces champs sont l'enregistrement au moment de la sauvegarde (<code>auto_now=True</code>), l'enregistrement à la création de l'objet (<code>auto_now_add</code>) et une valeur par défaut (<code>default)</code> qui pourra être changée par l'utilisateur.</li>
+ <li><a href="https://docs.djangoproject.com/fr/2.2/ref/models/fields/#emailfield">EmailField</a> est le type dédié à la gestion des courriers électroniques.</li>
+ <li><a href="https://docs.djangoproject.com/fr/2.2/ref/models/fields/#filefield">FileField</a> et <a href="https://docs.djangoproject.com/fr/2.2/ref/models/fields/#imagefield">ImageField</a> sont deux type utilisés pour permettre de télécharger des fichiers ou, plus spécifiquement des images. Les options de ces champs définissent où et comment ces fichiers seront enregistrés et conservés.</li>
+ <li><a href="https://docs.djangoproject.com/en/2.1/ref/models/fields/#autofield">AutoField</a> est un type particulier de nombre entier (<code>IntegerField</code>) qui est incrémenté automatiquement. S'il n'y a pas de clé primaire automatiquement déclarée alors un champs de ce type est automatiquement déclaré dans dans le modèle de données.</li>
+ <li><a href="https://docs.djangoproject.com/fr/2.2/ref/models/fields/#foreignkey">ForeignKey</a> est utilisé pour définir une relation un à plusieurs entre deux classe d'objet (ou deux enregistrements dans deux tables de la base de données). Plusieurs objets contenant la définition d'un champ de type <code>ForeignKey</code> peuvent faire référence à une seule et même clé ; tel est le sens de la relation un à plusieurs, ce n'est donc pas la clé étrangère qui porte la cardinalité de la relation.</li>
+ <li><a href="https://docs.djangoproject.com/fr/2.2/ref/models/fields/#manytomanyfield">ManyToManyField</a> est utilisé pour définir une relation n à n (e.g. un nom commun a plusieurs sens et un sens peut être décrit par plusieurs noms communs). Dans notre application bibliothèque, nous utiliserons ce type de champs d'une manière proche de la clé étrangère. Cependant, cette relation peut être utilisée pour exprimer des relations plus compliquées entre des groupes. Ce champ requiert l'option <code>on_delete</code> pour préciser le comportement de l'attribut quand l'enregistrement est supprimé (e.g. la valeur de l'attribut <code>models.SET_NULL</code> peut être affecté à <code>NULL</code>).</li>
+</ul>
+
+<p>L'ensemble <a href="https://docs.djangoproject.com/fr/2.2/ref/models/fields/#field-types">des types de champs</a> peut être consulté sur le site Django.</p>
+
+<h4 id="Métadonnées">Métadonnées</h4>
+
+<p>Vous avez la capacité de déclarer des métadonnées à l'aide de la classe  <code>class Meta</code>, comme précisé ci-dessous :</p>
+
+<pre class="brush: python notranslate">class Meta:
+ ordering = ['-my_field_name']
+</pre>
+
+<p>L'une des fonctionnalités les plus utiles disponible à l'aide des métadonnées est de définir et contrôler le classement des enregistrement. Vous l'obtenez en précisant la liste des champs dans l'attribut <code>ordering</code> comme indiqué ci-dessous. Le classement est fonction du type de l'attribut (une chaîne de caractère a un classement alphabétique alors qu'une date a un classement chronologique). Si vous préfixez le nom du champs du signe <em>moins</em> (-) alors le classement sera naturellement inversé.</p>
+
+<p>Voici un exemple de classe de livre par titre et dates de parution :</p>
+
+<pre class="brush: python notranslate">ordering = ['title', '-pubdate']</pre>
+
+<p>Les livres sont présenté dans l'ordre alphabétique de leur titre, puis dans l'ordre chronologique du plus récent au plus ancien.</p>
+
+<p>Un autre attribut très utile est celui d'un nom vernaculaire pour la classe, <code>verbose_name</code>  peut être au singulier et au pluriel :</p>
+
+<pre class="brush: python notranslate">verbose_name = 'BetterName'</pre>
+
+<p>D'autres attributs vous permettent de compléter des droits d'accès à ceux appliqués par défaut, des classement s'appuyant sur le comportement d'autres champs, ou de définir une classe abstraite (c'est-à-dire qui n'aura pas de transcription dans une table et des enregistrement, mais servira de support à d'autres classes partageant des éléments communs).</p>
+
+<p>D'autres éléments sont aussi disponible pour contrôler le comportement d'une base de données, mais sont principalement utilisé pour appliquer le modèle ORM sur une base de données déjà existante.</p>
+
+<p>L'ensemble <a href="https://docs.djangoproject.com/fr/2.2/ref/models/options/">des métadonnées de classe</a> peut être consulté sur le site Django.</p>
+
+<h4 id="Méthodes">Méthodes</h4>
+
+<p>Comme tout objet Python, une classe héritée de <code>model</code> peut utiliser des méthodes.</p>
+
+<p><strong>A minima, chaque modèle de données - c'est-à-dire une classe héritée de la classe model du module django.db - vous devez définir la méthode <code>__str__()</code> pour permettre d'afficher un élément compréhensible qui représentera l'instance de la classe.</strong> Cette méthode est aussi utilisée au niveau du site d'administration pour afficher les instances de la classe administrée. La plupart du temps, cette méthode retourne un titre ou nom associé à aux objets de la classe.</p>
+
+<pre class="brush: python notranslate">def __str__(self):
+  return self.field_name</pre>
+
+<p>Une seconde méthode très utilisée dans le cadriciel Django est <code>get_absolute_url()</code>. Elle permet de fournir un URL pour afficher dans le site web le contenu de de chacun des enregistrements associés au modèle de données décrit. Si vous utilisez cette méthode, Django ajoutera un bouton pour permet de visualiser le détail des enregistrements. Classiquement, une méthode <code>get_absolute_url()</code> est de la forme :</p>
+
+<pre class="brush: python notranslate">def get_absolute_url(self):
+ """Returns the url to access a particular instance of the model."""
+ return reverse('model-detail-view', args=[str(self.id)])
+</pre>
+
+<div class="note">
+<p><strong>Note</strong>: En supposant que vous allez utiliser des URLs du type <code>/myapplication/mymodelname/2</code> pour afficher individuellement les données des enregistrements de la table associée à votre modèle de données (où "2" est l'<code>id</code>entifiant d'un enregistrement donné), vous devrez créer un routage d'URL pour vous permettre de transmettre l'id à une vue détaillée de l'enregistrement (model detail view dans le cadriciel Django). Cette vue détaillée réalisera l'affichage de l'enregistrement. La fonction <code>reverse()</code> a pour objectif d'écrire l'URL dans un format cohérent avec le traitement des URL par les navigateurs.</p>
+
+<p>Bien entendu, cela requiert d'écrire le routage de l'URL, la vue et le gabarit...</p>
+</div>
+
+<p>Vous pouvez aussi définir toute les méthodes dont vous aurez besoin pour manipuler à travers les objets du modèle de données les enregistrements de la base de données.</p>
+
+<h3 id="Administration_des_données">Administration des données</h3>
+
+<p>A partir du moment où vous avez créé votre modèle de données, vous pouvez manipuler les instances pour créer, mettre à jour ou supprimer les enregistrements en base de données. Vous pouvez aussi faire des requêtes pour obtenir tout ou parti des enregistrements de la base. L'objet de cette section est d'évoquer la manière de manipuler ces données et cela revu progressivement dans les avancées de l'application Bibliothèque.</p>
+
+<h4 id="Créer_et_modifier_des_enregistrements">Créer et modifier des enregistrements</h4>
+
+<p>Pour créer un enregistrement, il suffit de définir une instance de la classe d'objet et de la sauvegarder avec la méthode <code>save()</code>.</p>
+
+<pre class="brush: python notranslate"># Créer un nouvel enregistrement en utilisant la méthode d'instanciation.
+record = MyModelName(my_field_name="Instance #1")
+
+# Sauvegarde de l'enregistrement en base de données.
+record.save()
+</pre>
+
+<div class="note">
+<p><strong>Note</strong>: Si aucun champs n'a été défini comme une clé primaire (option <code>primary_key</code>), un champs nommé <code>id</code> ou <code>pk</code> sera affecté au modèle et sera incrémenté automatiquement. Vous pouvez requêter cet enregistrement à l'aide de ce champ ; le premier enregistrement aura habituellement la valeur entière 1.</p>
+</div>
+
+<p>Les champs de l'enregistrement sont accessibles à l'aide des attributs de la classe d'objet. En utilisant la syntaxe pointée, vous pouvez modifier les valeurs des champs de l'enregistrement. Vous devez utiliser la méthode <code>save()</code> pour enregistrer en base de données les modifications.</p>
+
+<pre class="brush: python notranslate"># Accès au valeur des champs par le biais des attributs de classe Python.
+print(record.id) # devrez retourner la valeur 1 pour le premier en enregistrement.
+print(record.my_field_name) # devrez afficher 'Instance #1'
+
+# Changer la valeur d'un champs et le sauvegarder en base avec la méthoide save().
+record.my_field_name = "New Instance Name"
+record.save()</pre>
+
+<h4 id="Rechercher_des_enregistrements">Rechercher des enregistrements</h4>
+
+<p>La classe de base <code>objects</code> permet de faire des recherches d'enregistrement qui correspondront aux critères de recherche souhaités.</p>
+
+<div class="note">
+<p><strong>Note</strong>: Nous utiliserons dans les explications le modèle de données d'un livre (<code>Book</code>)avec des titres (<code>title</code>) et des genres littéraires (<code>genre</code>), car expliquer la manière de rechercher sur un modèle théorique n'est pas très pédagogique.</p>
+</div>
+
+<p>Vous pouvez obtenir tous les enregistrements d'un modèle de données sous la forme d'un jeu de données ou <code>QuerySet</code>, en utilisant <code>objects.all()</code>. Un <code>QuerySet</code> est un objet itérable, c'est-à-dire jeu de données contenant des objets que l'on peut parcourir.</p>
+
+<pre class="brush: python notranslate">all_books = Book.objects.all()
+</pre>
+
+<p>Un filtre Django ou <code>filter()</code> est une méthode qui permet de sélectionner un jeu de données répondant à des critères (texte ou numérique) de sélection. Par exemple, nus filtrons les livres dont le titre contient le mot "wild", puis nous dénombrons le jeu de données.</p>
+
+<pre class="brush: python notranslate">wild_books = Book.objects.filter(title__contains='wild')
+number_wild_books = wild_books.count()
+</pre>
+
+<p>Les arguments passés en option sont le champs et la nature du contrôle à effectuer. On utilise le format : <code>field_name__match_type</code> : dans l'exemple ci-dessus, le double sous-ligné marque la séparation entre le champ <code>title</code> et le type de contrôle <code>contains</code> ; concrètement, le filtre est appliqué sur le champ <code>title</code> contenant le mot <code>wild</code> en respectant la casse. Il existe d'autres options de contrôle : <code>icontains</code> (sans respect de la casse), <code>iexact</code> (le chmaps correspond exactement à la valeur donnée sans respect de la casse), <code>exact</code> (idem en respectant la casse) et <code>in</code>, <code>gt</code> (plus grand que), <code>startswith</code>(commence par), etc. La liste complète est <a href="https://docs.djangoproject.com/fr/2.2/ref/models/querysets/#field-lookups">consultatble sur la documentation de Django</a>.</p>
+
+<p>Le marqueur "double souligné" permet de construire une chaîne de navigation à travers les objets lorsque le champ considéré est une clé étrangère (<code>ForeignKey</code>). C'est systématiquement le cas lorsque l'on doit filtrer sur une propriété d'un attribut dans une relation un-à-un. Dans ce cas (exemple ci-dessous), vous identifiez l'attribut de la clé étrangère par le biais d'un "double souligné" qui indique le champs à filter. L'exemple ci-dessous indique que vous filtrez les livres selon le nom (<code>name</code>) du genre (<code>genre</code>) du livre.</p>
+
+<pre class="brush: python notranslate"># Le criètre s'appliquera sur les genres contenant 'fiction' i.e. : Fiction, Science fiction, non-fiction etc.
+books_containing_genre = Book.objects.filter(genre<strong>__</strong>name<strong>__</strong>icontains='fiction')
+</pre>
+
+<div class="note">
+<p><strong>Note</strong>: Vous pouvez construire une chemin pour naviguer dans autant de niveaux de relation (<code>ForeignKey</code>/<code>ManyToManyField</code>) que vous en avez besoin en concaténant des noms de champs à l'aide  (__) . Si par exemple vous souhaitez trouver un livre (<code>Book</code>) qui possède différents type (<code>type</code>) de couvertures (<code>cover</code>) identifiées par des noms (<code>name</code>) alors le chemin sera du type : <code>type__cover__name__exact='hard'.</code></p>
+</div>
+
+<p>La mise en oeuvre des requêtes est très riches en fonction des modèles et des relations, de sous-ensemble de données, etc. Pour une informations détaillées, vous devez consulter <a href="https://docs.djangoproject.com/fr/2.2/topics/db/queries/">les requêtes</a> sur le site de référence de Django.</p>
+
+<h2 id="Définition_du_modèle_de_données_de_lapplication_LocalLibrary">Définition du modèle de données de l'application LocalLibrary</h2>
+
+<p>Cette section est consacrée au démarrage de la définition de l'application LocalLibrary qui permet de gérer une petite bibliothèque locale. Ouvrez le fichier <em>models.py </em>présent dans le répertoire<em> /locallibrary/catalog/</em>. Le code par défaut est déjà en place au début du document et permet d'importer les éléments du module models de django.</p>
+
+<pre class="brush: python notranslate">from django.db import models
+
+# Create your models here.</pre>
+
+<h3 id="Lobjet_Genre">L'objet Genre</h3>
+
+<p>Cet objet est utilisé pour décrire et enregistrer le genre littéraire des livres — par exemple une fiction, une polard ou un roman. Comme cela a été évoqué précédemment, nous créons un modèle de données plutôt que de gérer cela à l'aide de texte libre ou de codage en dur. Copiez le texte ci-dessous à la fin du fichier <em>models.py</em>.</p>
+
+<pre class="brush: python notranslate">class Genre(models.Model):
+    """Cet objet représente une catégorie ou un genre littéraire."""
+    name = models.CharField(max_length=200, help_text='Enter a book genre (e.g. Science Fiction)')
+
+    def __str__(self):
+        """Cette fonction est obligatoirement requise par Django.
+ Elle retourne une chaîne de caractère pour identifier l'instance de la classe d'objet."""
+        return self.name</pre>
+
+<p>L'objet, en relation avec la base de données, possède un seul attribut (<code>name</code>) de type chaîne de caractères (<code>CharField</code>), qui sera utilisé pour décrire le genre d'un livre (limité à 200 caractères). Une option (<code>help_text)</code> permet d'utiliser une étiquettes d'aide dans les pages et formulaires du site web. La méthode <code>__str__()</code>, qui retourne simplement le nom du genre littéraire de chaque enregistrement. Puisque qu'il n'y a pas de nom vernaculaire (<code>verbose_name</code>), le champ sera simplement nommé <code>Name</code> dans les formulaires.</p>
+
+<h3 id="Lobjet_Book">L'objet Book</h3>
+
+<p>Comme précédemment, vous pouvez copier le descriptif de l'objet Book à la fin du fichier models.py. Cet objet représente un livre dans sa description et non une copie en rayon disponible au prêt. Par conséquent, l'objet contient un titre et son identifiant international (isbn dont on notera l'étiquette en majuscule pour ne pas avoir "Isbn" à la place) sous forme de chaînes de caractère. De plus, l'objet contient un résumé sous forme d'une chaîne de caractère de longueur non explicite pour traiter de résumés plus ou moins long.</p>
+
+<pre class="brush: python notranslate">from django.urls import reverse # Cette fonction est utilisée pour formater les URL
+
+class Book(models.Model):
+    """Cet objet représente un livre (mais ne traite pas les copies présentes en rayon)."""
+    title = models.CharField(max_length=200)
+
+ # La clé étrangère (ForeignKey) est utilisée car elle représente correcte le modèle de relation en livre et son auteur :
+ # Un livre a un seul auteur, mais un auteur a écrit plusieurs livres.
+ # Le type de l'objet Author est déclré comme une chaîne de caractère car
+ # la classe d'objet Author n'a pas encore été déclarée dans le fichier
+    author = models.ForeignKey('Author', on_delete=models.SET_NULL, null=True)
+
+    summary = models.TextField(max_length=1000, help_text='Enter a brief description of the book')
+    isbn = models.CharField('ISBN', max_length=13, help_text='13 Character &lt;a href="https://www.isbn-international.org/content/what-isbn"&gt;ISBN number&lt;/a&gt;')
+
+    # Le type ManyToManyField décrit correctement le modèle de relation en un livre et un genre.
+ # un livre peut avoir plusieurs genres littéraire et réciproquement.
+    # Comme la classe d'objets Genre a été définit précédemment, nous pouvons manipuler l'objet.
+ genre = models.ManyToManyField(Genre, help_text='Select a genre for this book')
+
+    def __str__(self):
+        """Fonction requise par Django pour manipuler les objets Book dans la base de données."""
+        return self.title
+
+    def get_absolute_url(self):
+        """Cette fonction est requise pas Django, lorsque vous souhaitez détailler le contenu d'un objet."""
+        return reverse('book-detail', args=[str(self.id)])
+</pre>
+
+<p>Le genre littéraire est une relation n à n (<code>ManyToManyField</code>)car un livre peut avoir plusieurs genre et inversement. Bien que des livres soient écrits à plusieurs, dans le modèle de données présent un livre n'aura qu'un et un seul auteur. Un auteur est donc vu comme une clé étrangère <code>(ForeignKey</code>) de telle sorte qu'un livre n'a qu'un seul auteur et une auteur peut avoir écrit plusieurs livres.</p>
+
+<p>La modélisation des relations entre les objets, c'est le cas pour les deux champs décrits à l'instant, nécessite de manipuler les classes d'objet par leur nom de classe. Vous devez déclarer l'objet par son de classe dans la déclaration de la relation entre les objets, si celui-ci a déjà été déclaré vous pouvez l'utiliser comme un nom d'objet - à l'identique d'une variable Python - ou comme une chaîne de caractère si l'objet n'a pas déjà fait l'objet d'un déclaration. les autres paramètres dans la déclaration des relations permettent de spécifier les comportement des attributs : l'option <code>null</code> positionné à <code>True</code> permet d'avoir un contenu vide en base de données, la second option<code> on_delete=models.SET_NULL</code> qualifie le fonctionnement de cet attribut si l'objet est supprimé en base de données, en l'occurence il peut être positionné à vide en base de données.</p>
+
+<p>Deux méthodes sont déclarées pour cet objet. La méthode <code>__str__()</code> obligatoirement requise par Django pour manipuler les instances d'objet et les enregistrements associés en base. La seconde méthode, <code>get_absolute_url()</code>, retourne une URL formatée qui peut être utilisée par le cadriciel pour délivrer le détail de chaque instance d'objet de la classe. Le routage d'URL sera associé au nom  <code>book-detail</code>, et nous aurons à définir une vue et un gabarit.</p>
+
+<h3 id="Lobjet_BookInstance">L'objet BookInstance</h3>
+
+<p>Occupons nous maintenant de l'objet <code>BookInstance</code>. Comme précédemment, copiez le contenu décrivant l'objet BookInstance ci-dessous dans votre fichier <em>models.py</em>. La classe d'objets décrit une copie d'un ouvrage qu'un individu peut physiquement emprunter. Elle prend en compte les éléments d'information qui permettent de l'identifier individuellement et de connaître son statut à chaque instant ainsi que la date de retour du prêt.</p>
+
+<p>Les attributs et méthodes vont vous paraître familiers. On utilise :</p>
+
+<ul>
+ <li>une clè étrangère (<code>ForeignKey</code>) pour modéliser la relation avec le livre (un livre disposant de plusieurs copies).</li>
+ <li>Une chaîne de caractères (<code>CharField)</code> pour enregistrer les mentions légales (imprint) du livre.</li>
+</ul>
+
+<pre class="brush: python notranslate">import uuid # Ce module est nécessaire à la gestion des identifiants unique (RFC 4122) pour les copies des livres
+
+class BookInstance(models.Model):
+ """Cet objet permet de modéliser les copies d'un ouvrage (i.e. qui peut être emprunté)."""
+ id = models.UUIDField(primary_key=True, default=uuid.uuid4, help_text='Unique ID for this particular book across whole library')
+ book = models.ForeignKey('Book', on_delete=models.SET_NULL, null=True)
+ imprint = models.CharField(max_length=200)
+ due_back = models.DateField(null=True, blank=True)
+
+ LOAN_STATUS = (
+ ('m', 'Maintenance'),
+ ('o', 'On loan'),
+ ('a', 'Available'),
+ ('r', 'Reserved'),
+ )
+
+ status = models.CharField(
+ max_length=1,
+ choices=LOAN_STATUS,
+ blank=True,
+ default='m',
+ help_text='Book availability',
+ )
+
+ class Meta:
+ ordering = ['due_back']
+
+ def __str__(self):
+ """Fonction requise par Django pour manipuler les objets Book dans la base de données."""
+ return f'{self.id} ({self.book.title})'</pre>
+
+<p>De nouveaux types de champs sont utilisés :</p>
+
+<ul>
+ <li>Le type <code>UUIDField</code> est utilisé pour traiter d'un identifiant unique de livre comme clé primaire. Ce type de champ permet de générer un identifiant unique pour enregistrer et suivre chacune des copies de chacun des livres.</li>
+ <li>Le type <code>DateField</code> est utilisé pour enregistrer la date de retour d'un prêt. Ce champ peut-être vide pour gérer le cas des livres dans les rayonnages c'est-à-dire disponibles pour un prêt. Il est fait appel à la classe <code>Meta</code> pour permettre de classer les requêtes sur les objet par date de retr</li>
+ <li>our.</li>
+ <li>Le champ <code>status</code> est un type connu (<code>CharField</code>) qui définit une liste de choix. Les choix sont définis dans la description de l'objet par l'usage de tuples (une paire clé-valeur) et transmis en option dans la déclaration du champs. Alors que l'utilisateur manipulera les valeurs, les clés seront enregistrées dans la base de données. Enfin, la valeur par défaut est la Maintenance car lorsqu'un ouvrage est créé il n'est pas immédiatement disponible au prêt et n'est pas directement positionné en rayon.</li>
+</ul>
+
+<p>La méthode <code>__str__()</code> obligatoirement requise par Django pour manipuler les instances d'objet et les enregistrements associés en base. Elle offre cependant la particularité d'associer l'identifiant unique et le titre du livre qui lui est associé.</p>
+
+<div class="note">
+<p><strong>Note</strong>: Un aspect de Python:</p>
+
+<ul>
+ <li>Si vous démarrez avec une version postérieure à la version 3.6, vous pouvez utiliser le formatage des chaînes de caractère avec la fonction f-strings : <code>f'{self.id} ({self.book.title})'</code>.</li>
+ <li>Dans les versions précédente ce formatage était réalisé de manière différente utilisant la fonction de formatage format : <code>'{0} ({1})'.format(self.id,self.book.title)</code>).</li>
+</ul>
+</div>
+
+<h3 id="Lobjet_Author">L'objet Author</h3>
+
+<p>Terminons en copiant la description de l'objet <code>Author</code> à la fin du fichier <strong>models.py</strong>.</p>
+
+<pre class="brush: python notranslate">class Author(models.Model):
+ """Model representing an author."""
+ first_name = models.CharField(max_length=100)
+ last_name = models.CharField(max_length=100)
+ date_of_birth = models.DateField(null=True, blank=True)
+ date_of_death = models.DateField('Died', null=True, blank=True)
+
+ class Meta:
+ ordering = ['last_name', 'first_name']
+
+ def get_absolute_url(self):
+ """Returns the url to access a particular author instance."""
+ return reverse('author-detail', args=[str(self.id)])
+
+ def __str__(self):
+ """String for representing the Model object."""
+ return f'{self.last_name}, {self.first_name}'
+</pre>
+
+<p>Désormais les notions manipulées pour définir cet objet vous sont connues. L'objet réprésente un auteur par ses nom et prénoms ainsi que par ses dates de naissance et de décès (celles-ci n'étant pas obligatoires). Deux méthodes permettent l'une d'accéder à l'objet de manière compréhensible (<code>__str__()</code>) en retournant les nom et prénom de l'auteur dans cet ordre, et, l'autre (<code>get_absolute_url()</code>) permettra de publier les informations propres à chaque auteur.</p>
+
+<h2 id="Appliquer_les_modifications_en_base">Appliquer les modifications en base</h2>
+
+<p>Les objets sont tous décrits dans le fichier dédié à la modélisation. Pour qu'elles soient effectives, il est nécessaire d'exécuter les deux commandes python qui gèrent les migrations de la base de données.</p>
+
+<pre class="notranslate"><code>python3 manage.py makemigrations
+python3 manage.py migrate</code></pre>
+
+<h2 id="Défi_—_Introduire_les_langues">Défi — Introduire les langues</h2>
+
+<p>Faisons l'hypothèse qu'un donateur lègue à la bibliothèque des livres dont certains sont écrits dans des langues étrangères comme le Farsi (langue majoritaire en Iran). Le défi consiste donc à modéliser puis utiliser la meilleure représentation possible de ce concept pour la bibliothèque.</p>
+
+<p>Gardez en tête que :</p>
+
+<ul>
+ <li>Une langue peut-être associée à plusieurs objets dont au moins <code>Book</code>, <code>BookInstance</code></li>
+ <li>Plusieurs types peuvent être utiliser pour modéliser une langue un objet, un champs, ou explicitement dans le code à l'aide d'une liste de choix</li>
+</ul>
+
+<p>Après avoir fait vos choix, modéliser le et ajouter les champs utiles. Vous pouvez ensuite voir sur <a href="https://github.com/mdn/django-locallibrary-tutorial/blob/master/catalog/models.py">Github nous l'avons fait</a>.</p>
+
+<p>Une dernière chose... n'oubliez pas d'appliquer les modifications en base de données</p>
+
+<pre class="notranslate"><code>python3 manage.py makemigrations</code><code>
+python3 manage.py migrate</code></pre>
+
+<ul>
+</ul>
+
+<ul>
+</ul>
+
+<h2 id="Résumé">Résumé</h2>
+
+<p>Cet article est consacré à la création des objets et leur lien en base de données ainsi qu'à leur gestion. Il s'appuie sur l'exemple de la bibliothèque locale pour lequel nous décrivons le design du modèle relationnel et la manière de l'implementer avec une description d'objet Python conforme au standard du cadriciel Django.</p>
+
+<p>A ce stade, il est prématuré de créer le site web, nous allons simplement utiliser le site d'administration qui permet d'ajouter et de manipuler des données. Nous afficherons ces informations ensuite en créant des vues et de gabarits.</p>
+
+<h2 id="A_voir_aussi">A voir aussi</h2>
+
+<ul>
+ <li><a href="https://docs.djangoproject.com/fr/2.2/intro/tutorial02/">Ecriture de votre première application Django, Deuxième partie</a> (Documentation Django)</li>
+ <li><a href="https://docs.djangoproject.com/fr/2.2/topics/db/queries/">Création de requêtes</a> (Documentation Django)</li>
+ <li><a href="https://docs.djangoproject.com/fr/2.2/ref/models/querysets/">Référence de l'API QuerySet</a> (Documentation Django)</li>
+</ul>
+
+<p>{{PreviousMenuNext("Learn/Server-side/Django/skeleton_website", "Learn/Server-side/Django/Admin_site", "Learn/Server-side/Django")}}</p>
+
+<h2 id="Dans_ce_module">Dans ce module</h2>
+
+<ul>
+ <li><a href="/fr/docs/Learn/Server-side/Django/Introduction">Django introduction</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/development_environment">Setting up a Django development environment</a></li>
+ <li><a href="/fr/docs/Learn/Server-side/Django/Tutorial_local_library_website">Django Didactique: Site web "Bibliothèque locale"</a></li>
+ <li><a href="/fr/docs/Learn/Server-side/Django/skeleton_website">Django didactique Section 2: Créer le squelette du site web</a></li>
+ <li><a href="/fr/docs/Learn/Server-side/Django/Models">Django didactique Section 3: Utilisation des modèles de données</a></li>
+ <li><a href="/fr/docs/Learn/Server-side/Django/Admin_site">Django didactique Section 4 : Site d'administration de Django</a></li>
+ <li><a href="/fr/docs/Learn/Server-side/Django/Home_page">Django didactique Section 5: Créer la page d'accueil</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Generic_views">Django Tutorial Part 6: Generic list and detail views</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Sessions">Django Tutorial Part 7: Sessions framework</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Authentication">Django Tutorial Part 8: User authentication and permissions</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Forms">Django Tutorial Part 9: Working with forms</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Testing">Django Tutorial Part 10: Testing a Django web application</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Deployment">Django Tutorial Part 11: Deploying Django to production</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/web_application_security">Django web application security</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/django_assessment_blog">DIY Django mini blog</a></li>
+</ul>
diff --git a/files/fr/learn/server-side/django/skeleton_website/index.html b/files/fr/learn/server-side/django/skeleton_website/index.html
new file mode 100644
index 0000000000..787db15aec
--- /dev/null
+++ b/files/fr/learn/server-side/django/skeleton_website/index.html
@@ -0,0 +1,403 @@
+---
+title: 'Django didactique Section 2: Créer le squelette du site web'
+slug: Learn/Server-side/Django/skeleton_website
+tags:
+ - Apprentissage
+ - Article
+ - Didactitiel
+ - Débutant
+ - Guide
+ - Intro
+ - Programmation
+ - Tutoriel
+ - django
+translation_of: Learn/Server-side/Django/skeleton_website
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/Server-side/Django/Tutorial_local_library_website", "Learn/Server-side/Django/Models", "Learn/Server-side/Django")}}</div>
+
+<p class="summary">Ce second article de la série <a href="/fr/docs/Learn/Server-side/Django/Tutorial_local_library_website">didactique Django</a> va décrire comment créer le squelette du site web du projet. Ensuite, vous pourrez paramètrer et développer les composants spécifiques comme les modèles de données, les vues, les gabarits, les formulaires...</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Prérequis:</th>
+ <td><a href="/en-US/docs/Learn/Server-side/Django/development_environment">Set up a Django development environment</a>. Avoir pris connaissance de <a href="/fr/docs/Learn/Server-side/Django/Tutorial_local_library_website">l'article précédent</a>.</td>
+ </tr>
+ <tr>
+ <th scope="row">Objectifs:</th>
+ <td>Être capable d'utiliser les outils de Django pour initier un nouveau projet.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Vue_densemble">Vue d'ensemble</h2>
+
+<p>Cet article décrit comment créer le squelette du site web du projet. Ensuite, vous pourrez paramètrer et développer les composants spcifiques comme les modèles de données, vues, formulaires... qui chacun seront vus plus en details dans les articles suivants.</p>
+
+<p>La création est aisée:</p>
+
+<ol>
+ <li><span style="line-height: 1.5;">Utilisez la commande </span><code style="font-style: normal; font-weight: normal; line-height: 1.5;">django-admin</code><span style="line-height: 1.5;"> pour créer le dossier du projet ainsi que les sous-dossiers et fichiers de base ainsi que le script de gestion du projet (</span><strong style="line-height: 1.5;">manage.py</strong><span style="line-height: 1.5;">).</span></li>
+ <li><span style="line-height: 1.5;">Utilisez </span><strong style="line-height: 1.5;">manage.py</strong><span style="line-height: 1.5;"> pour créer une ou plusieurs <em>applications</em> du projet</span><span style="line-height: 1.5;">.</span>
+ <div class="note">
+ <p><strong>Note</strong>: Un site web consiste en une ou plusieurs sections, par exemple un site principal, un blog, un wiki,... La bonne pratique avec Django est de réaliser chacun des composants comme des applications séparées qui pourront éventuellement être réutilisées dans d'autres projets.</p>
+ </div>
+ </li>
+ <li><span style="line-height: 1.5;">Enregistrez la nouvelle application dans le projet. </span></li>
+ <li><span style="line-height: 1.5;">Liez les urls et chemins pour chaque application.</span></li>
+</ol>
+
+<p>Pour <a href="/fr/docs/Learn/Server-side/Django/Tutorial_local_library_website">le site web "Bibliothèque locale"</a>, le dossier du site web et celui du projet auront le même nom <em>locallibrary</em>. Une seule application <em>catalog</em> sera utilisée. La hiérachie de dossier du projet à la forme ci-dessous :</p>
+
+<pre class="brush: bash notranslate"><em>locallibrary/ # Website folder</em>
+  <strong>manage.py </strong># Script to run Django tools for this project (created using django-admin)
+  <em>locallibrary/ # Website/project folder </em>(created using django-admin)
+ <em>catalog/ # Application folder </em>(created using manage.py)
+</pre>
+
+<div class="blockIndicator note">
+<p>Afin de respecter la cohérence du code et pouvoir utiliser les développements sur GitHub, les noms du site et des applications, <em>en anglais</em>, n'ont pas été modifiés.</p>
+</div>
+
+<p><span style="line-height: 1.5;">La suite de ce chapitre est consacrée pas à pas aux étapes de création d'un projet et d'une application. La fin du chapitre sera consacré à quelques éléments de configuration du site qui peuvent être réalisés à ce stade.</span></p>
+
+<h2 id="Créer_le_projet_locallibrary">Créer le projet <em>locallibrary</em></h2>
+
+<p>Tout d'abord, il est nécessaire d'ouvrir une fenêtre pour exécuter des commandes en ligne (un terminal sous Linux/MacOS ou une fenêtre command sous Windows). Assurez-vous d'être dans un <a href="/en-US/docs/Learn/Server-side/Django/development_environment#Using_a_virtual_environment">environnement virtuel python</a>, déplacez-vous dans votre arborescence de dossiers pour être dans votre zone de développement des applications Django. Créez-y un sous-dossier pour les projets Django <code>django_projects</code> et déplacez-vous dans ce dernier :</p>
+
+<pre class="brush: bash notranslate">mkdir django_projects
+cd django_projects</pre>
+
+<p>Pour créer un nouveau projet avec le quadriciel Django, il suffit d'utiliser la commande  <code>django-admin startproject</code>. Le résultat de cette commande sera un sous-dossier du nom du projet dans lequel il suffit de s'y déplacer comme indiqué ci-dessous :</p>
+
+<pre class="brush: bash notranslate">django-admin startproject locallibrary
+cd locallibrary</pre>
+
+<p>La commande <code>django-admin</code> crée une arboresence contenant des fichiers et un sous-dossier portant le même nom que le projet :</p>
+
+<pre class="brush: bash notranslate"><em>locallibrary/</em>
+  manage.py
+  <em>locallibrary/</em>
+ __init__.py
+    settings.py
+    urls.py
+    wsgi.py</pre>
+
+<p>Votre répertoire de travail est de la forme :</p>
+
+<pre class="syntaxbox notranslate">../django_projects/locallibrary/</pre>
+
+<p>Le sous-dossier <em>locallibrary</em> permettra de gérer les requêtes web, il contient :</p>
+
+<ul>
+ <li><strong>__init__.py </strong>est un fichier vide qui indique au langage Python de considérer ce dossier comme un module Python.</li>
+ <li><strong>settings.py</strong> contient les paramètrages du site web. C'est ce fichier qui permet de contrôler l'enregistrement des applications créées - qui va être exposé plus bas -, la configuration de la base de données ou des variables globales au site. </li>
+ <li><strong>urls.py</strong> contient les indications de routage des urls du site web. Alors qu'il pourraient contenir toutes les urls, nous verrons plus loin qu'ils est plus pratique de déléguer la gestion des urls à propre à chacune des applications dans le contexte de l'application.<span style="line-height: 1.5;"> </span></li>
+ <li><strong style="line-height: 1.5;">wsgi.py</strong><span style="line-height: 1.5;"> est utilisé pour la gestion de l'interface entre Python et le serveur web. Il est recommandé de ne pas y toucher.</span></li>
+</ul>
+
+<p>Le fichier <strong>manage.py</strong> est utilisé pour créer et gérer les applications au sein du projet. C'est une boîte à outil précieuse qu'il ne faut pas modifier.</p>
+
+<h2 id="Créer_lapplication_catalog">Créer l'application <em>catalog</em></h2>
+
+<p>La commande ci-dessous va créer l'application <em>catalog</em>. Vous devez être dans le dossier de votre projet locallibrary pour exécuter cette commande (dans le même dossier que le fichier <strong>manage.py</strong> de votre projet) :</p>
+
+<pre class="brush: bash notranslate">python3 manage.py startapp catalog</pre>
+
+<div class="note">
+<p><strong>Note</strong>: La commande ci-dessus est exécutée dans un environnement Linux/macOS X. Sous Windows, il se peut que la commande soit : <code>py -3 manage.py startapp catalog</code></p>
+
+<p>Si vous travaillez dans un environnement Windows, l'ensemble de la série didactique est écrite pour un environnement Linux/MacOS. Pensez, alors, à remplacer les commandes <code>python3</code> par <code>py -3</code>.</p>
+
+<p>Si vous utilisez une version postérieure à la version 3.7.0, la commande devrait désormais être  <code>py manage.py startapp catalog</code></p>
+</div>
+
+<p>Cet outil crée un nouveau dossier, du nom de l'application, et le peuple de fichiers essentiels. La plupart des fichiers ont des noms caractéristiques de leur fonction dans le fonctionnement de Django (par exemple, les vues sont traitées dans <strong>views.py</strong>, le modèle de données dans <strong>models.py</strong>, etc.). Ces fichiers contiennent les éléments minimaux nécessaires à leur utilisation dans le projet.</p>
+
+<p>Le dossier projet <em>locallibrary</em> est agrémenté d'un nouveau sous-dossier <em>catalog</em> :</p>
+
+<pre class="brush: bash notranslate"><em>locallibrary/</em>
+  manage.py
+  <em>locallibrary/
+</em><strong>  <em>catalog/</em>
+      admin.py
+      apps.py
+      models.py
+      tests.py
+      views.py
+      __init__.py
+  <em>migrations/</em></strong>
+</pre>
+
+<p>A ceci s'ajoute :</p>
+
+<ul>
+ <li>Un dossier <em>migrations</em>, qui sera utilisé par django pour gérer les migrations et les modifications progressives apportées à la base de données quand des modifications seront faîtes dans les fichiers <em>models.py.</em></li>
+ <li><strong>__init__.py</strong> — est un fichier vide qui indique au langage Python de considérer ce dossier comme un module Python.</li>
+</ul>
+
+<div class="note">
+<p><strong>Note</strong>: Vous pouvez constater que dans le dossier de l'application, il n'y a pas de fichier pour gérer les urls, les gabarits ou les fichiers statiques. Nouys verrons ce point un peu plus loin, ils ne sont pas systématiquement nécessaires.</p>
+</div>
+
+<h2 id="Enregistrer_lapplication_catalog">Enregistrer l'application <em>catalog</em></h2>
+
+<p>Après avoir créé l'application, il est necessaire de l'enregistrée au sein du projet. Ceci permet de prendre en charge l'ensemble des éléments de l'application pour qu'ils soient pris automatiquement en charge par le quadriciel. L'enregistrement se fait dans la section <code>INSTALLED_APPS</code> en ajoutant le nom de l'application à la liste déjà présente.</p>
+
+<p>Éditez le fichier <strong>django_projects/locallibrary/locallibrary/settings.py</strong> et allez jusqu'à la liste <code>INSTALLED_APPS</code>. Ajoutez alors comme indiqué ci-dessous l'application à la liste.</p>
+
+<pre class="brush: bash notranslate">INSTALLED_APPS = [
+ 'django.contrib.admin',
+ 'django.contrib.auth',
+ 'django.contrib.contenttypes',
+ 'django.contrib.sessions',
+ 'django.contrib.messages',
+ 'django.contrib.staticfiles',
+<strong> 'catalog.apps.CatalogConfig', </strong>
+]</pre>
+
+<p>Le nouvel enregistrement défini l'objet pour cette nouvelle application avec le nom (<code>CatalogConfig</code>) qui a été généré dans le fichier <strong>/locallibrary/catalog/apps.py</strong> quand l'application a été créée.</p>
+
+<div class="note">
+<p><strong>Note</strong>: Nous verrons plus loin les autres paramètres de ce fichier(comme <code>MIDDLEWARE</code>). Cela permet la prise en charge par <a href="/en-US/docs/Learn/Server-side/Django/Admin_site">Django administration site</a> et donne accès à de nombreuses fonctionnalités (gestion des sessions, de l'authentication, etc).</p>
+</div>
+
+<h2 id="Définir_la_base_de_données">Définir la base de données</h2>
+
+<p>Dès à présent, la base de données doit être décrite. Il est souvent recommandé pour minimiser une transition délicate d'utiliser la même base de données en développement et en production. La documentation concernant les <a href="https://docs.djangoproject.com/fr/2.2/ref/settings/#databases">bases de données</a> prises en charge sont bien décrites sur le site du projet Django.</p>
+
+<p>Le système de gestion de base de données (SGBD) SQLite sera utilisé dans le projet de cette série didactique ; nous n'aurons pas d'accès concurents massifs et ce système ne requiert pas  de paramétrages complémentaires. Ci-dessous la définition dans <strong>settings.py</strong> est nécessaire pour utiliser ce SGBD :</p>
+
+<pre class="brush: python notranslate">DATABASES = {
+ 'default': {
+ 'ENGINE': 'django.db.backends.sqlite3',
+ 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
+ }
+}
+</pre>
+
+<h2 id="Dautres_paramètrages_du_projet">D'autres paramètrages du projet</h2>
+
+<p>Le fichier <strong>settings.py</strong> est utilisé pour l'ensemble des paramètres du projet, mais pour le moment nous n'allons nous occuper du fuseau horaire. Le format des fuseaux horaires est le format standard en informatique (<a href="https://en.wikipedia.org/wiki/List_of_tz_database_time_zones">Liste des codes - <em>en anglais</em></a>). Changez la variable <code>TIME_ZONE</code> de votre projet avec la chaîne appropriée à votre fuseau, par exemple :</p>
+
+<pre class="brush: python notranslate">TIME_ZONE = 'Europe/Paris'</pre>
+
+<p>Il y a deux paramètres à connaître, même s'il ne seront pas modifiés pour l'instant :</p>
+
+<ul>
+ <li><code>SECRET_KEY</code>. Il s'agit d'une clé utilisée pour la gestion de la sécurité d'un site web par Django. Si vous ne protégez pas cette clé - c'est-à-dire si vous divulguez cette information à des tiers - vous devrez changer cette clé lors de la mise en production. </li>
+ <li><code>DEBUG</code>. Ce paramètre est utilisé pour afficher les journaux de traces en cas d'erreur plutôt qu'une simple erreur HTTP en réponse à une requête. Ce paramètre <strong>doit</strong> être positionné à <code>False</code> lors du passage en production, dans le cas contraire vous divulguerez des informations essentielles à un potentiel attaquant. Pendant la période de développement, il est très utile de la conserver à <code>True</code>.</li>
+</ul>
+
+<h2 id="Configurer_le_routage_des_URLs">Configurer le routage des URLs</h2>
+
+<p>La création du site web s'appuie sur un routage d'URL et une gestion de la cartographie des URLs dans le fichier <strong>urls.py</strong>) présent dans le dossier du projet. Même si vous pouvez directement utiliser ce fichier pour gérer le routage des URLs, il est recommandé d'utiliser un mécanisme de subsidiarité avec une gestion d'URLs par application. En outre cette méthode de délégation permet une meilleure poratbilité de vos développements dans vos différents projets.</p>
+
+<p>A l'ouverture du fichier <strong>locallibrary/locallibrary/urls.py</strong>,  vous pouvez remarquer les premières instructions sur la manière de gérer la cartographie des URLs.</p>
+
+<pre class="brush: python notranslate">"""locallibrary URL Configuration
+
+The `urlpatterns` list routes URLs to views. For more information please see:
+    https://docs.djangoproject.com/en/2.1/topics/http/urls/
+Examples:
+Function views
+    1. Add an import:  from my_app import views
+    2. Add a URL to urlpatterns:  path('', views.home, name='home')
+Class-based views
+    1. Add an import:  from other_app.views import Home
+    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
+Including another URLconf
+    1. Import the include() function: from django.urls import include, path
+    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
+"""
+from django.contrib import admin
+from django.urls import path
+
+urlpatterns = [
+    path('admin/', admin.site.urls),
+]
+</pre>
+
+<p>Le routage des URLs est géré à l'aide de la variable <code>urlpatterns</code>. Elle consititue une liste Python de fonctions <code>path()</code>. Chaque instance <code>path()</code> peut associer des motifs d'URL à une vue particulière, qui sera appelée si l'URL appellée correspond au motif décrit, ou vers une autre liste d'URL (dans ce cas, le motif est à considérer comme le motif de base pour le module dans lequel il est décrit). La variable <code>urlpatterns</code> contient au démarrage une seule fonction qui permet de gérer l'URL d'administration du site et utilisant le module par défaut de Django <code>admin.site.urls</code>.</p>
+
+<div class="note">
+<p><strong>Note</strong>: Dans la fonction <code>path()</code>, une route est une chaîne de caractères définissant une URL ou un motif d'URL. Cette chaîne peut inclure des variables nommées (entre &lt; et &gt;, par exemple <code>'catalog/&lt;id&gt;/'</code>). Ce motif correspondra à une URL du type <strong>/catalog/</strong><em>des_caracteres</em><strong>/</strong>. La chaîne <em>des_caracteres</em> sera transmis à la vue comme une chaîne de caractère associée à une variable nommée <code>id</code>. Ce point sera vu en détails plus loin dans la série didactique.</p>
+</div>
+
+<p>Ajoutez les lignes ci-dessous à la fin du fichier de manière à ajouter dans la variable <code>urlpatterns</code> une nouvelle entrée à la liste des routes. Cette nouvelle entrée permet une nouvelle route pour <code>catalog/</code> dont la gestion est déléguée au fichier <strong>urls.py</strong> du module <strong>catalog</strong> (c'est-à-dire le fichier <strong>catalog/urls.py</strong>).</p>
+
+<pre class="brush: python notranslate"># Use include() to add paths from the catalog application
+from django.urls import include
+from django.urls import path
+
+urlpatterns += [
+    path('catalog/', include('catalog.urls')),
+]
+
+</pre>
+
+<p>Il est nécessaire de rediriger la racine du site (concrètement <code>https://127.0.0.1:8000/</code>) vers celui de la seule application <em>catalog</em> qui va être utilisée dans ce projet (concrètemen <code>127.0.0.1:8000/catalog/</code>). Pour cette étape, nous utilisons la fonction particulière (<code>RedirectView</code>) qui prend comme argument le lien relatif (concrètement <code>/catalog/</code>) quand le motif de l'URL correspondra (concrètement la racine du site).</p>
+
+<p>Ajoutez les lignes ci-dessous au bas du fichier <strong>urls.py</strong> :</p>
+
+<pre class="brush: python notranslate">#Add URL maps to redirect the base URL to our application
+from django.views.generic import RedirectView
+urlpatterns += [
+    path('', RedirectView.as_view(url='/catalog/', permanent=True)),
+]
+</pre>
+
+<p>La racine du site ('/') est prise en compte par Django, il est donc inutile d'écrire le chemin avec le caractère '/' en début. Si vous maitenez ce mode d'écriture, vous aurez le message ci-dessous au démarrage du serveur :</p>
+
+<pre class="brush: python notranslate">System check identified some issues:
+
+WARNINGS:
+?: (urls.W002) Your URL pattern '/' has a route beginning with a '/'.
+Remove this slash as it is unnecessary.
+If this pattern is targeted in an include(), ensure the include() pattern has a trailing '/'.
+</pre>
+
+<p>Django ne s'occupe pas nativement de fichiers statiques tels que des fichiers CSS, JavaScript, ou des images, cependant il est très utile pour que le serveur de développement le fasse pendant la création du site. Une dernière étape de configuration du routage générique des urls, consiste donc à gérer la publication des fichiers statiques. </p>
+
+<p>Ajoutez les lignes ci-dessous au bas du fichier <strong>urls.py</strong> :</p>
+
+<pre class="notranslate"><code># Use static() to add url mapping to serve static files during development (only)
+from django.conf import settings
+from django.conf.urls.static import static
+
+urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)</code>
+</pre>
+
+<div class="note">
+<p><strong>Note</strong>: Il y a plusieurs manière pour ajouter des routes à la variable <code>urlpatterns</code> (dans les étapes décrites ci-dessus nous avons ajouté petit à patir en utilisant l'opérateur <code>+=</code> pour bien séparer les étapes). Il est en réalité tout à fait possible de toput regrouper dans une seule étape :</p>
+
+<pre class="brush: python notranslate">urlpatterns = [
+  path('admin/', admin.site.urls),
+  path('catalog/', include('catalog.urls')),
+ path('', RedirectView.as_view(url='/catalog/')),
+] + <code>static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)</code>
+</pre>
+
+<p>De même, nous avons ajouté des imports de module à chaque étapes (par exemple, <code>from django.urls import include</code>) ce qui permet de bien voir les différentes étapes. Cependant, l'habitude veut que tous les imports soient traités en début de fichier Python.</p>
+</div>
+
+<p>Dernière étape ! Il faut créer le fichier urls.py dans l'application (ou le module) catalog et de définir la variable <code>urlpatterns</code> vide pour le moment. </p>
+
+<pre class="brush: python notranslate">from django.urls import path
+from . import views
+
+urlpatterns = [
+
+]
+</pre>
+
+<h2 id="Tester_le_site_web">Tester le site web</h2>
+
+<p>A ce niveau, le squelette du site est prêt. Le site ne produit rien de concret mais il peut être démarré pour s'assurer que les modifications apportées ne génèrent pas d'erreur au démarrage du serveur.</p>
+
+<p>Avant de démarer le serveur, et si vous vous souvenez bien, nous devrions faire une mise à niveau de la base de données. Il s'agit de préparer et de faire une migration de la base de données.</p>
+
+<h3 id="Exécuter_la_migartion_de_la_base_de_données">Exécuter la migartion de la base de données</h3>
+
+<p>Django utilise une cartographie d'objet relation ou mapping d'objet relationnel pour simuler une base de données orientée objet avec une base de données relationnelles. Au fur et à mesure des modification qui sont apportées dans la définition du modèle de données, le quadriciel va générer les scripts de migration (ces scripts sont localisés dans <code>locallibrary/catalog/migration</code>) pour modifier les structures de données associées dans la base de données.</p>
+
+<p>Quand le site a été créé (cf. supra), Django a automatiquement ajouté plusieurs modèles de base pour pouvoir administrer le site (point qui sera abordé plus loin). Pour configurer la base de données, avec ces éléments de base, il vous faut exécuter les commandes en ligne ci-dessous dans le répertoire racine du projet (dossier où se trouve<strong> manage.py</strong>):</p>
+
+<pre class="brush: bash notranslate">python3 manage.py makemigrations
+python3 manage.py migrate
+</pre>
+
+<div class="warning">
+<p><strong>Important</strong>: Chaque fois que vous ferez évoluer le modèle de données, vous devrez exécuter le commandes ci-dessus (elles seront traduites en structure dans la base de données que cela conduise à l'ajout ou au retrait d'objets ou d'attributs).</p>
+</div>
+
+<p>L'option <code>makemigrations</code> réalise (sans les appliquer) les migrations nécessaires à toutes les applications du projet. Vous pouvez cependant préciser le nom de l'application pour laquelle vous souhaitez réaliser la migration. Ceci permet de vérifier le code et la cohérence du modèle de donner avant de l'appliquer réellement. Quand vous aurez un niveau expert, vous pourrez choisir de les modifier à la marge.</p>
+
+<p>L'option <code>migrate</code> applique les modifications sur la base de données (Django trace les modifications réalisées dans la base de données).</p>
+
+<div class="note">
+<p><strong>Note</strong>: Vous pouvez consulter la documentation <a href="https://docs.djangoproject.com/fr/2.2/topics/migrations/">Migrations</a> (sur le site Django) pour plus d'informations.</p>
+</div>
+
+<h3 id="Démarrer_le_site_web">Démarrer le site web</h3>
+
+<p>Pendant la phase de développement, vous pouvez tester votre serveur sur un mode local et le consulter avec votre navigateur.</p>
+
+<div class="note">
+<p><strong>Note</strong>: Le serveur local n'est ni robuste ni performant, il n'est donc pas fait pour être utilisé en production, mais il permet d'être autonome pour les travaux de développement. La configuration par défaut de ce serveur est telle que votre site est accessible à l'URL <code>http://127.0.0.1:8000/</code>. Cependant, vous pouvez modifier ces paramètres et pour plus d'information vous pouvez consulter la documentation sur le site Django des commandes <a href="https://docs.djangoproject.com/fr/2.2/ref/django-admin/#runserver">django-admin and manage.py: runserver</a>.</p>
+</div>
+
+<p>Pour démarrer le serveur local, il suffit d'exécuter la commande ci-dessous dans le répertoire du projet (dossier où se trouver <strong>manage.py</strong>) :</p>
+
+<pre class="brush: bash notranslate">python3 manage.py runserver
+
+ Performing system checks...
+
+ System check identified no issues (0 silenced).
+ August 15, 2018 - 16:11:26
+ Django version 2.1, using settings 'locallibrary.settings'
+ Starting development server at http://127.0.0.1:8000/
+ Quit the server with CTRL-BREAK.
+</pre>
+
+<p>Dès que le serveur est actif, vous pouvez utiliser votre navigateur est accéder à l'URL <code>http://127.0.0.1:8000/</code>. Vous devriez accéder à la page d'erreur ci-dessous :</p>
+
+<p><img alt="Django Debug page for Django 2.0" src="https://mdn.mozillademos.org/files/15729/django_404_debug_page.png"></p>
+
+<p>Ne vous inquitez ! Cette erreur était attendue ; elle est due à l'absence de défintion de routes dans le fichier catalog/urls.py ou dans le module <code>catalog.urls</code> module (que nous avons déclaré dans le fichier urls.py du projet). </p>
+
+<div class="note">
+<p><strong>Note</strong>: La page web ci-dessus met en exergue une fonctionnalité utile de Django ; le mode des traces de debogag. Au lieu d'une simple erreur renvoyée par le serveur, celui-ci affiche un écran d'erreur avec des informations utiles pour corriger le développement conduisant à cette erreur d'affichage. Dans le cas présent, l'erreur est due au motif de l'URL qui ne correspond pas à ce qui a été configuré.</p>
+</div>
+
+<p>À ce stade, nous pouvons considérer que le serveur fonctionne !</p>
+
+<div class="note">
+<p><strong>Note</strong>: Chaque fois que vous apportez des modifications significatives, il est important d'exécuter à nouveau un migration et un test du serveur. Cela est assez rapide, pour ne pas s'en priver !</p>
+</div>
+
+<h2 id="Relevez_le_défi...">Relevez le défi...</h2>
+
+<p>Le dossier <strong>catalog/</strong> a été créé automatiquement et contient des fichiers pour les vues, modèles de données, etc. Ouvrez-les pour les consulter. </p>
+
+<p>Comme vous avez pu le constatez plus haut, une route pour l'administration du site (<code>http://127.0.0.1:8000/admin/</code>) existe déjà dans le fichier <strong>urls.py</strong> du projet. Avec votre navigateur web, vous pouvez découvrir ce qui est derrière ce site.</p>
+
+<ul>
+</ul>
+
+<h2 id="Résumé">Résumé</h2>
+
+<p>Le squelette du site web est entièrement construit à ce stade. Désormais, vous allez pouvoir y ajouter des urls, des vues, des modèles de données, des gabarits et des formulaires.</p>
+
+<p>Maintenant que ceci est fait, <a href="/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">le site web Local Library</a> est opérationnel et nous allons passer à la partie codage et développement pour que le site produise ce qu'il est censé faire.</p>
+
+<h2 id="A_voir_aussi...">A voir aussi...</h2>
+
+<ul>
+ <li><a href="https://docs.djangoproject.com/fr/2.2/intro/tutorial01/">Écriture de votre première application Django, 1ère partie</a>  (Django docs)</li>
+ <li><a href="https://docs.djangoproject.com/fr/2.2/ref/applications/#configuring-applications">Applications</a> (Django Docs). Contains information on configuring applications.</li>
+</ul>
+
+<p>{{PreviousMenuNext("Learn/Server-side/Django/Tutorial_local_library_website", "Learn/Server-side/Django/Models", "Learn/Server-side/Django")}}</p>
+
+<h2 id="Dans_ce_module">Dans ce module</h2>
+
+<ul>
+ <li><a href="/fr/docs/Learn/Server-side/Django/Introduction">Django introduction</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/development_environment">Setting up a Django development environment</a></li>
+ <li><a href="/fr/docs/Learn/Server-side/Django/Tutorial_local_library_website">Django Didactique: Site web "Bibliothèque locale"</a></li>
+ <li><a href="/fr/docs/Learn/Server-side/Django/skeleton_website">Django didactique Section 2: Créer le squelette du site web</a></li>
+ <li><a href="/fr/docs/Learn/Server-side/Django/Models">Django didactique Section 3: Utilisation des modèles de données</a></li>
+ <li><a href="/fr/docs/Learn/Server-side/Django/Admin_site">Django didactique Section 4 : Site d'administration de Django</a></li>
+ <li><a href="/fr/docs/Learn/Server-side/Django/Home_page">Django didactique Section 5: Créer la page d'accuei</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Generic_views">Django Tutorial Part 6: Generic list and detail views</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Sessions">Django Tutorial Part 7: Sessions framework</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Authentication">Django Tutorial Part 8: User authentication and permissions</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Forms">Django Tutorial Part 9: Working with forms</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Testing">Django Tutorial Part 10: Testing a Django web application</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Deployment">Django Tutorial Part 11: Deploying Django to production</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/web_application_security">Django web application security</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/django_assessment_blog">DIY Django mini blog</a></li>
+</ul>
diff --git a/files/fr/learn/server-side/django/testing/index.html b/files/fr/learn/server-side/django/testing/index.html
new file mode 100644
index 0000000000..ab06d584ec
--- /dev/null
+++ b/files/fr/learn/server-side/django/testing/index.html
@@ -0,0 +1,956 @@
+---
+title: 'Django Tutorial Part 10: Testing a Django web application'
+slug: Learn/Server-side/Django/Testing
+tags:
+ - Beginner
+ - CodingScripting
+ - Django Testing
+ - Testing
+ - Tutorial
+ - django
+ - server-side
+ - tests
+ - unit tests
+translation_of: Learn/Server-side/Django/Testing
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/Server-side/Django/Forms", "Learn/Server-side/Django/Deployment", "Learn/Server-side/Django")}}</div>
+
+<p class="summary">Quant un site web grandit, il devient plus difficile à tester manuellement. Non seulement il y a plus de choses à tester, mais encore, comme les interactions entres ses composants deviennent plus complexes, un léger changement dans une partie de l'application peut affecter les autres parties, si bien qu'il va être nécessaire de faire beaucoup de modifications pour s'assurer que tout continue de fonctionner, et qu'aucune erreur ne sera introduite quand il y aura encore plus de modifications. Une façon de limiter ces problèmes est d'écrire des tests automatiques qui puissent être lancés d'une manière simple et fiable à chaque fois que vous faites une modification. Ce tutoriel montre comment automatiser des <em>tests unitaires</em> sur votre site web en utilisant le framework de tests de Django.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Prérequis:</th>
+ <td>Avoir terminé tous les tutoriels précédents, y compris <a href="/en-US/docs/Learn/Server-side/Django/Forms">Django Tutorial Part 9: Working with forms</a>.</td>
+ </tr>
+ <tr>
+ <th scope="row">Objectif:</th>
+ <td>Comprendre comment écrire des tests unitaires pour des sites web basés sur Django.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Vue_densemble">Vue d'ensemble</h2>
+
+<p>Le site <a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">Local Library</a> a actuellement des pages pour afficher des listes de tous les livres et auteurs, des pages de détail pour les éléments de type <code>Book</code> et <code>Author</code>, une page pour renouveler des <code>BookInstance</code>s, et des pages pour créer, mettre à jour et effacer des éléments de type <code>Author</code> (et également des enregistrements de type <code>Book</code>, si vous avez relevé le <em>défi</em> dans le <a href="/en-US/docs/Learn/Server-side/Django/Forms">tutoriel sur les formulaires</a>). Même avec ce site relativement petit, naviguer manuellement vers chaque page et vérifier <em>superficiellement</em> que tout fonctionne comme prévu peut prendre plusieurs minutes. Quand nous allons faire des modifications et agrandir le site, le temps requis pour vérifier manuellement que tout fonctionne "proprement" va grandir. Si nous continuons comme cela, nous allons sûrement passer beaucoup de temps à tester notre code, et peu à l'améliorer.</p>
+
+<p>Les tests automatiques peuvent vraiment nous aider à régler ce problème. Les avantages évidents sont qu'ils peuvent être lancés bien rapidement que des tests manuels, peuvent réaliser des tests à un niveau bien plus bas de détail, et tester exactement les mêmes fonctionnalités à chaque fois (des testeurs humains sont loin d'être aussi fiables !). Parce qu'ils sont rapides, les tests automatisés peuvent être exécutés plus régulièrement, et si un test échoue, ils pointent exactement vers la partie du code qui n'a pas fonctionné comme prévu.</p>
+
+<p>De plus, les tests automatisés peuvent se comporter comme le premier "utilisateur" de votre code dans le monde réel, vous obligeant à être rigoureux quand vous définissez et documentez la manière dont votre site doit se comporter. Souvent ils constituent une base pour vos exemples et votre documentation. Pour ces raisons, il existe des processus de développement de logiciels qui commencent par la définition et l'implémentation de tests, et ce n'est qu'après que le code est écrit pour atteindre le comportement attendu (par ex. le développement <a href="https://en.wikipedia.org/wiki/Test-driven_development">test-driven</a> et le développement <a href="https://en.wikipedia.org/wiki/Behavior-driven_development">behaviour-driven</a>).</p>
+
+<p>Ce tutoriel montre comment écrire des tests automatisés pour Django, en ajoutant un certain nombre de tests au site web <em>LocalLibrary</em>.</p>
+
+<h3 id="Catégories_de_tests">Catégories de tests</h3>
+
+<p>Il y a beaucoup de genres, de niveaux et de classifications de tests, ainsi que de manières de tester. Les tests automatisés les plus importants sont:</p>
+
+<dl>
+ <dt>Les tests unitaires</dt>
+ <dd>Ils vérifient le comportement fonctionnel de composants individuels, souvent au niveau des classes et des fonctions.</dd>
+ <dt>Les tests de régression</dt>
+ <dd>Ce sont des tests qui reproduisent des bugs historiques. Chaque test a été lancé originellement pour vérifier que le bug a été résolu, et on le relance ensuite pour s'assurer qu'il n'a pas été ré-introduit suite aux changements de code.</dd>
+ <dt>Les test d'intégration</dt>
+ <dd>Ils vérifient comment les groupes de composants fonctionnent quand ils sont utilisés ensemble. Les tests d'intégraion sont attentifs aux interactions souhaitées entre composants, mais pas nécessairement aux opérations internes de chaque composant. Ils peuvent couvrir des groupes simples de composants à travers tout le site.</dd>
+</dl>
+
+<div class="note">
+<p><strong>Note : </strong>Les autres genres habituels de tests comprennent : la boîte noire, la boîte blanche, les tests manuels, automatiques, de canari (canary), de fumée (smoke), de conformité (conformance), d'approbation (acceptance), fonctionnels, système, performance, chargement et stress. Consultez pour plus d'information sur chacun d'eux.</p>
+</div>
+
+<h3 id="Que_fournit_Django_pour_tester">Que fournit Django pour tester ?</h3>
+
+<p>Tester un site web est une tâche complexe, car c'est une opération qui comporte plusieurs couches de logique : depuis la couche HTTP, la gestion des requêtes, les modèles d'interrogation de bases de données, jusqu'à la validation des formulaires, leur traitement et le rendu des templates.</p>
+
+<p>Django fournit un framework de test avec une petite hiérarchie de classes construites sur la librairie standard de Python <code><a href="https://docs.python.org/3/library/unittest.html#module-unittest" title="(in Python v3.5)">unittest</a></code>. Malgré son nom, ce framework de test est utilisable pour les tests unitaires aussi bien que pour les tests d'intégration. Le framework Django ajoute les méthodes et les outils d'une API pour aider à tester un site web et les comportements spécifiques à Django. Ces méthodes vous permettent de simuler des requêtes, d'insérer des données de test et d'inspecter la sortie de votre application. Django fournit aussi une API (<a href="https://docs.djangoproject.com/en/2.1/topics/testing/tools/#liveservertestcase">LiveServerTestCase</a>) et des outils pour <a href="https://docs.djangoproject.com/en/2.1/topics/testing/advanced/#other-testing-frameworks">utiliser d'autres frameworks de test</a>. Par exemple vous pouvez intégrer le célèbre framework <a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Your_own_automation_environment">Selenium</a> pour simuler l'interaction entre un utilisateur et un vrai navigateur.</p>
+
+<p>Pour écrire un test, vous partez de l'une des classes de test de base fournies par Django (ou par <em>unittest</em>) (<a href="https://docs.djangoproject.com/en/2.1/topics/testing/tools/#simpletestcase">SimpleTestCase</a>, <a href="https://docs.djangoproject.com/en/2.1/topics/testing/tools/#transactiontestcase">TransactionTestCase</a>, <a href="https://docs.djangoproject.com/en/2.1/topics/testing/tools/#testcase">TestCase</a>, <a href="https://docs.djangoproject.com/en/2.1/topics/testing/tools/#liveservertestcase">LiveServerTestCase</a>), et ensuite vous écrivez des méthodes séparées pour vérifier que telle fonctionnalité se comporte comme prévu (les tests utilisent des méthodes "assert" pour vérifier qu'une expression retourne <code>True</code> ou <code>False</code>, ou que deux valeurs sont égales, etc.). Quant vous commencez à lancer un test, le framework exécute les méthodes de test écrites dans vos classes dérivées. Les méthodes de test sont lancées de manière indépendante, avec en commun un réglage initial (<em>setUp</em>) et/ou un comportement de fin (<em>tearDown</em>) définis dans la classe, comme indiqué ci-dessous.</p>
+
+<pre class="brush: python">class YourTestClass(TestCase):
+    def setUp(self):
+  # Setup run before every test method.
+        pass
+
+    def tearDown(self):
+  # Clean up run after every test method.
+        pass
+
+    def test_something_that_will_pass(self):
+        self.assertFalse(False)
+
+    def test_something_that_will_fail(self):
+        self.assertTrue(False)
+</pre>
+
+<p>La meilleure classe de base pour la plupart des tests est <a href="https://docs.djangoproject.com/en/2.1/topics/testing/tools/#testcase">django.test.TestCase</a>. Cette classe de test crée une base de données vide avant que ses tests ne soient lancés, et lance toutes les fonctions de test dans sa propre transaction. La classe possède aussi un <a href="https://docs.djangoproject.com/en/2.1/topics/testing/tools/#django.test.Client" title="django.test.Client">Client</a> de test, que vous pouvez utiliser pour simuler l'interaction entre un utilisateur et le code au niveau de la vue. Dans les sections suivantes, nous allons nous concentrer sur les tests unitaires, créés en utilisant la classe de base <a href="https://docs.djangoproject.com/en/2.1/topics/testing/tools/#testcase">TestCase</a>.</p>
+
+<div class="note">
+<p><strong>Note :</strong> La classe <a href="https://docs.djangoproject.com/en/2.1/topics/testing/tools/#testcase">django.test.TestCase</a> est très commode, mais peut avoir pour effet de ralentir certains tests plus que nécessaire (tous les tests n'ont pas besoin de créer leur propre base de données ni de simuler une interaction au niveau de la vue). Une fois que vous serez familiarisé avec ce que vous pouvez faire avec cette classe, vous voudrez sans doute remplacer certains de vos tests avec d'autres classes plus simples parmi celles qui sont disponibles.</p>
+</div>
+
+<h3 id="Que_faut-il_tester">Que faut-il tester ?</h3>
+
+<p>Vous pouvez tester tous les aspects de votre code, mais non les librairies ou fonctionnalités faisant partie de Python ou de Django.</p>
+
+<p>Ainsi par exemple, considérez le modèle <code>Author</code> défini ci-dessous. Vous n'avez pas besoin de tester explicitement que <code>first_name</code> et <code>last_name</code> ont été stockés correctement comme <code>CharField</code> dans la base de données, car c'est là quelque chose de défini par Django (cependant, bien sûr, vous allez inévitablement tester cette fonctionnalité pendant le développement). Vous n'avez pas non plus besoin de tester que <code>date_of_birth</code> a été validé comme champ date, car, encore une fois, cela est implémenté par Django.</p>
+
+<p>En revanche, vous pouvez tester que les textes utilisés pour les labels (<em>First name, Last name, Date of birth, Died</em>), ainsi que le respect de la taille allouée au champ texte (100 caractères), car c'est là une partie de votre propre design et quelque chose qui pourrait être cassé/modifié dans le futur.</p>
+
+<pre class="brush: python">class Author(models.Model):
+    first_name = models.CharField(max_length=100)
+    last_name = models.CharField(max_length=100)
+    date_of_birth = models.DateField(null=True, blank=True)
+    date_of_death = models.DateField('Died', null=True, blank=True)
+
+    def get_absolute_url(self):
+        return reverse('author-detail', args=[str(self.id)])
+
+    def __str__(self):
+        return '%s, %s' % (self.last_name, self.first_name)</pre>
+
+<p>De même, vous pouvez tester que les méthodes personnalisées <code style="font-style: normal; font-weight: normal;">get_absolute_url()</code> et <code style="font-style: normal; font-weight: normal;">__str__()</code> se comportent comme prévu, car elles appartiennent à votre logique code/métier. Dans le cas de <code style="font-style: normal; font-weight: normal;">get_absolute_url()</code>, vous pouvez supposer que la méthode Django <code>reverse()</code> a été implémentée correctement, aussi ce que vous allez tester, c'est que la vue associée a été effectivement définie.</p>
+
+<div class="note">
+<p><strong>Note :</strong> Les lecteurs attentifs auront noté que nous pourrions aussi vouloir limiter les dates de naissance et de décès à des valeurs sensibles, et vérifier que le décès intervient après la naissance. En Django, cette contrainte est ajoutée à vos classes de formulaires (bien que vous puissiez définir des validateurs pour les champs du modèle et des validateurs de modèles, ceux-ci ne sont utilisés qu'au niveau du formulaire s'ils sont appelés par la méthode clean() du modèle. Cela requière un ModelForm ou bien la méthode clean() du modèle a besoin d'être appelée explicitement.)</p>
+</div>
+
+<p>Avec cela en tête, commençons à voir comment définir et lancer des tests.</p>
+
+<h2 id="Vue_densemble_de_la_structure_de_test">Vue d'ensemble de la structure de test</h2>
+
+<p>Avant d'entrer dans le détail de "que tester", voyons d'abord brièvement <em>où</em> et <em>comment</em> les tests sont définis.</p>
+
+<p>Django utilise le <a href="https://docs.python.org/3/library/unittest.html#unittest-test-discovery" title="(in Python v3.5)">built-in test discovery</a> du module unittest, qui va chercher des tests, sous le répertoire de travail actuel, dans tous les fichiers dont le nom contient le pattern<strong> test*.py</strong>. Du moment que vous nommez vos fichiers de manière appropriée, vous pouvez utiliser n'importe quelle structure. Nous vous recommandons de créer un module pour coder vos tests, et d'avoir des fichiers distincts pour les modèles, les vues, les formulaires et tout autre type de code que vous avez besoin de tester. Par exemple :</p>
+
+<pre>catalog/
+  /tests/
+  __init__.py
+  test_models.py
+  test_forms.py
+  test_views.py
+</pre>
+
+<p>Créez une structure de fichier comme montré ci-dessus, dans votre projet <em>LocalLibrary</em>. Le ficheir<strong> __init__.py</strong> doit être vide (il dit simplement à Python que ce répertoire est un package). Vous pouvez créer les trois fichiers de test en copiant et renommant le fichier de test du squelette <strong>/catalog/tests.py</strong>.</p>
+
+<div class="note">
+<p><strong>Note :</strong> le fichier de test du squelette <strong>/catalog/tests.py</strong> a été créé automatiquement quand nous avons <a href="/en-US/docs/Learn/Server-side/Django/skeleton_website">construit le squelette du site web Django</a>. Il est parfaitement "légal" de mettre tous vos tests dedans, mais si vous testez correctement, vous allez rapidement vous retrouver avec un fichier de test énorme et impossible à gérer.</p>
+
+<p>Supprimez le fichier de squelette, car nous n'en aurons plus besoin.</p>
+</div>
+
+<p>Ouvrez le fichier <strong>/catalog/tests/test_models.py</strong>. Ce fichier doit importer <code>django.test.TestCase</code>, comme indiqué ci-après :</p>
+
+<p>Open <strong>/catalog/tests/test_models.py</strong>. The file should import <code>django.test.TestCase</code>, as shown:</p>
+
+<pre class="brush: python">from django.test import TestCase
+
+# Create your tests here.
+</pre>
+
+<p>Souvent vous voudrez ajouter une classe de test pour chaque modèle/vue/form que vous voulez tester, avec des méthodes individuelles pour tester une fonctionnalité spécifique. Dans d'autres cas vous pourriez souhaiter avoir une class séparée pour tester un cas d'utilisation spécifique, avec des fonctions de test individuelles pour tester les aspects de ce cas d'utilisation (par exemple, une classe pour tester que tel champ d'un modèle est validé correctement, avec des fonctions pour tester chaque possibilité d'échec). Encore une fois, c'est à vous de décider de la structure à adopter, mais elle sera meilleure si vous êtes cohérent.</p>
+
+<p>Ajoutez la classe de test ci-dessous à la fin du fichier. La classe montre comment construire une classe de test de cas dérivant de <code>TestCase</code>.</p>
+
+<pre class="brush: python">class YourTestClass(TestCase):
+    @classmethod
+    def setUpTestData(cls):
+        print("setUpTestData: Run once to set up non-modified data for all class methods.")
+        pass
+
+    def setUp(self):
+        print("setUp: Run once for every test method to setup clean data.")
+        pass
+
+    def test_false_is_false(self):
+        print("Method: test_false_is_false.")
+        self.assertFalse(False)
+
+    def test_false_is_true(self):
+        print("Method: test_false_is_true.")
+        self.assertTrue(False)
+
+    def test_one_plus_one_equals_two(self):
+        print("Method: test_one_plus_one_equals_two.")
+        self.assertEqual(1 + 1, 2)</pre>
+
+<p>La nouvelle classe définit deux méthodes que vous pouvez utiliser pour une configuration pré-test (par exemple, pour créer des modèles ou d'autres objets dont vous aurez besoin pour les tests) :</p>
+
+<ul>
+ <li><code>setUpTestData()</code> est appelée une fois au début du lancement des tests pour un réglage au niveau de la classe. Vous pouvez l'utiliser pour créer des objets qui ne sont pas destinés à être modifiés ou changés dans les méthodes de test.</li>
+ <li><code>setUp()</code> est appelée avant chaque fonction de test pour définir des objets qui peuvent être modifiés par le test (chaque fonction de test obtiendra une version "fraîche" de ces objets).</li>
+</ul>
+
+<div class="note">
+<p>Les classes de test ont aussi une méthode <code>tearDown()</code>, que nous n'avons pas utilisée. Cette méthode n'est pas particulièrement utile pour les tests avec bases de données, dans la mesure où la classe de base <code>TestCase</code> prend soin pour vous de supprimer la base de données utilisées pour les tests.</p>
+</div>
+
+<p>En dessous de ces méthodes, nous avons un certain nombre de méthodes de test, qui utilisent des fonctions <code>Assert</code>, pour tester si certaines conditions sont vraies, fausses ou égales (<code>AssertTrue</code>, <code>AssertFalse</code>, <code>AssertEqual</code>). Si la condition ne renvoie pas le résultat escompté, le test plante et renvoie une erreur à votre console.</p>
+
+<p>Les méthodes <code>AssertTrue</code>, <code>AssertFalse</code> et <code>AssertEqual</code> sont des assertions standard fournies par <strong>unittest</strong>. Il y a d'autres assertions standard dans le framework, et aussi des <a href="https://docs.djangoproject.com/en/2.1/topics/testing/tools/#assertions">assertions spécifiques à Django</a>, pour tester si une vue redirige (<code>assertRedirects</code>), pour tester si tel template a été utilisé (<code>assertTemplateUsed</code>), etc.</p>
+
+<div class="note">
+<p>Normallement vous ne devriez <strong>pas</strong> inclure de fonctions <strong>print()</strong> dans vos tests, comme montré ci-dessus. Nous avons fait cela uniquement pour que vous puissiez voir dans la console (dans la section suivante) l'ordre dans lequel les fonctions de setup sont appelées.</p>
+</div>
+
+<h2 id="Comment_lancer_les_tests">Comment lancer les tests</h2>
+
+<p>La manière la plus facile pour lancer tous les tests est d'utiliser la commande :</p>
+
+<pre class="brush: bash">python3 manage.py test</pre>
+
+<p>Cette commande va lancer la recherche de tous les fichiers ayant la forme <strong>test*.py</strong> sous le répertoire courant, et lancer tous les tests définis, en utilisant les classes de base appropriées (ici nous avons un certain nombre de fichiers de test, mais pour le moment seul <strong>/catalog/tests/test_models.py</strong> contient des tests). Par défaut, chaque test ne fera de rapport qu'en cas d'échec, avec ensuite un résumé du test.</p>
+
+<div class="note">
+<p>Si vous obtenez des erreurs telles que : <code>ValueError: Missing staticfiles manifest entry ...</code>, cela peut être dû au fait que le test ne lance pas <em>collectstatic</em> par défaut, et que votre application utilise une classe de storage qui le requiert (voyez <a href="https://docs.djangoproject.com/en/2.1/ref/contrib/staticfiles/#django.contrib.staticfiles.storage.ManifestStaticFilesStorage.manifest_strict">manifest_strict</a> pour plus d'information). Il y a plusieurs façons de remédier à ce problème - la plus facile est de lancer tout simplement <em>collectstatic</em> avant de lancer les tests :</p>
+
+<pre class="brush: bash">python3 manage.py collectstatic
+</pre>
+</div>
+
+<p>Lancez les tests dans le répertoire racine de <em>LocalLibrary</em>. Vous devriez voir une sortie semblable à celle ci-dessous.</p>
+
+<pre class="brush: bash">&gt; python3 manage.py test
+
+Creating test database for alias 'default'...
+<strong>setUpTestData: Run once to set up non-modified data for all class methods.
+setUp: Run once for every test method to setup clean data.
+Method: test_false_is_false.
+setUp: Run once for every test method to setup clean data.
+Method: test_false_is_true.
+setUp: Run once for every test method to setup clean data.
+Method: test_one_plus_one_equals_two.</strong>
+.
+======================================================================
+FAIL: test_false_is_true (catalog.tests.tests_models.YourTestClass)
+----------------------------------------------------------------------
+Traceback (most recent call last):
+  File "D:\Github\django_tmp\library_w_t_2\locallibrary\catalog\tests\tests_models.py", line 22, in test_false_is_true
+    self.assertTrue(False)
+AssertionError: False is not true
+
+----------------------------------------------------------------------
+Ran 3 tests in 0.075s
+
+FAILED (failures=1)
+Destroying test database for alias 'default'...</pre>
+
+<p>Ici nous voyons que nous avons eu un échec pour un test, et nous pouvons voir exactement quelle fonction a planté et pourquoi (cet échec était prévu, car <code>False</code> n'est pas <code>True</code> !).</p>
+
+<div class="note">
+<p><strong>Truc: </strong>La chose la plus importante à apprendre de la sortie de test ci-dessus est qu'il est bien mieux d'utiliser des noms descriptifs/informatifs pour vos objets et méthodes.</p>
+</div>
+
+<p>Le texte en <strong>gras</strong> ci-dessus n'apparaîtra pas normalement dans la sortie de test (elle est générée par les fonctions <code>print()</code> dans nos tests). Cela montre comment la méthode <code>setUpTestData()</code> est appelée une fois pour l'ensemble de classe, tandis que <code>setUp()</code> est appelée avant chaque méthode.</p>
+
+<p>La section suivante mnotre comment vous pouvez lancer des test spécifiques, et comment contrôler la quantité d'information fournie par les tests.</p>
+
+<h3 id="Montrer_plus_dinformations_à_propos_du_test">Montrer plus d'informations à propos du test</h3>
+
+<p>Si vous souhaitez obtenir plus d'informations à propos du test lancé, vous pouvez changer sa <em>verbosité</em>. Par exemple, pour faire la liste de ce qui a fonctionné dans le test, comme de ce qui a échoué (ainsi que tout un tas d'informations sur la manière dont la base de données à été initialisée), vous pouvez mettre la verbosité à "2", comme indiqué ci-dessous :</p>
+
+<pre class="brush: bash">python3 manage.py test --verbosity 2</pre>
+
+<p>Les niveaux de verbosité sont 0, 1, 2 et 3, avec "1" comme valeur par défaut.</p>
+
+<h3 id="Lancer_des_tests_spécifiques">Lancer des tests spécifiques</h3>
+
+<p>Si vous voulez lancer une sous-sélection parmi vos tests, vous pouvez le faire en spécifiant le chemin complet (avec des points) vers le ou les package(s), module, sous-classe de <code>TestCase</code> ou méthode :</p>
+
+<pre class="brush: bash"># Run the specified module
+python3 manage.py test catalog.tests
+
+# Run the specified module
+python3 manage.py test catalog.tests.test_models
+
+# Run the specified class
+python3 manage.py test catalog.tests.test_models.YourTestClass
+
+# Run the specified method
+python3 manage.py test catalog.tests.test_models.YourTestClass.test_one_plus_one_equals_two
+</pre>
+
+<h2 id="Tests_de_LocalLibrary">Tests de LocalLibrary</h2>
+
+<p>Maintenant que nous savons comment lancer nos tests et quel genre de choses nous avons besoin de tester, regardons quelques exemples pratiques.</p>
+
+<div class="note">
+<p><strong>Note : </strong>Nous n'allons pas écrire tous les tests possibles, mais ce qui suit devrait vous donner une idée sur le fonctionnement des tests, et ce que vous pouvez faire ensuite.</p>
+</div>
+
+<h3 id="Modèles">Modèles</h3>
+
+<p>Comme nous l'avons dit ci-dessus, nous devrions tester tout ce qui relève de notre design, ou tout ce qui est défini par du code que nous avons écrit nous-mêmes, mais pas les bibliothèques ou le code qui est déjà testé par Django ou par l'équipe qui développe Python.</p>
+
+<p>Par exemple, considérez le modèle <code>Author</code> ci-dessous. Ici nous devrions tester les labels de tous les champs, car, bien que nous n'ayons pas explicitement spécifié la plupart d'entre eux, nous avons un design qui dit ce que ces valeurs devraient être. Si nous ne testons pas ces valeurs, nous ne savons pas que les labels des champs ont les valeurs souhaitées. De même, alors que nous sommes tranquilles sur le fait que Django créera un champ de la longueur indiquée, il est intéressant de lancer un test spécifique pour s'assurer qu'il a été implémenté comme prévu.</p>
+
+<pre class="brush: python">class Author(models.Model):
+    first_name = models.CharField(max_length=100)
+    last_name = models.CharField(max_length=100)
+    date_of_birth = models.DateField(null=True, blank=True)
+    date_of_death = models.DateField('Died', null=True, blank=True)
+
+    def get_absolute_url(self):
+        return reverse('author-detail', args=[str(self.id)])
+
+    def __str__(self):
+        return f'{self.last_name}, {self.first_name}'</pre>
+
+<p>Ouvrez notre <strong>/catalog/tests/test_models.py</strong>, et remplacez tout le code qui s'y trouve par le code de test ci-après pour le modèle <code>Author</code>.</p>
+
+<p>Vous voyez que nous importons d'abord <code>TestCase</code> et faisons dériver d'elle notre classe de test (<code>AuthorModelTest</code>) en utilisant un nom descriptif, de façon à pouvoir identifier aisément dans la sortie tout test qui échoue. Nous appelons ensuite <code>setUpTestData()</code> afin de créer un objet <em>author</em>, que nous utiliserons mais que nous ne modifierons jamais dans aucun de nos tests.</p>
+
+<pre class="brush: python">from django.test import TestCase
+
+from catalog.models import Author
+
+class AuthorModelTest(TestCase):
+ @classmethod
+ def setUpTestData(cls):
+ # Set up non-modified objects used by all test methods
+ Author.objects.create(first_name='Big', last_name='Bob')
+
+ def test_first_name_label(self):
+ author = Author.objects.get(id=1)
+ field_label = author._meta.get_field('first_name').verbose_name
+ self.assertEquals(field_label, 'first name')
+
+ def test_date_of_death_label(self):
+ author=Author.objects.get(id=1)
+ field_label = author._meta.get_field('date_of_death').verbose_name
+ self.assertEquals(field_label, 'died')
+
+ def test_first_name_max_length(self):
+ author = Author.objects.get(id=1)
+ max_length = author._meta.get_field('first_name').max_length
+ self.assertEquals(max_length, 100)
+
+ def test_object_name_is_last_name_comma_first_name(self):
+ author = Author.objects.get(id=1)
+ expected_object_name = f'{author.last_name}, {author.first_name}'
+ self.assertEquals(expected_object_name, str(author))
+
+ def test_get_absolute_url(self):
+ author = Author.objects.get(id=1)
+ # This will also fail if the urlconf is not defined.
+ self.assertEquals(author.get_absolute_url(), '/catalog/author/1')</pre>
+
+<p>Les tests de champ vérifient que les valeurs des labels de champ (<code>verbose_name</code>) et que la taille des champs de type <em>character</em> sont tels que nous les souhaitons. Ces méthodes ont toutes des noms descriptifs et suivent le même pattern :</p>
+
+<pre class="brush: python"># Get an author object to test
+author = Author.objects.get(id=1)
+
+# Get the metadata for the required field and use it to query the required field data
+field_label = author._meta.get_field('first_name').verbose_name
+
+# Compare the value to the expected result
+self.assertEquals(field_label, 'first name')</pre>
+
+<p>Les choses intéressantes à noter sont :</p>
+
+<ul>
+ <li>Nous ne pouvons obtenir le <code>verbose_name</code> directement en utilisant <code>author.first_name.verbose_name</code>, car <code>author.first_name</code> est une <em>chaîne</em> (non un moyen d'accéder à l'objet <code>first_name</code>, que nous pourrions utiliser pour accéder à ses propriétés). À la place nous devons utiliser l'attribut <code>_meta</code> de author afin d'obtenir une instance de ses champs et utiliser celle-ci pour demander l'information que nous cherchons.</li>
+ <li>Nous avons fait le choix d'utiliser <code>assertEquals(field_label,'first name')</code> plutôt que <code>assertTrue(field_label == 'first name')</code>. La raison en est que, en cas d'échec du test, la sortie vous dira, dans le premier cas, quel est effectivement le label du champ, ce qui rend un peu plus facile le débogage du problème.</li>
+</ul>
+
+<div class="note">
+<p><strong>Note :</strong> Les tests pour les labels de <code>last_name</code> et <code>date_of_birth</code>, ainsi que le test de la longueur du champ <code>last_name</code>, ont été omis. Ajoutez vos propres versions maintenant, en suivant les conventions de nommage et les approches que nous vous avons montrées ci-dessus.</p>
+</div>
+
+<p>Il nous faut également tester nos méthodes personnalisées. Essentiellement, celles-ci vérifient uniquement que le nom de l'objet a été construit comme prévu, en utilisant le format "Last name", "First name", et que l'URL que nous obtenons pour un élément <code>Author</code> est telle que nous l'attendons.</p>
+
+<pre class="brush: python">def test_object_name_is_last_name_comma_first_name(self):
+    author = Author.objects.get(id=1)
+    expected_object_name = f'{author.last_name}, {author.first_name}'
+    self.assertEquals(expected_object_name, str(author))
+
+def test_get_absolute_url(self):
+    author = Author.objects.get(id=1)
+    # This will also fail if the urlconf is not defined.
+    self.assertEquals(author.get_absolute_url(), '/catalog/author/1')</pre>
+
+<p>Maintenant lancez les tests. Si vous avez créé le modèle <code>Author</code> comme décrit dans le tutoriel sur les modèles, il est assez probable que vous allez obtenir une erreur pour le label <code>date_of_death</code>, comme montré ci-dessous. Le test plante parce qu'il a été écrit en s'attendant à ce que la définition du label suive cette convention de Django : ne pas mettre en capitale la première lettre du label (Django le fait pour vous).</p>
+
+<pre class="brush: bash">======================================================================
+FAIL: test_date_of_death_label (catalog.tests.test_models.AuthorModelTest)
+----------------------------------------------------------------------
+Traceback (most recent call last):
+ File "D:\...\locallibrary\catalog\tests\test_models.py", line 32, in test_date_of_death_label
+ self.assertEquals(field_label,'died')
+AssertionError: 'Died' != 'died'
+- Died
+? ^
++ died
+? ^</pre>
+
+<p>C'est vraiment un bug mineur, mais il met en lumière comment écrire des test peut vérifier de plus près les hypothèses que vous pourriez avoir supposées vraies.</p>
+
+<div class="note">
+<p><strong>Note : </strong>Changez en "died" le label pour le champ date_of_death (/catalog/models.py) et relancez les tests.</p>
+</div>
+
+<p>La configuration pour tester les autres modèles est semblable pour tous, aussi nous n'allons pas discuter chacune plus longuement. Sentez-vous libre de créer vos propres tests pour nos autres modèles.</p>
+
+<h3 id="Les_Formulaires">Les Formulaires</h3>
+
+<p>La philosophie pour tester vos formulaires est la même que pour tester vos modèles: vous avez besoin de tester tout ce que vous avez codé ou les spécificités de votre design, mais non le comportement du framework sous-jacent, ni celui des autres bibliothèques tierces.</p>
+
+<p>Généralement, cela signifie que vous devriez tester que les formulaires ont bien les champs que vous voulez, et qu'ils sont rendus avec les bons labels et textes d'aide. Vous n'avez pas besoin de vérifier que Django valide correctement les champs selon leurs types (à moins que vous n'ayez créé vos propres champs personnalisés et leurs validations) ; c'est-à-dire que vous n'avez pas besoin de tester qu'un champ email n'accepte que des emails. Cependant vous pouvez avoir besoin de tester toute validation complémentaire que vous vous attendez à voir réalisée sur les champs, et tout message d'erreur généré par votre code.</p>
+
+<p>Considérez notre formulaire pour renouveler les livres. Il a seulement 1 champ pour la date de renouvellement, qui va avoir un label et un texte d'aide que nous avons besoin de vérifier.</p>
+
+<pre class="brush: python">class RenewBookForm(forms.Form):
+ """Form for a librarian to renew books."""
+ renewal_date = forms.DateField(help_text="Enter a date between now and 4 weeks (default 3).")
+
+ def clean_renewal_date(self):
+ data = self.cleaned_data['renewal_date']
+
+ # Check if a date is not in the past.
+ if data &lt; datetime.date.today():
+ raise ValidationError(_('Invalid date - renewal in past'))
+
+ # Check if date is in the allowed range (+4 weeks from today).
+ if data &gt; datetime.date.today() + datetime.timedelta(weeks=4):
+ raise ValidationError(_('Invalid date - renewal more than 4 weeks ahead'))
+
+ # Remember to always return the cleaned data.
+ return data</pre>
+
+<p>Ouvrez notre fichier <strong>/catalog/tests/test_forms.py</strong>, et remplacez tout le code qui s'y trouve par le code suivant, qui teste le formulaire <code>RenewBookForm</code>. Nous commençons par importer notre formulaire et des bibliothèques Python et Django pour tester les fonctionnalités liées au temps. Ensuite nous déclarons notre classe de test pour formulaire de la même manière que nous l'avons fait pour les modèles, en utilisant un nom descriptif pour notre classe de test dérivée de <code>TestCase</code>.</p>
+
+<pre class="brush: python">import datetime
+
+from django.test import TestCase
+from django.utils import timezone
+
+from catalog.forms import RenewBookForm
+
+class RenewBookFormTest(TestCase):
+    def test_renew_form_date_field_label(self):
+        form = RenewBookForm()
+        self.assertTrue(form.fields['renewal_date'].label == None or form.fields['renewal_date'].label == 'renewal date')
+
+    def test_renew_form_date_field_help_text(self):
+        form = RenewBookForm()
+        self.assertEqual(form.fields['renewal_date'].help_text, 'Enter a date between now and 4 weeks (default 3).')
+
+    def test_renew_form_date_in_past(self):
+        date = datetime.date.today() - datetime.timedelta(days=1)
+        form = RenewBookForm(data={'renewal_date': date})
+        self.assertFalse(form.is_valid())
+
+    def test_renew_form_date_too_far_in_future(self):
+        date = datetime.date.today() + datetime.timedelta(weeks=4) + datetime.timedelta(days=1)
+        form = RenewBookForm(data={'renewal_date': date})
+        self.assertFalse(form.is_valid())
+
+    def test_renew_form_date_today(self):
+        date = datetime.date.today()
+        form = RenewBookForm(data={'renewal_date': date})
+        self.assertTrue(form.is_valid())
+
+    def test_renew_form_date_max(self):
+        date = timezone.localtime() + datetime.timedelta(weeks=4)
+        form = RenewBookForm(data={'renewal_date': date})
+        self.assertTrue(form.is_valid())
+</pre>
+
+<p>Les deux premières fonctions testent que le <code>label</code> et le <code>help_text</code> du champ sont tels qu'on les attend. Nous devons accéder au champ en utilisant le dictionnaire du champ (p. ex. <code>form.fields['renewal_date']</code>). Notez bien ici que nous devons aussi tester si la valeur du label est <code>None</code>, car même si Django rend le label correct, il retournera <code>None</code> si la valeur n'est pas définie <em>explicitement</em>.</p>
+
+<p>Les autres fonctions testent que le formulaire est valide avec des dates de renouvellement situées à l'intérieur des limites acceptables, et invalide avec des valeurs en dehors de ces limites. Notez comment nous construisons des valeurs de dates de test autour de notre date actuelle (<code>datetime.date.today()</code>) en utilisant <code>datetime.timedelta()</code> (dans ce cas en spécifiant un nombre de jours ou de semaines). Ensuite nous créons juste le formulaire en lui passant nos données, et nous testons s'il est valide.</p>
+
+<div class="note">
+<p><strong>Note :</strong> Ici nous n'utilisons pas réellement la base de données ni le client de test. Envisagez de modifier ces tests pour utiliser <a href="https://docs.djangoproject.com/en/2.1/topics/testing/tools/#django.test.SimpleTestCase">SimpleTestCase</a>.</p>
+
+<p>Nous avons aussi besoin de vérifier que les erreurs correctes sont levées si le formulaire est invalide. Cependant cela se fait habituellement dans la partie view, c'est pourquoi nous allons nous y attacher dans la prochaine section.</p>
+</div>
+
+<p>C'est tout pour les formulaires; nous en avons d'autres, mais ils sont automatiquement créés par nos vues génériques pour édition basées sur des classes, et c'est là qu'elles doivent être testées. Lancez les tests et vérifiez que notre code passe toujours !</p>
+
+<h3 id="Vues">Vues</h3>
+
+<p>Pour valider le comportement de notre vue, nous utilisons le <a href="https://docs.djangoproject.com/en/2.1/topics/testing/tools/#django.test.Client">client</a> de test de Django. Cette classe se comporte comme un navigateur web fictif que nous pouvons utiliser pour simuler des requêtes <code>GET</code> et <code>POST</code> à une URL donnée, et observer la réponse. Nous pouvons voir à peu près tout au sujet de la réponse, depuis le HTTP bas-niveau (entêtes et codes de statut résultants) jusqu'au template que nous utilisons pour rendre le HTML et aux données de contexte que nous lui passons. Nous pouvons aussi voir la chaîne des redirections (s'il y en a) et vérifier l'URL et le code de statut à chaque étape. Cela nous permet de vérifier que chaque vue se comporte comme prévu.</p>
+
+<p>Commençons avec l'une de nos vues les plus simples, celle qui fournit une liste de tous les auteurs. Elle est affichée à l'URL <strong>/catalog/authors/</strong> (une URL nommée 'authors' dans la configuration des URL).</p>
+
+<pre class="brush: python">class AuthorListView(generic.ListView):
+ model = Author
+ paginate_by = 10
+</pre>
+
+<p>Comme c'est une vue liste générique, presque tout est fait à notre place par Django. Probablement, si vous faites confiance à Django, la seule chose que vous aurez besoin de tester, c'est que la vue est accessible à l'URL correcte et qu'elle peut être atteinte en utilisant son nom. Cependant, si vous utilisez un processus de développement 'test-driven', vous allez commencer par écrire des tests qui confirmeront que la vue affiche bien tous les auteurs, en les paginant par lots de 10.</p>
+
+<p>Ouvrez le fichier <strong>/catalog/tests/test_views.py</strong>, et remplacez tout texte existant par le code de test suivant, pour la vue <code>AuthorListView</code>. Comme auparavant, nous importons notre modèle et quelques classes utiles. Dans la méthode <code>setUpTestData()</code>, nous définissons un certain nombre d'objets <code>Author</code>, de façon à pouvoir tester notre pagination.</p>
+
+<pre class="brush: python">from django.test import TestCase
+from django.urls import reverse
+
+from catalog.models import Author
+
+class AuthorListViewTest(TestCase):
+    @classmethod
+    def setUpTestData(cls):
+        # Create 13 authors for pagination tests
+        number_of_authors = 13
+
+        for author_id in range(number_of_authors):
+            Author.objects.create(
+ first_name=f'Christian {author_id}',
+ last_name=f'Surname {author_id}',
+ )
+
+    def test_view_url_exists_at_desired_location(self):
+        response = self.client.get('/catalog/authors/')
+        self.assertEqual(response.status_code, 200)
+
+    def test_view_url_accessible_by_name(self):
+        response = self.client.get(reverse('authors'))
+        self.assertEqual(response.status_code, 200)
+
+    def test_view_uses_correct_template(self):
+        response = self.client.get(reverse('authors'))
+        self.assertEqual(response.status_code, 200)
+        self.assertTemplateUsed(response, 'catalog/author_list.html')
+
+    def test_pagination_is_ten(self):
+        response = self.client.get(reverse('authors'))
+        self.assertEqual(response.status_code, 200)
+        self.assertTrue('is_paginated' in response.context)
+        self.assertTrue(response.context['is_paginated'] == True)
+        self.assertTrue(len(response.context['author_list']) == 10)
+
+    def test_lists_all_authors(self):
+        # Get second page and confirm it has (exactly) remaining 3 items
+        response = self.client.get(reverse('authors')+'?page=2')
+        self.assertEqual(response.status_code, 200)
+        self.assertTrue('is_paginated' in response.context)
+        self.assertTrue(response.context['is_paginated'] == True)
+        self.assertTrue(len(response.context['author_list']) == 3)</pre>
+
+<p>Tous les tests utilisent le client (qui appartient à notre classe dérivée de <code>TestCase</code>), afin de simuler une requête <code>GET</code> et d'obtenir une réponse. La première version vérifie une URL spécifique (note : seulement le chemin spécifique, sans le domaine), tandis que la seconde génère une URL à partir de son nom tel qu'il se trouve dans la configuration des URL.</p>
+
+<pre class="brush: python">response = self.client.get('/catalog/authors/')
+response = self.client.get(reverse('authors'))
+</pre>
+
+<p>Une fois que nous avons la réponse, nous lui demandons son code de statut, le template utilisé, si la réponse est paginée ou non, le nombre d'éléments retournés et le nombre total d'éléments.</p>
+
+<div class="blockIndicator note">
+<p class="brush: python"><strong>Note :</strong> Si, dans votre fichier <strong>/c</strong><strong>atalog/views.py</strong>, vous mettez la variable <code>paginate_by</code> à un nombre autre que 10, assurez-vous de mettre à jour les lignes qui testent le nombre correct d'éléments affichés dans les templates paginés, ci-dessus et dans les sections qui suivent. Par exemple, si vous mettez à 5 la variable pour la liste des auteurs, changez ainsi la ligne ci-dessus :</p>
+
+<pre class="brush: python">self.assertTrue(len(response.context['author_list']) == 5)
+</pre>
+</div>
+
+<p>La variable la plus intéressante que nous montrons ci-dessus est <code>response.context</code>, qui est la variable de contexte passée au template par la vue. C'est incroyablement utile pour tester, parce qu'elle nous autorise à confirmer que notre template reçoit bien toutes les données dont il a besoin. En d'autres termes, nous pouvons vérifier que nous utilisons le template prévu, et quelles données le template utilise, ce qui permet dans une large mesure de vérifier que tous les problèmes de 'render' sont seulement dus au template.</p>
+
+<h4 id="Vues_limitées_aux_utilisateurs_connectés">Vues limitées aux utilisateurs connectés</h4>
+
+<p>Dans certains cas, vous voudrez tester une vue qui est limitée aux seuls utilisateurs connectés. Par exemple notre vue <code>LoanedBooksByUserListView</code> est très semblable à notre vue précédente, mais n'est accessible qu'aux utilisateurs connectés, et n'affiche que des enregistrements de type <code>BookInstance</code> qui sont empruntés par l'utilisateur courant, ont le statut 'on loan', et sont triés 'le plus ancien en premier'.</p>
+
+<pre class="brush: python">from django.contrib.auth.mixins import LoginRequiredMixin
+
+class LoanedBooksByUserListView(LoginRequiredMixin, generic.ListView):
+ """Generic class-based view listing books on loan to current user."""
+ model = BookInstance
+ template_name ='catalog/bookinstance_list_borrowed_user.html'
+ paginate_by = 10
+
+ def get_queryset(self):
+ return BookInstance.objects.filter(borrower=self.request.user).filter(status__exact='o').order_by('due_back')</pre>
+
+<p>Ajoutez le code de test suivant à <strong>/catalog/tests/test_views.py</strong>. Ici nous utilisons d'abord la méthode <code>SetUp()</code> pour créer des logins de comptes d'utilisateurs et des objets de type <code>BookInstance</code> (avec leurs livres et autres enregistrements associés), que nous utiliserons plus tard dans les tests. La moitié des livres sont empruntés par chaque utilisateur-test, mais nous avons initialement mis le statut de tous les livres à "maintenance". Nous avons utilisé <code>SetUp()</code> plutôt que <code>setUpTestData()</code>, parce que nous allons modifier plus tard certains de ces objets.</p>
+
+<div class="note">
+<p><strong>Note :</strong> Le code de <code>setUp()</code> ci-dessous crée un livre avec un <code>Language</code> spécifique, mais <em>votre</em> code n'inclut peut-être pas le modèle <code>Language</code>, étant donné que celui-ci a été créé lors d'un <em>défi</em>. Si c'est le cas, commentez simplement les bouts de code qui créent ou importent des objets de type Language. Vous devrez aussi le faire dans la section <code>RenewBookInstancesViewTest</code> qui suit.</p>
+</div>
+
+<pre class="brush: python">import datetime
+
+from django.utils import timezone
+from django.contrib.auth.models import User # Required to assign User as a borrower
+
+from catalog.models import BookInstance, Book, Genre, Language
+
+class LoanedBookInstancesByUserListViewTest(TestCase):
+    def setUp(self):
+        # Create two users
+        test_user1 = User.objects.create_user(username='testuser1', password='1X&lt;ISRUkw+tuK')
+        test_user2 = User.objects.create_user(username='testuser2', password='2HJ1vRV0Z&amp;3iD')
+
+ test_user1.save()
+        test_user2.save()
+
+        # Create a book
+        test_author = Author.objects.create(first_name='John', last_name='Smith')
+        test_genre = Genre.objects.create(name='Fantasy')
+        test_language = Language.objects.create(name='English')
+        test_book = Book.objects.create(
+ title='Book Title',
+ summary='My book summary',
+ isbn='ABCDEFG',
+ author=test_author,
+ language=test_language,
+ )
+
+ # Create genre as a post-step
+        genre_objects_for_book = Genre.objects.all()
+  test_book.genre.set(genre_objects_for_book) # Direct assignment of many-to-many types not allowed.
+        test_book.save()
+
+        # Create 30 BookInstance objects
+        number_of_book_copies = 30
+        for book_copy in range(number_of_book_copies):
+            return_date = timezone.localtime() + datetime.timedelta(days=book_copy%5)
+            the_borrower = test_user1 if book_copy % 2 else test_user2
+            status = 'm'
+            BookInstance.objects.create(
+ book=test_book,
+ imprint='Unlikely Imprint, 2016',
+ due_back=return_date,
+ borrower=the_borrower,
+ status=status,
+ )
+
+    def test_redirect_if_not_logged_in(self):
+        response = self.client.get(reverse('my-borrowed'))
+        self.assertRedirects(response, '/accounts/login/?next=/catalog/mybooks/')
+
+    def test_logged_in_uses_correct_template(self):
+        login = self.client.login(username='testuser1', password='1X&lt;ISRUkw+tuK')
+        response = self.client.get(reverse('my-borrowed'))
+
+        # Check our user is logged in
+        self.assertEqual(str(response.context['user']), 'testuser1')
+        # Check that we got a response "success"
+        self.assertEqual(response.status_code, 200)
+
+        # Check we used correct template
+        self.assertTemplateUsed(response, 'catalog/bookinstance_list_borrowed_user.html')
+</pre>
+
+<p>Pour vérifier que la vue redirige à une page de login si l'utilisateur n'est pas connecté, nous utilisons <code>assertRedirects</code>, comme montré dans <code>test_redirect_if_not_logged_in()</code>. Pour vérifier que la page est affichée pour un utilisateur connecté, nous connectons d'abord notre utilisateur-test, et ensuite nous accédons de nouveau à la page et vérifions que nous obtenons un <code>status_code</code> de 200 (succès).</p>
+
+<p>Le reste des test vérifie que notre vue ne retourne que les livres qui sont prêtés à notre emprunteur courant. Copiez ce code et collez le à la fin de la classe de test ci-dessus.</p>
+
+<pre class="brush: python">    def test_only_borrowed_books_in_list(self):
+        login = self.client.login(username='testuser1', password='1X&lt;ISRUkw+tuK')
+        response = self.client.get(reverse('my-borrowed'))
+
+        # Check our user is logged in
+        self.assertEqual(str(response.context['user']), 'testuser1')
+        # Check that we got a response "success"
+        self.assertEqual(response.status_code, 200)
+
+        # Check that initially we don't have any books in list (none on loan)
+        self.assertTrue('bookinstance_list' in response.context)
+        self.assertEqual(len(response.context['bookinstance_list']), 0)
+
+        # Now change all books to be on loan
+        books = BookInstance.objects.all()[:10]
+
+        for book in books:
+            book.status = 'o'
+            book.save()
+
+        # Check that now we have borrowed books in the list
+        response = self.client.get(reverse('my-borrowed'))
+        # Check our user is logged in
+        self.assertEqual(str(response.context['user']), 'testuser1')
+        # Check that we got a response "success"
+        self.assertEqual(response.status_code, 200)
+
+        self.assertTrue('bookinstance_list' in response.context)
+
+        # Confirm all books belong to testuser1 and are on loan
+        for bookitem in response.context['bookinstance_list']:
+            self.assertEqual(response.context['user'], bookitem.borrower)
+            self.assertEqual('o', bookitem.status)
+
+    def test_pages_ordered_by_due_date(self):
+        # Change all books to be on loan
+        for book in BookInstance.objects.all():
+            book.status='o'
+            book.save()
+
+        login = self.client.login(username='testuser1', password='1X&lt;ISRUkw+tuK')
+        response = self.client.get(reverse('my-borrowed'))
+
+        # Check our user is logged in
+        self.assertEqual(str(response.context['user']), 'testuser1')
+        # Check that we got a response "success"
+        self.assertEqual(response.status_code, 200)
+
+        # Confirm that of the items, only 10 are displayed due to pagination.
+        self.assertEqual(len(response.context['bookinstance_list']), 10)
+
+        last_date = 0
+        for book in response.context['bookinstance_list']:
+            if last_date == 0:
+                last_date = book.due_back
+            else:
+ self.assertTrue(last_date &lt;= book.due_back)
+                last_date = book.due_back</pre>
+
+<p>Vous pourriez aussi ajouter les tests de pagination, si vous voulez !</p>
+
+<h4 id="Tester_des_vues_avec_formulaires">Tester des vues avec formulaires</h4>
+
+<p>Tester des vues avec formulaires est un peu plus compliqué que dans les cas précédents, car vous devez tester un code qui parcourt plus de chemin : l'affichage initial, l'affichage après que la validation des données a échoué, et l'affichage après que la validation a réussi. La bonne nouvelle, c'est que nous utilisons le client de test presque de la même manière que nous l'avons fait pour des vues qui ne font qu'afficher des données.</p>
+
+<p>Pour voir cela, écrivons des tests pour la vue utilisée pour renouveler des livres (<code>renew_book_librarian()</code>) :</p>
+
+<pre class="brush: python">from catalog.forms import RenewBookForm
+
+@permission_required('catalog.can_mark_returned')
+def renew_book_librarian(request, pk):
+    """View function for renewing a specific BookInstance by librarian."""
+    book_instance = get_object_or_404(BookInstance, pk=pk)
+
+    # If this is a POST request then process the Form data
+    if request.method == 'POST':
+
+        # Create a form instance and populate it with data from the request (binding):
+        book_renewal_form = RenewBookForm(request.POST)
+
+        # Check if the form is valid:
+        if form.is_valid():
+            # process the data in form.cleaned_data as required (here we just write it to the model due_back field)
+            book_instance.due_back = form.cleaned_data['renewal_date']
+            book_instance.save()
+
+            # redirect to a new URL:
+            return HttpResponseRedirect(reverse('all-borrowed'))
+
+    # If this is a GET (or any other method) create the default form
+    else:
+        proposed_renewal_date = datetime.date.today() + datetime.timedelta(weeks=3)
+        book_renewal_form = RenewBookForm(initial={'renewal_date': proposed_renewal_date})
+
+ context = {
+ 'book_renewal_form': book_renewal_form,
+ 'book_instance': book_instance,
+ }
+
+    return render(request, 'catalog/book_renew_librarian.html', context)</pre>
+
+<p>Nous allons devoir tester que la vue n'est disponible qu'aux utilisateurs ayant la permission <code>can_mark_returned</code>, et que les utilisateurs sont bien redirigés vers une page d'erreur HTTP 404 s'ils essaient de renouveler une <code>BookInstance</code> inexistante. Nous devons vérifier que la valeur initiale du formulaire est remplie avec une date de trois semaines dans le futur, et que si la validation réussit, nous sommes redirigés vers la vue "tous les livres empruntés". Dans le cadre des tests sur l'échec de la validation, nous allons aussi vérifier que notre formulaire envoie les bons messages d'erreur.</p>
+
+<p>Ajoutez la première partie de la classe de test ci-dessous à la fin du fichier <strong>/catalog/tests/test_views.py</strong>. Cela crée deux utilisateurs et deux instances de livres, mais ne donne qu'à un seul utilisateur la permission d'accéder à la vue. Le code pour autoriser les permissions durant les tests est montrée en gras :</p>
+
+<pre class="brush: python">import uuid
+
+from django.contrib.auth.models import Permission # Required to grant the permission needed to set a book as returned.
+
+class RenewBookInstancesViewTest(TestCase):
+ def setUp(self):
+ # Create a user
+ test_user1 = User.objects.create_user(username='testuser1', password='1X&lt;ISRUkw+tuK')
+ test_user2 = User.objects.create_user(username='testuser2', password='2HJ1vRV0Z&amp;3iD')
+
+ test_user1.save()
+ test_user2.save()
+
+<strong> permission = Permission.objects.get(name='Set book as returned')
+ test_user2.user_permissions.add(permission)
+ test_user2.save()</strong>
+
+ # Create a book
+ test_author = Author.objects.create(first_name='John', last_name='Smith')
+ test_genre = Genre.objects.create(name='Fantasy')
+ test_language = Language.objects.create(name='English')
+ test_book = Book.objects.create(
+ title='Book Title',
+ summary='My book summary',
+ isbn='ABCDEFG',
+ author=test_author,
+ language=test_language,
+ )
+
+ # Create genre as a post-step
+ genre_objects_for_book = Genre.objects.all()
+ test_book.genre.set(genre_objects_for_book) # Direct assignment of many-to-many types not allowed.
+ test_book.save()
+
+ # Create a BookInstance object for test_user1
+ return_date = datetime.date.today() + datetime.timedelta(days=5)
+ self.test_bookinstance1 = BookInstance.objects.create(
+ book=test_book,
+ imprint='Unlikely Imprint, 2016',
+ due_back=return_date,
+ borrower=test_user1,
+ status='o',
+ )
+
+ # Create a BookInstance object for test_user2
+ return_date = datetime.date.today() + datetime.timedelta(days=5)
+ self.test_bookinstance2 = BookInstance.objects.create(
+ book=test_book,
+ imprint='Unlikely Imprint, 2016',
+ due_back=return_date,
+ borrower=test_user2,
+ status='o',
+ )</pre>
+
+<p>Ajoutez les tests suivants à la fin de la classe de test. Ils vérifient que seuls les utilisateurs avec les bonnes permissions (<em>testuser2</em>) peuvent accéder à la vue. Nous vérifions tous les cas : quand l'utilisateur n'est pas connecté, quand un utilisateur est connecté mais n'a pas les permissions requises, quand l'utilisateur a les permissions mais n'est pas l'emprunteur (ce test devrait réussir), et ce qui se passe quand ils tentent d'accéder à une <code>BookInstance</code> inexistante. Nous vérifions aussi que le bon template est utilisé.</p>
+
+<pre class="brush: python"> def test_redirect_if_not_logged_in(self):
+        response = self.client.get(reverse('renew-book-librarian', kwargs={'pk': self.test_bookinstance1.pk}))
+        # Manually check redirect (Can't use assertRedirect, because the redirect URL is unpredictable)
+        self.assertEqual(response.status_code, 302)
+        self.assertTrue(response.url.startswith('/accounts/login/'))
+
+    def test_redirect_if_logged_in_but_not_correct_permission(self):
+        login = self.client.login(username='testuser1', password='1X&lt;ISRUkw+tuK')
+        response = self.client.get(reverse('renew-book-librarian', kwargs={'pk': self.test_bookinstance1.pk}))
+        self.assertEqual(response.status_code, 403)
+
+    def test_logged_in_with_permission_borrowed_book(self):
+        login = self.client.login(username='testuser2', password='2HJ1vRV0Z&amp;3iD')
+        response = self.client.get(reverse('renew-book-librarian', kwargs={'pk': self.test_bookinstance2.pk}))
+
+        # Check that it lets us login - this is our book and we have the right permissions.
+        self.assertEqual(response.status_code, 200)
+
+    def test_logged_in_with_permission_another_users_borrowed_book(self):
+        login = self.client.login(username='testuser2', password='2HJ1vRV0Z&amp;3iD')
+        response = self.client.get(reverse('renew-book-librarian', kwargs={'pk': self.test_bookinstance1.pk}))
+
+        # Check that it lets us login. We're a librarian, so we can view any users book
+        self.assertEqual(response.status_code, 200)
+
+    def test_HTTP404_for_invalid_book_if_logged_in(self):
+ # unlikely UID to match our bookinstance!
+        test_uid = uuid.uuid4()
+        login = self.client.login(username='testuser2', password='2HJ1vRV0Z&amp;3iD')
+        response = self.client.get(reverse('renew-book-librarian', kwargs={'pk':test_uid}))
+        self.assertEqual(response.status_code, 404)
+
+    def test_uses_correct_template(self):
+        login = self.client.login(username='testuser2', password='2HJ1vRV0Z&amp;3iD')
+        response = self.client.get(reverse('renew-book-librarian', kwargs={'pk': self.test_bookinstance1.pk}))
+        self.assertEqual(response.status_code, 200)
+
+        # Check we used correct template
+        self.assertTemplateUsed(response, 'catalog/book_renew_librarian.html')
+</pre>
+
+<p>Ajoutez la méthode de test suivante, comme montré ci-dessous. Elle vérifie que la date initiale pour le formulaire est trois semaines dans le futur. Notez comment nous pouvons accéder à la valeur initiale de ce champ de formulaire (en gras).</p>
+
+<pre class="brush: python">    def test_form_renewal_date_initially_has_date_three_weeks_in_future(self):
+        login = self.client.login(username='testuser2', password='2HJ1vRV0Z&amp;3iD')
+        response = self.client.get(reverse('renew-book-librarian', kwargs={'pk': self.test_bookinstance1.pk}))
+        self.assertEqual(response.status_code, 200)
+
+        date_3_weeks_in_future = datetime.date.today() + datetime.timedelta(weeks=3)
+        self.assertEqual(response<strong>.context['form'].initial['renewal_date']</strong>, date_3_weeks_in_future)
+</pre>
+
+<div class="warning">
+<p>Si vous utilisez la class de formulaire <code>RenewBookModelForm(forms.ModelForm)</code> à la place de la classe <code>RenewBookForm(forms.Form)</code>, le nom du champ est <strong>'due_back'</strong> et non <strong>'renewal_date'</strong>.</p>
+</div>
+
+<p>Le test suivant (ajoutez-le à la classe également) vérifie que la vue redirige vers une liste de tous les livres empruntés si le renouvellement réussit. Ce qui diffère ici est que, pour la première fois, nous montrons comment vous pouvez <code>POST</code>er des données en utilisant le client. Les données postées forment le second argument de la fonction post, et elles sont spécifiées comme un dictionnaire de clés/valeurs.</p>
+
+<pre class="brush: python">    def test_redirects_to_all_borrowed_book_list_on_success(self):
+        login = self.client.login(username='testuser2', password='2HJ1vRV0Z&amp;3iD')
+        valid_date_in_future = datetime.date.today() + datetime.timedelta(weeks=2)
+        <strong>response = self.client.post(reverse('renew-book-librarian', kwargs={'pk':self.test_bookinstance1.pk,}), {'renewal_date':valid_date_in_future})</strong>
+        self.assertRedirects(response, reverse('all-borrowed'))
+</pre>
+
+<div class="warning">
+<p>La vue <em>all-borrowed</em> a été ajoutée comme <em>défi</em>, et votre code peut, à la place, rediriger vers la page d'accueil '/'. Si c'est le cas, modifiez les deux dernières lignes du code de test pour qu'elles ressemblent au code ci-dessous. L'expression <code>follow=True</code> dans la requête s'assure que la requête retourne l'URL de la destination finale (donc vérifie <code>/catalog/</code> plutôt que <code>/</code>).</p>
+
+<pre class="brush: python"> response = self.client.post(reverse('renew-book-librarian', kwargs={'pk':self.test_bookinstance1.pk,}), {'renewal_date':valid_date_in_future}, <strong>follow=True</strong> )
+ <strong>self.assertRedirects(</strong><strong>response, '/catalog/')</strong></pre>
+</div>
+
+<p>Copiez les deux dernières fonctions dans la classe, comme indiqué ci-dessous. Elles testent de nouveau des requêtes POST, mais dans ce cas avec des dates de renouvellement invalides. Nous utilisons la méthode assertFormError() pour vérifier que les messages d'erreur sont ceux que nous attendons.</p>
+
+<pre class="brush: python">    def test_form_invalid_renewal_date_past(self):
+        login = self.client.login(username='testuser2', password='2HJ1vRV0Z&amp;3iD')
+        date_in_past = datetime.date.today() - datetime.timedelta(weeks=1)
+        response = self.client.post(reverse('renew-book-librarian', kwargs={'pk': self.test_bookinstance1.pk}), {'renewal_date': date_in_past})
+        self.assertEqual(response.status_code, 200)
+        <strong>self.assertFormError(</strong><strong>response, 'form', 'renewal_date', 'Invalid date - renewal in past')</strong>
+
+    def test_form_invalid_renewal_date_future(self):
+        login = self.client.login(username='testuser2', password='2HJ1vRV0Z&amp;3iD')
+        invalid_date_in_future = datetime.date.today() + datetime.timedelta(weeks=5)
+        response = self.client.post(reverse('renew-book-librarian', kwargs={'pk': self.test_bookinstance1.pk}), {'renewal_date': invalid_date_in_future})
+        self.assertEqual(response.status_code, 200)
+        <strong>self.assertFormError(</strong><strong>response, 'form', 'renewal_date', 'Invalid date - renewal more than 4 weeks ahead')</strong>
+</pre>
+
+<p>Le même genre de technique peut être utilisé pour tester les autres vues.</p>
+
+<h3 id="Templates">Templates</h3>
+
+<p>Django fournit des API de test pour vérifier que le bon template sera appelé par vos vues, et pour vous permettre de vérifier que l'information correcte sera envoyée. Il n'y a cependant pas de support d'API spécifique en Django pour tester que votre sortie HTML a le rendu souhaité.</p>
+
+<h2 id="Autres_outils_de_test_recommandés">Autres outils de test recommandés</h2>
+
+<p>Le framework de test de Django peut vous aider à écrire des tests unitaires et d'intégration efficaces - nous n'avons fait que gratter la surface de ce que peut faire unittest,le framework de test sous-jacent, et plus encore les additions de Django (par exemple, regardez comment vous pouvez utiliser unittest.mock pour patcher les bibliothèques tierces afin de tester plus finement votre propre code).</p>
+
+<p>Comme il y a un grand nombre d'autres outils de test à votre disposition, nous ne mentionnerons que les deux suivants :</p>
+
+<ul>
+ <li><a href="http://coverage.readthedocs.io/en/latest/">Coverage</a>: Cet outil Python fait un rapport sur la proportion de votre code réellement exécutée par vos tests. C'est particulièrement intéressant quand vous commencez, et que vous cherchez à vous représenter exactement ce que vous devez tester.</li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Your_own_automation_environment">Selenium</a> est un framework pour automatiser les tests dans un vrai navigateur. Il vous permet de simuler un utilisateur réel en interaction avec le site, et fournit un excellent framework pour les tests système de votre site (l'étape qui suit les tests d'intégration).</li>
+</ul>
+
+<h2 id="Défi">Défi</h2>
+
+<p>Il y a beaucoup d'autres modèles et vues que nous pouvons tester. Comme exercice simple, essayez de créer un cas de test pour la vue <code>AuthorCreate</code>.</p>
+
+<pre class="brush: python">class AuthorCreate(PermissionRequiredMixin, CreateView):
+ model = Author
+ fields = '__all__'
+ initial = {'date_of_death':'12/10/2016'}
+ permission_required = 'catalog.can_mark_returned'</pre>
+
+<p>Souvenez-vous que vous avez besoin de vérifier tout ce que vous avez spécifié ou ce qui fait partie du design. Cela va inclure qui a accès, la date initiale, le template utilisé, et où la vue redirige en cas de succès.</p>
+
+<h2 id="Résumé">Résumé</h2>
+
+<p>Écrire un code de test n'est ni très excitant ni très fascinant, et par conséquent ce travail est souvent laissé pour la fin (ou complètement délaissé) par les créateurs de sites web. C'est pourtant un élément essentiel pour vous assurer que, malgré les changements apportés, votre code peut passer à une nouvelle version en toute sécurité, et que sa maintenance est rentable.</p>
+
+<p>Dans ce tutoriel, nous vous avons montré comment écrire et lancer des tests pour vos modèles, formulaires et vues. Plus important, nous avons fourni un bref résumé de ce que vous devez tester, ce qui est souvent la chose la plus difficile à comprendre quand on commence. Il y a beaucoup de choses à savoir, mais avec ce que vous avez déjà appris, vous devriez être capable de créer des tests unitaires efficaces pour vos sites web.</p>
+
+<p>Le prochain (et dernier) tutoriel montre comment vous pouvez déployer votre merveilleux (et entièrement testé !) site web Django.</p>
+
+<h2 id="À_voir_également">À voir également</h2>
+
+<ul>
+ <li><a href="https://docs.djangoproject.com/en/2.1/topics/testing/overview/">Writing and running tests</a> (Django docs)</li>
+ <li><a href="https://docs.djangoproject.com/en/2.1/intro/tutorial05/">Writing your first Django app, part 5 &gt; Introducing automated testing</a> (Django docs)</li>
+ <li><a href="https://docs.djangoproject.com/en/2.1/topics/testing/tools/">Testing tools reference</a> (Django docs)</li>
+ <li><a href="https://docs.djangoproject.com/en/2.1/topics/testing/advanced/">Advanced testing topics</a> (Django docs)</li>
+ <li><a href="http://toastdriven.com/blog/2011/apr/10/guide-to-testing-in-django/">A Guide to Testing in Django</a> (Toast Driven Blog, 2011)</li>
+ <li><a href="http://test-driven-django-development.readthedocs.io/en/latest/index.html">Workshop: Test-Driven Web Development with Django</a> (San Diego Python, 2014)</li>
+ <li><a href="https://realpython.com/blog/python/testing-in-django-part-1-best-practices-and-examples/">Testing in Django (Part 1) - Best Practices and Examples</a> (RealPython, 2013)</li>
+</ul>
+
+<p>{{PreviousMenuNext("Learn/Server-side/Django/Forms", "Learn/Server-side/Django/Deployment", "Learn/Server-side/Django")}}</p>
+
+<h2 id="Dans_ce_module">Dans ce module</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Introduction">Django introduction</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/development_environment">Setting up a Django development environment</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">Django Tutorial: The Local Library website</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/skeleton_website">Django Tutorial Part 2: Creating a skeleton website</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Models">Django Tutorial Part 3: Using models</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Admin_site">Django Tutorial Part 4: Django admin site</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Home_page">Django Tutorial Part 5: Creating our home page</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Generic_views">Django Tutorial Part 6: Generic list and detail views</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Sessions">Django Tutorial Part 7: Sessions framework</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Authentication">Django Tutorial Part 8: User authentication and permissions</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Forms">Django Tutorial Part 9: Working with forms</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Testing">Django Tutorial Part 10: Testing a Django web application</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Deployment">Django Tutorial Part 11: Deploying Django to production</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/web_application_security">Django web application security</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/django_assessment_blog">DIY Django mini blog</a></li>
+</ul>
diff --git a/files/fr/learn/server-side/django/tutorial_local_library_website/index.html b/files/fr/learn/server-side/django/tutorial_local_library_website/index.html
new file mode 100644
index 0000000000..e7ff3ca5c6
--- /dev/null
+++ b/files/fr/learn/server-side/django/tutorial_local_library_website/index.html
@@ -0,0 +1,101 @@
+---
+title: 'Django Didactique: Site web "Bibliothèque locale"'
+slug: Learn/Server-side/Django/Tutorial_local_library_website
+tags:
+ - Apprentissage
+ - Article
+ - Didacticiel
+ - Débutant
+ - Guide
+ - django
+translation_of: Learn/Server-side/Django/Tutorial_local_library_website
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/Server-side/Django/development_environment", "Learn/Server-side/Django/skeleton_website", "Learn/Server-side/Django")}}</div>
+
+<p>Le premier article de cette série didactique explique ce que vous apprendrez et donne un aperçu du site Web "Bibliothèque locale", un exemple, qui va être utiliser et évoluer dans les articles suivants.</p>
+
+<div></div>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Prérequis:</th>
+ <td>La lecture de <a href="/fr/docs/Learn/Server-side/Django/Introduction">l'introduction</a>. Pour les articles suivants avoir mis à jour l'environnement comme décrit précédemment. </td>
+ </tr>
+ <tr>
+ <th scope="row">Objectifs:</th>
+ <td>Présenter l'application à venir et les thèmes qui seront abordés dans cette série didactique.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Vue_d'ensemble">Vue d'ensemble</h2>
+
+<p>La série didactique MDN "Bibliothèque locale" va vous permettre de développer un site web destiné à gérer le catalogue d'une bibliothèque.</p>
+
+<p>Dans les articles qui suivent, vous allez apprendre à :</p>
+
+<ul>
+ <li>Utiliser les outils de Django pour créer le squelette d'un site web et d'applications</li>
+ <li>Démarrer et arrêter le serveur de développement.</li>
+ <li>Créer les modèles de données utilisés par les applications.</li>
+ <li>Utiliser les outils d'administration Django du site web pour y enregsitrer et y peupler les données.</li>
+ <li>Créer des vues pour exploiter en fonction de demandes particulières et restituer à l'aide de modèles les informations dans des documents HTML affichés par votre navigateur.</li>
+ <li>Créer les chemins pour associer des URL avec des vues particulières.</li>
+ <li>Ajouter et gérer les autorisations et le contrôle d'accès au site des utilisateurs.</li>
+ <li>Manipuler les formulaires.</li>
+ <li>Ecrire des jeux de test pour votre application.</li>
+ <li>Utiliser les moyens de sécurité de Django.</li>
+ <li>Déployer en production vote application.</li>
+</ul>
+
+<p>Que vous ayez déjà des connaissance sur le sujet ou que vous ayez aborder succinctement ce quadriciel, à la fin de cette série didactique, vous serez suffisamment autonome pour développer vos propres applications avec Django.</p>
+
+<h2 id="Le_site_web_de_la_Bibliothèque_locale">Le site web de la "Bibliothèque locale"</h2>
+
+<p>La <em>LocalLibrary</em> (Bibliothèque locale) est le nom du site web qui va être créer et qui évoluera tout au long de cette série didatcique. La finalité de ce site web est de diffuser un catalogue des livres en ligne et de permettre aux utilisateurs de le parcourir et de gérer leur propre compte.</p>
+
+<p>Cet exemple a été soigneusement choisi car il permet de progresser en montrant nombre de détails et abordre presque toutes les fonctionnalités de Django. De plus, cet exemple permet d'appréhender progressivement les fonctionnalités les plus importantes du quadriciel :</p>
+
+<ul>
+ <li>Une première étape consistera à définir un catalogue simple qui permet aux utilisateurs de consulter les ouvrages disponibles. Cela combine les schémas classiques et les opérations communes à la plupart de ce type de sites : lire et afficher le contenu d'une base de données...</li>
+ <li>La progression des différents articles permettra d'étudier des fonctions plus avancées du quadriciel. Par exemple, utiliser des formulaires et permettre aux utilisateurs de réserver leurs ouvrages, ceci conduit à mettre en place et utiliser la gestion des utilisateurs et de l'authentification.</li>
+</ul>
+
+<p>Même s'il s'agit d'un sujet extensible, son sujet de <em>Bibliothèque <strong>locale</strong></em> est volontaire. Il s'agit d'aborder rapidement de nombreux sujets de Django en manipulant un minimum d'information. Il s'agit d'enregistrer localement les informations fictives sur les livres, copies, auteurs, etc. Il ne s'agit en aucun cas d'élaborer un produit qui gère, comme pourrait le faire une bibliothèque classique d'autres informations, ni gérer un réseau de bibliothèques comme cela pourrait être le cas avec une <em><strong>grande</strong> biblothèque</em>. </p>
+
+<h2 id="Je_suis_coincé_où_puis-je_trouver_les_sources">Je suis coincé, où puis-je trouver les sources ?</h2>
+
+<p>Au fur et à mesure, les codes et commandes à écrire seront fournis. Ils peuvent être copiés et collés à chaque étapes. Il y aura aussi des codes que vous pourrez compléter avec quelques conseils.</p>
+
+<p>Si vous êtes coincé, vous pourrez trouver une version totalement développée du site sur<a href="https://github.com/mdn/django-locallibrary-tutorial"> Github</a> (<strong>Anglais</strong>).</p>
+
+<h2 id="Résumé">Résumé</h2>
+
+<p>Vous en savez plus sur le projet <em>LocalLibrary</em> et ce que vous allez progressivement apprendre, il est désormais temps de créer le <a href="/en-US/docs/Learn/Server-side/Django/skeleton_website">squellette du projet</a> qui hébergera la bibliothèque.</p>
+
+<p>{{PreviousMenuNext("Learn/Server-side/Django/development_environment", "Learn/Server-side/Django/skeleton_website", "Learn/Server-side/Django")}}</p>
+
+
+
+<h2 id="Dans_ce_module">Dans ce module</h2>
+
+<ul>
+ <li><a href="/fr/docs/Learn/Server-side/Django/Introduction">Django introduction</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/development_environment">Setting up a Django development environment</a></li>
+ <li><a href="/fr/docs/Learn/Server-side/Django/Tutorial_local_library_website">Django Didactique: Site web "Bibliothèque locale"</a></li>
+ <li><a href="/fr/docs/Learn/Server-side/Django/skeleton_website">Django didactique Section 2: Créer le squelette du site web</a></li>
+ <li><a href="/fr/docs/Learn/Server-side/Django/Models">Django didactique Section 3: Utilisation des modèles de données</a></li>
+ <li><a href="/fr/docs/Learn/Server-side/Django/Admin_site">Django didactique Section 4 : Site d'administration de Django</a></li>
+ <li><a href="/fr/docs/Learn/Server-side/Django/Home_page">Django didactique Section 5: Créer la page d'accueil</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Generic_views">Django Tutorial Part 6: Generic list and detail views</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Sessions">Django Tutorial Part 7: Sessions framework</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Authentication">Django Tutorial Part 8: User authentication and permissions</a></li>
+ <li><a href="/fr/docs/Learn/Server-side/Django/Forms">Django Tutorial Part 9: Working with forms</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Testing">Django Tutorial Part 10: Testing a Django web application</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Deployment">Django Tutorial Part 11: Deploying Django to production</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/web_application_security">Django web application security</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/django_assessment_blog">DIY Django mini blog</a></li>
+</ul>
diff --git a/files/fr/learn/server-side/django/vues_generiques/index.html b/files/fr/learn/server-side/django/vues_generiques/index.html
new file mode 100644
index 0000000000..f2d48431fc
--- /dev/null
+++ b/files/fr/learn/server-side/django/vues_generiques/index.html
@@ -0,0 +1,634 @@
+---
+title: 'Tutoriel Django - 6e partie : Vues génériques pour les listes et les détails'
+slug: Learn/Server-side/Django/Vues_generiques
+tags:
+ - Beginner
+ - Learn
+ - Tutorial
+ - django
+ - django templates
+ - django views
+translation_of: Learn/Server-side/Django/Generic_views
+---
+<div></div>
+
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/Server-side/Django/Home_page", "Learn/Server-side/Django/Sessions", "Learn/Server-side/Django")}}</div>
+
+<div>Ce tutoriel améliore notre site web <a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">LocalLibrary</a>, en ajoutant des pages de listes et de détails pour les livres et les auteurs. Ici nous allons apprendre les vues génériques basées sur des classes, et montrer comment elles peuvent réduire le volume de code à écrire pour les cas ordinaires. Nous allons aussi entrer plus en détail dans la gestion des URLs, en montrant comment réaliser des recherches de patterns simples.</div>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Prérequis:</th>
+ <td>
+ <p>Avoir terminé tous les tutoriels précédents, y compris <a href="/en-US/docs/Learn/Server-side/Django/Home_page">Django Tutorial Part 5: Creating our home page</a>.</p>
+ </td>
+ </tr>
+ <tr>
+ <th scope="row">Objectif:</th>
+ <td>
+ <p>Comprendre où et comment utiliser des vues génériques basées sur classes, et comment extraire des patterns dans des URLs pour transmettre les informations aux vues.</p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Aperçu">Aperçu</h2>
+
+<p>Dans ce tutoriel, nous allons terminer la première version du site web <a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">LocalLibrary</a>, en ajoutant des pages de listes et de détails pour les livres et les auteurs (ou pour être plus précis, nous allons vous montrer comment implémenter les pages concernant les livres, et vous faire créer vous-mêmes les pages concernant les auteurs !).</p>
+
+<p>Le processus est semblable à celui utilisé pour créer la page d'index, processus que nous avons montré dans le tutoriel précédent. Nous allons avoir de nouveau besoin de créer des mappages d'URLs, des vues et des templates. La principale différence est que, pour la page des détails, nous allons avoir le défi supplémentaire d'extraire de l'URL des informations que nous transmettrons à la vue. Pour ces pages, nous allons montrer comment utiliser un type de vue complètement différent : des vues "listes" et "détails" génériques et basées sur des classes. Cela peut réduire significativement la somme de code nécessaire, les rendant ainsi faciles à écrire et à maintenir.</p>
+
+<p>La partie finale de ce tutoriel montrera comment paginer vos données quand vous utilisez des vues "listes" génériques basées sur des classes.</p>
+
+<h2 id="Page_de_liste_de_livres">Page de liste de livres</h2>
+
+<p>La page de liste des livres va afficher une liste de tous les enregistrements de livres disponibles, en utilisant l'URL: <code>catalog/books/</code>. La page va afficher le titre et l'auteur pour chaque enregistrement, et le titre sera un hyperlien vers la page de détails associée. La page aura la même structure et la même zone de navigation que les autres pages du site, et nous pouvons dès lors étendre le template de base (<strong>base_generic.html</strong>) que nous avons créé dans le tutoriel précédent.</p>
+
+<h3 id="Mappage_dURL">Mappage d'URL</h3>
+
+<p>Ouvrez le fichier <strong>/catalog/urls.py</strong>, et copiez-y la ligne en gras ci-dessous. Comme pour la page d'index, cette fonction <code>path()</code> définit un pattern destiné à identifier l'URL (<strong>'books/'</strong>), une fonction vue qui sera appelée si l'URL correspond (<code>views.BookListView.as_view()</code>), et un nom pour ce mappage particulier.</p>
+
+<pre class="brush: python notranslate">urlpatterns = [
+ path('', views.index, name='index'),
+<strong>  </strong>path<strong>('books/', views.BookListView.as_view(), name='books'),</strong>
+]</pre>
+
+<p>Comme discuté dans le tutoriel précédent, l'URL doit auparavant avoir identifié la chaîne <code>/catalog</code>, aussi la vue ne sera réellement appelée que pour l'URL complète: <code>/catalog/books/</code>.</p>
+
+<p>La fonction vue a un format différent de celui que nous avions jusqu'ici : c'est parce que cette vue sera en réalité implémentée sous forme de classe. Nous allons la faire hériter d'une fonction vue générique existante, qui fait la plus grande partie de ce que nous souhaitons réaliser avec cette vue, plutôt que d'écrire notre propre fonction à partir de zéro.</p>
+
+<p>En Django, on accède à la fonction appropriée d'une vue basée sur classe en appelant sa méthode de classe <code>as_view()</code>. Cela a pour effet de créer une instance de la classe, et de s'assurer que les bonnes méthodes seront appelées lors de requêtes HTTP.</p>
+
+<h3 id="Vue_basée_sur_classe">Vue (basée sur classe)</h3>
+
+<p>Nous pourrions assez aisément écrire la vue "liste de livres" comme une fonction ordinaire (comme notre précédente vue "index"), qui interrogerait la base de données pour tous les livres, et qui ensuite appellerait <code>render()</code> pour passer la liste à un template spécifique. À la place, cependant, nous allons utiliser une vue "liste" générique, basée sur une classe (<code>ListView</code>), une classe qui hérite d'une vue existante. Parce que la vue générique implémente déjà la plupart des fonctionnalités dont nous avons besoin et suit les meilleures pratiques Django, nous pourrons créer une vue "liste" plus robuste avec moins de code, moins de répétition, et au final moins de maintenance.</p>
+
+<p>Ouvrez le fichier <strong>catalog/views.py</strong>, et copiez-y le code suivant à la fin :</p>
+
+<pre class="brush: python notranslate">from django.views import generic
+
+class BookListView(generic.ListView):
+ model = Book</pre>
+
+<p>C'est tout ! La vue générique va adresser une requête à la base de données pour obtenir tous les enregistrements du modèle spécifié (<code>Book</code>), et ensuite rendre un template situé à l'adresse <strong>/locallibrary/catalog/templates/catalog/book_list.html</strong> (que nous allons créer ci-dessous). À l'intérieur du template vous pouvez accéder à la liste de livres grâce à la variable de template appelée <code>object_list</code> OU <code>book_list</code> (c'est-à-dire l'appellation générique "<code><em>the_model_name</em>_list</code>").</p>
+
+<div class="note">
+<p><strong>Note </strong>: Ce chemin étrange vers le lieu du template n'est pas une faute de frappe : les vues génériques cherchent les templates dans <code>/<em>application_name</em>/<em>the_model_name</em>_list.html</code> (<code>catalog/book_list.html</code> dans ce cas) à l'intérieur du répertoire <code>/<em>application_name</em>/templates/</code> (<code>/catalog/templates/</code>).</p>
+</div>
+
+<p>Vous pouvez ajouter des attributs pour changer le comportement par défaut utilisé ci-dessus. Par exemple, vous pouvez spécifier un autre fichier de template si vous souhaitez avoir plusieurs vues qui utilisent ce même modèle, ou bien vous pourriez vouloir utiliser un autre nom de variable de template, si book_list n'est pas intuitif par rapport à l'usage que vous faites de vos templates. Probablement, le changement le plus utile est de changer/filtrer le sous-ensemble des résultats retournés : au lieu de lister tous les livres, vous pourriez lister les 5 premiers livres lus par d'autres utilisateurs.</p>
+
+<pre class="brush: python notranslate">class BookListView(generic.ListView):
+ model = Book
+ context_object_name = 'my_book_list' # your own name for the list as a template variable
+ queryset = Book.objects.filter(title__icontains='war')[:5] # Get 5 books containing the title war
+ template_name = 'books/my_arbitrary_template_name_list.html' # Specify your own template name/location</pre>
+
+<h4 id="Ré-écrire_des_méthodes_dans_des_vues_basées_sur_classes">Ré-écrire des méthodes dans des vues basées sur classes</h4>
+
+<p>Bien que nous n'ayons pas besoin de le faire ici, sachez qu'il vous est possible de ré-écrire des méthodes de classe.</p>
+
+<p>Par exemple, nous pouvons ré-écrire la méthode <code>get_queryset()</code> pour changer la liste des enregistrements retournés. Cette façon de faire est plus flexible que simplement définir l'attribut <code>queryset</code>, comme nous l'avons fait dans le précédent fragment de code (bien qu'il n'y ait pas vraiment d'intérêt dans ce cas) :</p>
+
+<pre class="brush: python notranslate">class BookListView(generic.ListView):
+ model = Book
+
+    def get_queryset(self):
+        return Book.objects.filter(title__icontains='war')[:5] # Get 5 books containing the title war
+</pre>
+
+<p>Nous pourrions aussi réécrire <code>get_context_data()</code>, afin d'envoyer au template des variables de contexte supplémentaires (par défaut c'est la liste de livres qui est envoyée). Le bout de code ci-dessous montre comment ajouter une variable appelée "<code>some_data</code>" au contexte (elle sera alors accessible comme variable de template).</p>
+
+<pre class="brush: python notranslate">class BookListView(generic.ListView):
+ model = Book
+
+    def get_context_data(self, **kwargs):
+        # Call the base implementation first to get the context
+        context = super(BookListView, self).get_context_data(**kwargs)
+        # Create any data and add it to the context
+        context['some_data'] = 'This is just some data'
+        return context</pre>
+
+<p>Quand vous faites cela, il est important de suivre la procédure indiquée ci-dessus :</p>
+
+<ul>
+ <li>D'abord récupérer auprès de la superclasse le contexte existant.</li>
+ <li>Ensuite ajouter la nouvelle information de contexte.</li>
+ <li>Enfin retourner le nouveau contexte (mis à jour).</li>
+</ul>
+
+<div class="note">
+<p><strong>Note </strong>: Voyez dans <a href="https://docs.djangoproject.com/en/2.1/topics/class-based-views/generic-display/">Built-in class-based generic views</a> (doc de Django) pour avoir beaucoup plus d'exemples de ce que vous pouvez faire.</p>
+</div>
+
+<h3 id="Créer_le_template_pour_la_Vue_Liste">Créer le template pour la Vue Liste</h3>
+
+<p>Créez le fichier HTML <strong>/locallibrary/catalog/templates/catalog/book_list.html</strong>, et copiez-y le texte ci-dessous. Comme nous l'avons dit ci-dessus, c'est ce fichier que va chercher par défaut la classe générique "liste" basée sur une vue (dans le cas d'un modèle appelé <code>Book</code>, dans une application appelée <code>catalog</code>).</p>
+
+<p>Les templates pour vues génériques sont exactement comme les autres templates (cependant, bien sûr, le contexte et les informations envoyées au templates peuvent être différents). Comme pour notre template <em>index</em>, nous étendons notre template de base à la première ligne, et remplaçons ensuite le bloc appelé <code>content</code>.</p>
+
+<pre class="brush: html notranslate">{% extends "base_generic.html" %}
+
+{% block content %}
+ &lt;h1&gt;Book List&lt;/h1&gt;
+  <strong>{% if book_list %}</strong>
+  &lt;ul&gt;
+  {% for book in book_list %}
+      &lt;li&gt;
+        &lt;a href="\{{ book.get_absolute_url }}"&gt;\{{ book.title }}&lt;/a&gt; (\{{book.author}})
+      &lt;/li&gt;
+  {% endfor %}
+  &lt;/ul&gt;
+  <strong>{% else %}</strong>
+  &lt;p&gt;There are no books in the library.&lt;/p&gt;
+  <strong>{% endif %} </strong>
+{% endblock %}</pre>
+
+<p>La vue envoie le contexte (liste de livres), en utilisant par défaut les alias <code>object_list</code> et <code>book_list</code> ; l'un et l'autre fonctionnent.</p>
+
+<h4 id="Exécution_conditionnelle">Exécution conditionnelle</h4>
+
+<p>Nous utilisons les balises de templates <code><a href="https://docs.djangoproject.com/en/2.1/ref/templates/builtins/#if">if</a></code>, <code>else</code>, et <code>endif</code> pour vérifier que la <code>book_list</code> a été définie et n'est pas vide. Si <code>book_list</code> est vide, alors la condition <code>else</code> affiche un texte expliquant qu'il n'y a pas de livres à lister. Si <code>book_list</code> n'est pas vide, nous parcourons la liste de livres.</p>
+
+<pre class="brush: html notranslate"><strong>{% if book_list %}</strong>
+ &lt;!-- code here to list the books --&gt;
+<strong>{% else %}</strong>
+ &lt;p&gt;There are no books in the library.&lt;/p&gt;
+<strong>{% endif %}</strong>
+</pre>
+
+<p>La condition ci-dessus ne vérifie qu'un seul cas, mais vous pouvez ajouter d'autres tests grâce à la balise de template <code>elif</code> (par exemple <code>{% elif var2 %}</code>). Pour plus d'information sur les opérateurs conditionnels, voyez ici :  <a href="https://docs.djangoproject.com/en/2.1/ref/templates/builtins/#if">if</a>, <a href="https://docs.djangoproject.com/en/2.1/ref/templates/builtins/#ifequal-and-ifnotequal">ifequal/ifnotequal</a>, et <a href="https://docs.djangoproject.com/en/2.1/ref/templates/builtins/#ifchanged">ifchanged</a> dans <a href="https://docs.djangoproject.com/en/2.1/ref/templates/builtins">Built-in template tags and filters</a> (Django Docs).</p>
+
+<h4 id="Boucles_for">Boucles for</h4>
+
+<p>Le template utilise les balises de template <a href="https://docs.djangoproject.com/en/2.1/ref/templates/builtins/#for">for</a> et <code>endfor</code> pour boucler à travers la liste de livres, comme montré ci-dessous. Chaque itération peuple la variable de template <code>book</code> avec l'information concernant l'élément courant de la liste.</p>
+
+<pre class="brush: html notranslate">{% for <strong>book</strong> in book_list %}
+ &lt;li&gt; &lt;!-- code here get information from each <strong>book</strong> item --&gt; &lt;/li&gt;
+{% endfor %}
+</pre>
+
+<p>Bien que nous ne l'utilisions pas ici, Django, à l'intérieur de la boucle, va aussi créer d'autres variables que vous pouvez utiliser pour suivre l'itération. Par exemple, vous pouvez tester la variable <code>forloop.last</code> pour réaliser une action conditionnelle au dernier passage de la boucle.</p>
+
+<h4 id="Accéder_aux_variables">Accéder aux variables</h4>
+
+<p>Le code à l'intérieur de la boucle crée un élément de liste pour chaque livre, élément qui montre à la fois le titre (comme lien vers la vue détail, encore à créer), et l'auteur.</p>
+
+<pre class="brush: html notranslate">&lt;a href="\{{ book.get_absolute_url }}"&gt;\{{ book.title }}&lt;/a&gt; (\{{book.author}})
+</pre>
+
+<p>Nous accédont aux <em>champs</em> de l'enregistrement "livre" associé, en utilisant la notation "à points" (par exemple <code>book.title</code> et <code>book.author</code>), où le texte suivant l'item <code>book</code> est le nom du champ (comme défini dans le modèle).</p>
+
+<p>Nous pouvons aussi appeler des <em>fonctions</em> contenues dans le modèle depuis l'intérieur de notre template — dans ce cas nous appelons <code>Book.get_absolute_url()</code> pour obtenir une URL que vous pouvez utiliser pour afficher dans la vue détail l'enregistrement associé. Cela fonctionne, pourvu que la fonction ne comporte pas d'arguments (il n'y a aucun moyen de passer des arguments !).</p>
+
+<div class="note">
+<p><strong>Note</strong> : Il nous faut être quelque peu attentif aux "effets de bord" quand nous appelons des fonctions dans nos templates. Ici nous récupérons simplement une URL à afficher, mais une fonction peut faire à peu près n'importe quoi — nous ne voudrions pas effacer notre base de données (par exemple) juste parce que nous avons affiché notre template !</p>
+</div>
+
+<h4 id="Mettre_à_jour_le_template_de_base">Mettre à jour le template de base</h4>
+
+<p>Ouvrez le template de base (<strong>/locallibrary/catalog/templates/<em>base_generic.html</em></strong>) et insérez <strong>{% url 'books' %}</strong> dans le lien URL pour <strong>All books</strong>, comme indiqué ci-dessous. Cela va afficher le lien dans toutes les pages (nous pouvons mettre en place ce lien avec succès, maintenant que nous avons créé le mappage d'URL "books").</p>
+
+<pre class="brush: python notranslate">&lt;li&gt;&lt;a href="{% url 'index' %}"&gt;Home&lt;/a&gt;&lt;/li&gt;
+<strong>&lt;li&gt;&lt;a href="{% url 'books' %}"&gt;All books&lt;/a&gt;&lt;/li&gt;</strong>
+&lt;li&gt;&lt;a href=""&gt;All authors&lt;/a&gt;&lt;/li&gt;</pre>
+
+<h3 id="À_quoi_cela_ressemble-t-il">À quoi cela ressemble-t-il ?</h3>
+
+<p>Vous ne pouvez pas encore construire la liste des livres, car il nous manque toujours une dépendance, à savoir le mappage d'URL pour la page de détail de chaque livre, qui est requise pour créer des hyperliens vers chaque livre. Nous allons montrer les vues liste et détail après la prochaine section.</p>
+
+<h2 id="Page_de_détail_dun_livre">Page de détail d'un livre</h2>
+
+<p>La page de détail d'un livre va afficher les informations sur un livre précis, auquel on accède en utilisant l'URL <code>catalog/book/<em>&lt;id&gt;</em></code> (où <code><em>&lt;id&gt;</em></code> est la clé primaire pour le livre). En plus des champs définis dans le modèle <code>Book</code> (auteur, résumé, ISBN, langue et genre), nous allons aussi lister les détails des copies disponibles (<code>BookInstances</code>), incluant le statut, la date de retour prévue, la marque d'éditeur et l'id. Cela permettra à nos lecteurs, non seulement de s'informer sur le livre, mais aussi de confirmer si et quand il sera disponible.</p>
+
+<h3 id="Mappage_dURL_2">Mappage d'URL</h3>
+
+<p>Ouvrez <strong>/catalog/urls.py</strong> et ajoutez-y le mappeur d'URL '<strong>book-detail</strong>' indiqué en gras ci-dessous. Cette fonction <code>path()</code> définit un pattern, la vue générique basée sur classe qui lui est associée, ainsi qu'un nom.</p>
+
+<pre class="brush: python notranslate">urlpatterns = [
+ path('', views.index, name='index'),
+    path('books/', views.BookListView.as_view(), name='books'),
+<strong>  path('book/&lt;int:pk&gt;', views.BookDetailView.as_view(), name='book-detail'),</strong>
+]</pre>
+
+<p>Pour le chemin <em>book-detail</em>, le pattern d'URL utilise une syntaxe spéciale pour capturer l'id exact du livre que nous voulons voir. La syntaxe est très simple : les chevrons ('&lt;' et '&gt;') définissent la partie de l'URL qui doit être capturée et encadrent le nom de la variable que la vue pourra utiliser pour accéder aux données capturées. Par exemple, <strong>&lt;something&gt;</strong>  va capturer le pattern marqué et passer la valeur à la vue en tant que variable "something". De manière optionnelle, vous pouvez faire précéder le nom de variable d'une <a href="https://docs.djangoproject.com/en/2.1/topics/http/urls/#path-converters">spécification de convertisseur</a>, qui définit le type de la donnée (int, str, slug, uuid, path).</p>
+
+<p>Dans ce cas, nous utilisons <code>'&lt;int:pk&gt;'</code> pour capturer l'id du livre, qui doit être une chaîne formatée d'une certaine manière, et passer cet id à la vue en tant que paramètre nommé <code>pk</code> (abbréviation pour primary key - clé primaire). C'est l'id qui doit être utilisé pour stocker le livre de manière unique dans la base de données, comme défini dans le modèle Book.</p>
+
+<div class="note">
+<p><strong>Note </strong>: Comme nous l'avons dit précédemment, notre URL correcte est en réalité <code>catalog/book/&lt;digits&gt;</code> (comme nous sommes dans l'application <strong>catalog</strong>, <code>/catalog/</code> est supposé).</p>
+</div>
+
+<div class="warning">
+<p><strong>Important</strong> : La vue générique basée sur classe "détail" <em>s'attend</em> à recevoir un paramètre appelé <strong>pk</strong>. Si vous écrivez votre propre fonction, vous pouvez utiliser le nom que vous voulez pour votre paramètre, ou même passer l'information avec un argument non nommé.</p>
+</div>
+
+<h4 id="Introduction_aux_chemins_et_expressions_régulières_avancés">Introduction aux chemins et expressions régulières avancés</h4>
+
+<div class="note">
+<p><strong>Note </strong>: Vous n'aurez pas besoin de cette section pour achever le tutoriel ! Nous en parlons parce que nous savons que cette option vous sera probablement utile dans votre avenir centré sur Django.</p>
+</div>
+
+<p>La recherche de pattern fournie par <code>path()</code> est simple et utile pour les cas (très communs) où vous voulez seulement capturer <em>n'importe quelle</em> chaîne ou entier. Si vous avez besoin d'un filtre plus affiné (par exemple pour filtrer seulement les chaînes qui ont un certain nombre de caractères), alors vous pouvez utiliser la méthode <a href="https://docs.djangoproject.com/en/2.1/ref/urls/#django.urls.re_path">re_path()</a>.</p>
+
+<p>Cette méthode est utilisée exactement comme <code>path()</code>, sauf qu'elle vous permet de spécifier un pattern utilisant une <a href="https://docs.python.org/3/library/re.html">Expression régulière</a>. Par exemple, le chemin précédent pourrait avoir été écrit ainsi :</p>
+
+<pre class="brush: python notranslate"><strong>re_path(r'^book/(?P&lt;pk&gt;\d+)$', views.BookDetailView.as_view(), name='book-detail'),</strong>
+</pre>
+
+<p>Les <em>expressions régulières</em> sont un outil de recherche de pattern extrêmement puissant. Ils sont, il est vrai, assez peu intuitifs et peuvent se révéler intimidants pour les débutants. Ci-dessous vous trouverez une introduction très courte !</p>
+
+<p>La première chose à savoir est que les expressions régulières devraient ordinairement être déclarées en utilisant la syntaxe "chaîne littérale brute" (c'est-à-dire encadrées ainsi : <strong>r'&lt;votre texte d'expression régulière va ici&gt;'</strong>).</p>
+
+<p>L'essentiel de ce que vous aurez besoin de savoir pour déclarer une recherche de pattern est contenu dans le tableau qui suit :</p>
+
+<table class="standard-table">
+ <thead>
+ <tr>
+ <th scope="col">Symbol</th>
+ <th scope="col">Meaning</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>^</td>
+ <td>Recherche le début du texte.</td>
+ </tr>
+ <tr>
+ <td>$</td>
+ <td>Recherche la fin du texte.</td>
+ </tr>
+ <tr>
+ <td>\d</td>
+ <td>Recherche un digit (0, 1, 2, ... 9).</td>
+ </tr>
+ <tr>
+ <td>\w</td>
+ <td>Recherche un caractère de mot, c'est-à-dire tout caractère dans l'alphabet (majuscule ou minuscule), un digit ou un underscore (_).</td>
+ </tr>
+ <tr>
+ <td>+</td>
+ <td>Recherche au moins une occurence du caractère précédent. Par exemple, pour rechercher au moins 1 digit, vous utiliseriez <code>\d+</code>. Pour rechercher au moins 1 caractère "a", vous utiliseriez <code>a+</code>.</td>
+ </tr>
+ <tr>
+ <td>*</td>
+ <td>Recherche zéro ou plus occurrence(s) du caractère précédent. Par exemple, pour rechercher "rien ou un mot", vous pourriez utiliser <code>\w*</code>.</td>
+ </tr>
+ <tr>
+ <td>( )</td>
+ <td>Capture la partie du pattern contenue dans les parenthèses. Toutes les valeurs capturées seront passées à la vue en tant que paramètres non nommés (si plusieurs patterns sont capturés, les paramètres associés seront fournis dans l'ordre de déclaration des captures).</td>
+ </tr>
+ <tr>
+ <td>(?P&lt;<em>name</em>&gt;...)</td>
+ <td>Capture le pattern (indiqué par …) en tant que variable nommée (dans ce cas "name"). Les valeurs capturées sont passées à la vue avec le nom spécifié. Votre vue doit par conséquent déclarer un argument avec le même nom !</td>
+ </tr>
+ <tr>
+ <td>[  ]</td>
+ <td>Recherche l'un des caractères contenus dans cet ensemble. Par exemple, [abc] va rechercher "a" ou "b" ou "c". [-\w] va rechercher le caractère "-" ou tout caractère de mot.</td>
+ </tr>
+ </tbody>
+</table>
+
+<p>La plupart des autres caractères peuvent être pris littéralement.</p>
+
+<p>Considérons quelques exemples réels de patterns :</p>
+
+<table class="standard-table">
+ <thead>
+ <tr>
+ <th scope="col">Pattern</th>
+ <th scope="col">Description</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td><strong>r'^book/(?P&lt;pk&gt;\d+)$'</strong></td>
+ <td>
+ <p>C'est là l'expression régulière utilisée dans notre mappeur d'URL. Elle recherche une chaîne qui a <code>book/</code> au commencement de la ligne (<strong>^book/</strong>), ensuite a au moins 1 digit (<code>\d+</code>), et enfin se termine (avec aucun caractère non-digit avant la fin du marqueur de ligne).</p>
+
+ <p>Elle capture aussi tous les digits <strong>(?P&lt;pk&gt;\d+)</strong> et les passe à la vue dans un paramètre appelé 'pk'. <strong>Les valeurs capturées sont toujours passées comme des chaînes !</strong></p>
+
+ <p>Par exemple, cette expression régulière trouverait une correspondance dans l'URL <code>book/1234</code>, et enverrait alors une variable <code>pk='1234'</code> à la vue.</p>
+ </td>
+ </tr>
+ <tr>
+ <td><strong>r'^book/(\d+)$'</strong></td>
+ <td>
+ <p>Ceci rechercher la même URL que dans le cas précédent. L'information capturée serait envoyée à la vue en tant qu'argument non nommé.</p>
+ </td>
+ </tr>
+ <tr>
+ <td><strong>r'^book/(?P&lt;stub&gt;[-\w]+)$'</strong></td>
+ <td>
+ <p>Ceci recherche une chaîne qui a <code>book/</code> au commencement de la ligne (<strong>^book/</strong>), ensuite a au moins 1 caractère étant <em>soit</em> un '-', <em>soit</em> un caractère de mot (<strong>[-\w]+</strong>), puis la fin. Ce pattern capture aussi cet ensemble de caractères et le passe à la vue en tant que paramètre nommé 'stub'.</p>
+
+ <p>Ceci est un pattern relativement typique pour un "stub". Les stubs sont des clés primaires basées sur des mots (plus agréables que des IDs) pour retrouver des données. Vous pouvez utiliser un stub si vous voulez que votre URL de livre contienne plus d'informations. Par exemple <code>/catalog/book/the-secret-garden</code>, plutôt que <code>/catalog/book/33</code>.</p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+<p>Vous pouvez capturer plusieurs patterns en une seule fois, et donc encoder beaucoup d'informations différentes dans l'URL.</p>
+
+<div class="note">
+<p><strong>Note </strong>: Comme défi, essayez d'envisager comment vous devriez encoder une URL pour lister tous les livres sortis en telle année, à tel mois et à tel jour, et l'expression régulière qu'il faudrait utiliser pour la rechercher.</p>
+</div>
+
+<h4 id="Passer_des_options_supplémentaires_dans_vos_mappages_dURL">Passer des options supplémentaires dans vos mappages d'URL</h4>
+
+<p>Une fonctionnalité que nous n'avons pas utilisée ici, mais que vous pourriez trouver valable, c'est que vous pouvez passer à la vue des <a href="https://docs.djangoproject.com/en/2.1/topics/http/urls/#views-extra-options">options supplémentaires</a>. Les options sont déclarées comme un dictionnaire que vous passez comme troisième argument (non nommé) à la fonction <code>path()</code>. Cette approche peut être utile si vous voulez utiliser la même vue pour des ressources multiples, et passer des données pour configurer son comportement dans chaque cas (ci-dessous nous fournissons un template différent dans chaque cas).</p>
+
+<pre class="brush: python notranslate">path('url/', views.my_reused_view, <strong>{'my_template_name': 'some_path'}</strong>, name='aurl'),
+path('anotherurl/', views.my_reused_view, <strong>{'my_template_name': 'another_path'}</strong>, name='anotherurl'),
+</pre>
+
+<div class="note">
+<p><strong>Note :</strong> Les options supplémentaires aussi bien que les patterns capturés sont passés à la vue comme arguments <em>nommés</em>. Si vous utilisez le<strong> </strong><strong>même nom</strong> pour un pattern capturé et une option supplémentaire, alors seul la value du pattern capturé sera envoyé à la vue (la valeur spécifiée dans l'option supplémentaire sera abandonnée).</p>
+</div>
+
+<h3 id="Vue_basée_sur_classe_2">Vue (basée sur classe)</h3>
+
+<p>Ouvrez <strong>catalog/views.py</strong>, et copiez-y le code suivant à la fin du fichier :</p>
+
+<pre class="brush: python notranslate">class BookDetailView(generic.DetailView):
+    model = Book</pre>
+
+<p>C'est tout ! La seule chose que vous avez à faire maintenant, c'est créer un template appelé <strong>/locallibrary/catalog/templates/catalog/book_detail.html</strong>, et la vue va lui passer les informations de la base de donnée concernant l'enregistrement <code>Book</code> spécifique, extrait par le mapper d'URL. À l'intérieur du template, vous pouvez accéder à la liste de livres via la variable de template appelée <code>object</code> OU <code>book</code> (c'est-à-dire, de manière générique, "le_nom_du_modèle").</p>
+
+<p>Si vous en avez besoin, vous pouvez changer le template utilisé et le nom de l'objet-contexte utilisé pour désigner le livre dans le template. Vous pouvez aussi renommer les méthodes pour, par exemple, ajouter des informations supplémentaires au contexte.</p>
+
+<h4 id="Que_se_passe-t-il_si_lenregistrement_nexiste_pas">Que se passe-t-il si l'enregistrement n'existe pas ?</h4>
+
+<p>Si l'enregistrement demandé n'existe pas, alors la vue générique basée sur classe "détail" va lever automatiquement pour vous une exception <code>Http404</code> — en production, cela va automatiquement afficher une page appropriée "ressource non trouvée", que vous pouvez personnaliser si besoin.</p>
+
+<p>Juste pour vous donner une idée de la manière dont tout cela fonctionne, le morceau de code ci-dessous montre comment vous implémenteriez cette vue comme une fonction si vous n'utilisiez <strong>pas</strong> la vue générique basée sur classe "détail".</p>
+
+<pre class="brush: python notranslate">def book_detail_view(request, primary_key):
+ try:
+ book = Book.objects.get(pk=primary_key)
+ except Book.DoesNotExist:
+ raise Http404('Book does not exist')
+
+ return render(request, 'catalog/book_detail.html', context={'book': book})
+</pre>
+
+<p>La vue essaie d'abord d'obtenir du modèle l'enregistrement correspondant au livre spécifié. Si cela échoue, la vue devrait lever une exception <code>Http404</code> pour indiquer que le livre est "non trouvé". L'étape finale est ensuite, comme d'habitude, d'appeler <code>render()</code> avec le nom du template et les données concernant le livre dans le paramètre <code>context</code> (comme un dictionnaire).</p>
+
+<p>Une alternative consiste à utiliser la fonction <code>get_object_or_404()</code> comme un raccourci pour lever une exception <code>Http404</code> si l'enregistrement n'existe pas.</p>
+
+<pre class="brush: python notranslate">from django.shortcuts import get_object_or_404
+
+def book_detail_view(request, primary_key):
+  book = get_object_or_404(Book, pk=primary_key)
+ return render(request, 'catalog/book_detail.html', context={'book': book})</pre>
+
+<h3 id="Créerle_template_de_la_Vue_Détail">Créerle template de la Vue Détail</h3>
+
+<p>Créez le fichier HTML <strong>/locallibrary/catalog/templates/catalog/book_detail.html</strong>, et copiez-y le code ci-dessous. Comme on l'a dit plus haut, c'est là le nom de template attendu par défaut par la vue générique basée sur classe <em>detail</em> (pour un modèle appelé <code>Book</code> dans une application appelée <code>catalog</code>).</p>
+
+<pre class="brush: html notranslate">{% extends "base_generic.html" %}
+
+{% block content %}
+ &lt;h1&gt;Title: \{{ book.title }}&lt;/h1&gt;
+
+ &lt;p&gt;&lt;strong&gt;Author:&lt;/strong&gt; &lt;a href=""&gt;\{{ book.author }}&lt;/a&gt;&lt;/p&gt; &lt;!-- author detail link not yet defined --&gt;
+ &lt;p&gt;&lt;strong&gt;Summary:&lt;/strong&gt; \{{ book.summary }}&lt;/p&gt;
+ &lt;p&gt;&lt;strong&gt;ISBN:&lt;/strong&gt; \{{ book.isbn }}&lt;/p&gt;
+ &lt;p&gt;&lt;strong&gt;Language:&lt;/strong&gt; \{{ book.language }}&lt;/p&gt;
+ &lt;p&gt;&lt;strong&gt;Genre:&lt;/strong&gt; \{{ book.genre.all|join:", " }}&lt;/p&gt;
+
+ &lt;div style="margin-left:20px;margin-top:20px"&gt;
+ &lt;h4&gt;Copies&lt;/h4&gt;
+
+ {% for copy in book.bookinstance_set.all %}
+ &lt;hr&gt;
+ &lt;p class="{% if copy.status == 'a' %}text-success{% elif copy.status == 'm' %}text-danger{% else %}text-warning{% endif %}"&gt;
+ \{{ copy.get_status_display }}
+ &lt;/p&gt;
+ {% if copy.status != 'a' %}
+ &lt;p&gt;&lt;strong&gt;Due to be returned:&lt;/strong&gt; \{{ copy.due_back }}&lt;/p&gt;
+ {% endif %}
+ &lt;p&gt;&lt;strong&gt;Imprint:&lt;/strong&gt; \{{ copy.imprint }}&lt;/p&gt;
+ &lt;p class="text-muted"&gt;&lt;strong&gt;Id:&lt;/strong&gt; \{{ copy.id }}&lt;/p&gt;
+ {% endfor %}
+ &lt;/div&gt;
+{% endblock %}</pre>
+
+<ul>
+</ul>
+
+<div class="note">
+<p>Le lien vers l'auteur dans le template ci-dessus est vide, parce que nous n'avons pas encore crée de page détail pour un auteur. Une fois que cette page sera créée, vous pourrez remplacer l'URL par ceci :</p>
+
+<pre class="notranslate">&lt;a href="<strong>{% url 'author-detail' book.author.pk %}</strong>"&gt;\{{ book.author }}&lt;/a&gt;
+</pre>
+</div>
+
+<p>Bien qu'en un peu plus grand, presque tout ce qu'il y a dans ce template a été décrit précédemment :</p>
+
+<ul>
+ <li>Nous étendons notre template de base et récrivons le block "content".</li>
+ <li>Nous utilisons une procédure conditionnelle pour déterminer s'il faut ou non afficher tel contenu spécifique.</li>
+ <li>Nous utilisons une boucle <code>for</code> pour boucler sur des listes d'objets.</li>
+ <li>Nous accédons aux champs du contexte en utilisant la notation à point (parce que nous avons utilisé la vue générique <em>detail</em>, le contexte est nommé <code>book</code> ; nous pourrions aussi utiliser "<code>object</code>").</li>
+</ul>
+
+<p>Une chose intéressante que nous n'avons pas encore vue, c'est la fonction <code>book.bookinstance_set.all()</code>. Cette méthode est "automagiquement" construite par Django pour retourner l'ensemble des enregistrements <code>BookInstance</code> associés à un <code>Book</code> particulier.</p>
+
+<pre class="brush: python notranslate">{% for copy in book.bookinstance_set.all %}
+ &lt;!-- code to iterate across each copy/instance of a book --&gt;
+{% endfor %}</pre>
+
+<p>Cette méthode est requise parce que vous déclarez un champ <code>ForeignKey</code> (one-to-many) seulement du côté "one" de la relation. Comme vous ne faites rien pour déclarer la relation dans les modèles opposés ("many"), Django n'a pas de champ pour récupérer l'ensemble des enregistrements associés. Pour remédier à ce problème, Django construit une fonction justement nommée "recherche inversée", que vous pouvez utiliser. Le nom de la fonction est construit en mettant en minuscule le nom du modèle où a été déclarée la <code>ForeignKey</code>, suivi de <code>_set</code> (ainsi la fonction créée dans <code>Book</code> est <code>bookinstance_set()</code>).</p>
+
+<div class="note">
+<p><strong>Note </strong>: Ici nous utilisons <code>all()</code> pour récupérer tous les enregistrements (comportement par défaut). Bien que vous puissiez utiliser la méthode <code>filter()</code> pour obtenir un sous-ensemble d'enregistrements dans le code, vous ne pouvez faire cela directement dans le template, parce que vous ne pouvez pas spécifier d'arguments dans les fonctions.</p>
+
+<p>Prenez garde également que, si vous ne définissez pas un ordre (dans votre vue basée sur classe ou votre modèle), vous allez voir des erreurs de ce genre en provenance du serveur de développement :</p>
+
+<pre class="notranslate">[29/May/2017 18:37:53] "GET /catalog/books/?page=1 HTTP/1.1" 200 1637
+/foo/local_library/venv/lib/python3.5/site-packages/django/views/generic/list.py:99: UnorderedObjectListWarning: Pagination may yield inconsistent results with an unordered object_list: &lt;QuerySet [&lt;Author: Ortiz, David&gt;, &lt;Author: H. McRaven, William&gt;, &lt;Author: Leigh, Melinda&gt;]&gt;
+ allow_empty_first_page=allow_empty_first_page, **kwargs)
+</pre>
+
+<p>Ceci vient du fait que l'<a href="https://docs.djangoproject.com/en/2.1/topics/pagination/#paginator-objects">objet paginator</a> s'attend à ce qu'un ORDER BY soit exécuté sur votre base de données sous-jacente. Sans cela il ne peut pas être sûr que les enregistrements retournés sont vraiment dans le bon ordre !</p>
+
+<p>Ce tutoriel n'a pas (encore !) traité de la <strong>pagination</strong>, mais comme vous ne pouvez pas utiliser <code>sort_by()</code> et passer un paramètre (pour la même raison que le <code>filter()</code> décrit précédemment), vous avez le choix entre trois options :</p>
+
+<ol>
+ <li>Ajouter un <code>ordering</code> lors de la déclaration de la <code>class Meta</code> dans votre modèle.</li>
+ <li>Ajouter un attribut <code>queryset</code> dans votre vue personnalisée basée sur classe, en spécifiant un <code>order_by()</code>.</li>
+ <li>Ajouter une méthode <code>get_queryset</code> à votre vue personnalisée basée sur classe, et préciser de même un <code>order_by()</code>.</li>
+</ol>
+
+<p>Si vous décidez d'ajouter une <code>class Meta</code> au modèle <code>Author</code> (solution peut-être pas aussi flexible que personnalier la vue basée sur classe, mais assez facile), vous allez vous retrouver avec quelque chose de ce genre :</p>
+
+<pre class="notranslate">class Author(models.Model):
+ first_name = models.CharField(max_length=100)
+ last_name = models.CharField(max_length=100)
+ date_of_birth = models.DateField(null=True, blank=True)
+ date_of_death = models.DateField('Died', null=True, blank=True)
+
+ def get_absolute_url(self):
+ return reverse('author-detail', args=[str(self.id)])
+
+ def __str__(self):
+ return f'{self.last_name}, {self.first_name}'
+
+<strong> class Meta:
+ ordering = ['last_name']</strong></pre>
+
+<p>Bien sûr le champ n'est pas forcément <code>last_name</code> : ce pourrait être un autre champ.</p>
+
+<p>Dernier point, mais non le moindre : vous devriez trier les données par un attribut/colonne qui a réellement un index (unique ou pas) dans votre base de données, afin d'éviter des problèmes de performance. Bien sûr ce n'est pas requis ici (ce serait un peu exagéré avec si peu de livres et d'utilisateurs), mais il vaut mieux avoir cela à l'esprit pour de futurs projets.</p>
+</div>
+
+<h2 id="À_quoi_cela_ressemble-t-il_2">À quoi cela ressemble-t-il ?</h2>
+
+<p>À ce point, nous devrions avoir créé tout ce qu'il faut pour afficher à la fois la liste des livres et les pages de détail pour chaque livre. Lancez le serveur (<code>python3 manage.py runserver</code>) et ouvrez votre navigateur à l'adresse <a href="http://127.0.0.1:8000/">http://127.0.0.1:8000/</a>.</p>
+
+<div class="warning">
+<p><strong>Attention :</strong> Ne cliquez pas sur les liens vers le détail des auteurs : vous allez les créer lors du prochain défi !</p>
+</div>
+
+<p>Cliquez sur le lien <strong>Tous les livres</strong> pour afficher la liste des livres.</p>
+
+<p><img alt="Book List Page" src="https://mdn.mozillademos.org/files/14049/book_list_page_no_pagination.png" style="border-style: solid; border-width: 1px; display: block; height: 216px; margin: 0px auto; width: 823px;"></p>
+
+<p>Ensuite cliquez sur un lien dirigeant vers l'un de vos livres. Si tout est réglé correctement, vous allez voir quelque chose de semblable à la capture d'écran suivante :</p>
+
+<p><img alt="Book Detail Page" src="https://mdn.mozillademos.org/files/14051/book_detail_page_no_pagination.png" style="border-style: solid; border-width: 1px; display: block; height: 783px; margin: 0px auto; width: 926px;"></p>
+
+<h2 id="Pagination">Pagination</h2>
+
+<p>Si vous avez seulement quelques enregistrements, notre page de liste de livres aura une bonne apparence. Mais si vous avez des dizaines ou des centaines d'enregistrements, la page va progressivement devenir plus longue à charger (et aura beaucoup trop de contenu pour naviguer de manière raisonnable). La solution à ce problème est d'ajouter une pagination à vos vues listes, en réduisant le nombre d'éléments affichés sur chaque page.</p>
+
+<p>Django a d'excellents outils pour la pagination. Mieux encore, ces outils sont intégrés dans les vues listes génériques basées sur classes, aussi n'avez-vous pas grand chose à faire pour les activer !</p>
+
+<h3 id="Vues">Vues</h3>
+
+<p>Ouvrez <strong>catalog/views.py</strong>, et ajoutez la ligne <code>paginate_by</code>, en gras ci-dessous.</p>
+
+<pre class="brush: python notranslate">class BookListView(generic.ListView):
+ model = Book
+ <strong>paginate_by = 10</strong></pre>
+
+<p>Avec cet ajout, dès que vous aurez plus de 10 enregistrements, la vue démarrera la pagination des données qu'elle envoie au template. Les différentes pages sont obtenues en utilisant le paramètre GET : pour obtenir la page 2, vous utiliseriez l'URL <code>/catalog/books/<strong>?page=2</strong></code>.</p>
+
+<h3 id="Templates">Templates</h3>
+
+<p>Maintenant que les données sont paginées, nous avons besoin d'ajouter un outil au template pour parcourir l'ensemble des résultats. Et parce que nous voudrons sûrement faire cela pour toutes les listes vues, nous allons le faire d'une manière qui puisse être ajoutée au template de base.</p>
+
+<p>Ouvrez <strong>/locallibrary/catalog/templates/<em>base_generic.html</em></strong>, et copiez-y, sous notre bloc de contenu, le bloc de pagination suivant (mis en gras ci-dessous). Le code commence par vérifier si une pagination est activée sur la page courante. Si oui, il ajoute les liens "précédent" et "suivant" appropriés (et le numéro de la page courante).</p>
+
+<pre class="brush: python notranslate">{% block content %}{% endblock %}
+
+<strong>  {% block pagination %}
+    {% if is_paginated %}
+        &lt;div class="pagination"&gt;
+            &lt;span class="page-links"&gt;
+                {% if page_obj.has_previous %}
+                    &lt;a href="\{{ request.path }}?page=\{{ page_obj.previous_page_number }}"&gt;previous&lt;/a&gt;
+                {% endif %}
+                &lt;span class="page-current"&gt;
+                    Page \{{ page_obj.number }} of \{{ page_obj.paginator.num_pages }}.
+                &lt;/span&gt;
+                {% if page_obj.has_next %}
+                    &lt;a href="\{{ request.path }}?page=\{{ page_obj.next_page_number }}"&gt;next&lt;/a&gt;
+                {% endif %}
+            &lt;/span&gt;
+        &lt;/div&gt;
+    {% endif %}
+  {% endblock %} </strong></pre>
+
+<p>Le <code>page_obj</code> est un objet <a href="https://docs.djangoproject.com/en/2.1/topics/pagination/#paginator-objects">Paginator</a> qui n'existera que si une pagination est utilisée dans la page courante. Cet objet vous permet de récupérer toutes les informations sur la page courante, les pages précédentes, combien il y a de pages au total, etc.</p>
+
+<p>Nous utilisons <code>\{{ request.path }}</code> pour récupérer l'URL de la page courante, afin de créer les liens de pagination. Cela est utile, car cette variable est indépendante de l'objet que nous sommes en train de paginer.</p>
+
+<p>C'est tout !</p>
+
+<h3 id="À_quoi_cela_ressemble-t-il_3">À quoi cela ressemble-t-il ?</h3>
+
+<p>La capture d'écran ci-dessous montre à quoi ressemble la pagination. Si vous n'avez pas entré plus de 10 titres dans votre base de données, vous pouvez tester plus facilement cette pagination en diminuant le nombre spécifié à la ligne <code>paginate_by</code> dans votre  fichier <strong>catalog/views.py</strong>. Pour obtenir le résultat ci-dessous, nous avons changé la ligne en <code>paginate_by = 2</code>.</p>
+
+<p>Les liens de pagination sont affichés en bas de la page, avec les liens suivant/précédent affichés selon la page sur laquelle nous nous trouvons.</p>
+
+<p><img alt="Book List Page - paginated" src="https://mdn.mozillademos.org/files/14057/book_list_paginated.png" style="border-style: solid; border-width: 1px; display: block; height: 216px; margin: 0px auto; width: 924px;"></p>
+
+<h2 id="Mettez-vous_vous-même_au_défi_!">Mettez-vous vous-même au défi !</h2>
+
+<p>Le challenge dans cet article consiste à créer les vues détail et liste nécessaires à l'achèvement du projet. Ces pages devront être accessibles aux URLs suivantes :</p>
+
+<ul>
+ <li><code>catalog/authors/</code> — La liste de tous les auteurs.</li>
+ <li><code>catalog/author/<em>&lt;id&gt;</em></code><em> </em>— La vue détail pour un auteur précis, avec un champ clé-primaire appelé <em><code>&lt;id&gt;</code></em>.</li>
+</ul>
+
+<p>Le code requis pour le mappeur d'URL et les vues sera virtuellement identique aux vues liste et détail du modèle <code>Book</code>, créées ci-dessus. Les templates seront différents, mais auront un comportement semblable.</p>
+
+<div class="note">
+<p><strong>Note</strong>:</p>
+
+<ul>
+ <li>Une fois que vous aurez créé le mappeur d'URL pour la page "liste d'auteurs", vous aurez besoin de mettre aussi à jour le lien <strong>All authors</strong> dans le template de base. Suivez la <a href="#Update_the_base_template">même procédure</a> que celle adoptée quand nous avons mis à jour le lien <strong>All books</strong>.</li>
+ <li>Une fois créé le mappeur d'URL pour la page de détails sur l'auteur, vous devrez aussi mettre à jour le <a href="#Creating_the_Detail_View_template">template de la vue détail d'un livre</a> (<strong>/locallibrary/catalog/templates/catalog/book_detail.html</strong>), de sorte que le lien vers l'auteur pointe vers votre nouvelle page de détails sur l'auteur (au lieu d'être une URL vide). La ligne va avoir comme changement la balise montrée en gras ci-dessous.
+ <pre class="brush: html notranslate">&lt;p&gt;&lt;strong&gt;Author:&lt;/strong&gt; &lt;a href="<strong>{% url 'author-detail' book.author.pk %}</strong>"&gt;\{{ book.author }}&lt;/a&gt;&lt;/p&gt;
+</pre>
+ </li>
+</ul>
+</div>
+
+<p>Quand vous aurez fini, vos pages vont ressembler aux captures d'écran suivantes.</p>
+
+<p><img alt="Author List Page" src="https://mdn.mozillademos.org/files/14053/author_list_page_no_pagination.png" style="border-style: solid; border-width: 1px; display: block; margin: 0px auto;"></p>
+
+<ul>
+</ul>
+
+<p><img alt="Author Detail Page" src="https://mdn.mozillademos.org/files/14055/author_detail_page_no_pagination.png" style="border-style: solid; border-width: 1px; display: block; height: 358px; margin: 0px auto; width: 825px;"></p>
+
+<ul>
+</ul>
+
+<h2 id="Résumé">Résumé</h2>
+
+<p>Félicitations ! Notre application basique pour bibliothèque est maintenant terminée.</p>
+
+<p>Dans cet article, nous avons appris comment utiliser les vues génériques basées sur classe "liste" et "détail", et nous les avons utilisées pour créer des pages permettant de voir nos livres et nos auteurs. Au passage nous avons appris la recherche d'un pattern d'URL grâce aux expressions régulières, et la manière de passer des données depuis les URLs vers les vues. Nous avons aussi appris quelques trucs supplémentaires pour mieux utiliser les templates. Et en dernier nous vous avons montré comment paginer les vues liste, de façon à pouvoir gérer des listes même avec beaucoup d'enregistrements.</p>
+
+<p>Dans les articles que nous vous présenterons ensuite, nous améliorerons cette application pour intégrer des comptes utilisateurs, et nous allons donc vous montrer comment gérer l'authentification des utilisateurs, les permissions, les sessions et les formulaires.</p>
+
+<h2 id="Voyez_aussi">Voyez aussi</h2>
+
+<ul>
+ <li><a href="https://docs.djangoproject.com/en/2.1/topics/class-based-views/generic-display/">Built-in class-based generic views</a> (Django docs)</li>
+ <li><a href="https://docs.djangoproject.com/en/2.1/ref/class-based-views/generic-display/">Generic display views</a> (Django docs)</li>
+ <li><a href="https://docs.djangoproject.com/en/2.1/topics/class-based-views/intro/">Introduction to class-based views</a> (Django docs)</li>
+ <li><a href="https://docs.djangoproject.com/en/2.1/ref/templates/builtins">Built-in template tags and filters</a> (Django docs).</li>
+ <li><a href="https://docs.djangoproject.com/en/2.1/topics/pagination/">Pagination</a> (Django docs)</li>
+</ul>
+
+<p>{{PreviousMenuNext("Learn/Server-side/Django/Home_page", "Learn/Server-side/Django/Sessions", "Learn/Server-side/Django")}}</p>
+
+<h2 id="In_this_module">In this module</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Introduction">Django introduction</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/development_environment">Setting up a Django development environment</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">Django Tutorial: The Local Library website</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/skeleton_website">Django Tutorial Part 2: Creating a skeleton website</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Models">Django Tutorial Part 3: Using models</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Admin_site">Django Tutorial Part 4: Django admin site</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Home_page">Django Tutorial Part 5: Creating our home page</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Generic_views">Django Tutorial Part 6: Generic list and detail views</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Sessions">Django Tutorial Part 7: Sessions framework</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Authentication">Django Tutorial Part 8: User authentication and permissions</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Forms">Django Tutorial Part 9: Working with forms</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Testing">Django Tutorial Part 10: Testing a Django web application</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/Deployment">Django Tutorial Part 11: Deploying Django to production</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/web_application_security">Django web application security</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Django/django_assessment_blog">DIY Django mini blog</a></li>
+</ul>
diff --git a/files/fr/learn/server-side/express_nodejs/index.html b/files/fr/learn/server-side/express_nodejs/index.html
new file mode 100644
index 0000000000..d361dd6fd9
--- /dev/null
+++ b/files/fr/learn/server-side/express_nodejs/index.html
@@ -0,0 +1,71 @@
+---
+title: Express Web Framework (Node.js/JavaScript)
+slug: Learn/Server-side/Express_Nodejs
+tags:
+ - Apprentissage
+ - Débutant
+ - Express
+ - Express.js
+ - Programmation côté client
+ - Programmation côté serveur
+translation_of: Learn/Server-side/Express_Nodejs
+---
+<div>{{LearnSidebar}}</div>
+
+<p class="summary">Express est une infrastructure d'application (framework), écrit en JavaScript et hébergée dans l'environnement d'exécution node.js. Cette section explique certains de ses principaux avantages, comment configurer votre environnement de développement et comment effectuer des tâches courantes de développement et de déploiement.</p>
+
+<h2 id="Prérequis">Prérequis</h2>
+
+<p>Avant d'aller plus loin, vous devrez avoir compris ce qu'est la programmation côté serveur et le concept de "framework", idéalement en ayant lu notre article <a href="/en-US/docs/Learn/Server-side/First_steps">Premiers pas en programmation côté-serveur</a>. Une connaissance générale des concepts de programmation et du <a href="/en-US/docs/Web/JavaScript">JavaScript</a> est vivement recommandée, sans pour autant être essentielle à la compréhension des concepts fondamentaux.</p>
+
+<div class="note">
+<p><strong>Note </strong>:  Le site MDN possède de nombreuses ressources utiles pour apprendre JavaScript dans le contexte du <em>développement côté client </em>: <a href="/en-US/docs/Web/JavaScript">JavaScript</a>, <a href="/en-US/docs/Web/JavaScript/Guide">JavaScript Guide</a>, <a href="/en-US/docs/Learn/Getting_started_with_the_web/JavaScript_basics">JavaScript Basics</a>, <a href="/en-US/docs/Learn/JavaScript">JavaScript</a> (apprentissage). Le noyau du langage et les principaux concepts de JavaScript sont les mêmes que pour le développement côté serveur sur Node.js, il est donc important d'avoir déjà une bonne compréhension de JavaScript avant de continuer. Node.js offre des <a href="https://nodejs.org/dist/latest-v6.x/docs/api/">API supplémentaires</a> pour supporter des fonctionnalités utiles dans des environnements sans navigateur, par ex. pour créer des serveurs HTTP et accéder au système de fichiers, mais ne prend pas en charge les API JavaScript pour travailler avec le navigateur et le DOM.</p>
+
+<p>Ce guide vous fournira des informations sur l'utilisation de Node.js et Express, et contient de nombreuses références à d'autres excellentes ressources sur Internet et dans des livres — dont des liens depuis <a href="http://stackoverflow.com/a/5511507/894359">How do I get started with Node.js</a> (StackOverflow) et <a href="https://www.quora.com/What-are-the-best-resources-for-learning-Node-js?">What are the best resources for learning Node.js?</a> (Quora).</p>
+</div>
+
+<h2 id="Guides">Guides</h2>
+
+<dl>
+ <dt><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Introduction">Introduction à Express/Node</a></dt>
+ <dd>Dans ce premier article sur Express nous répondons aux questions « Qu'est-ce que Node? » et « Qu'est-ce que Express? » et vous donne une vue d'ensemble de ce qui rend cette infrastructure d'application Express si spéciale. Nous allons décrire les principales fonctionnalités et vous montrer quelques-uns des principaux éléments constitutifs d'une application Express (bien qu'à ce stade, vous n'aurez pas encore un environnement de développement dans lequel le tester)</dd>
+ <dt><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/development_environment">Installer un environnement de développement pour Node (Express)</a></dt>
+ <dd>Maintenant que nous savons à quoi sert Express, nous allons vous apprendre à installer et tester un environnement de développement Node/Express sur Windows, Linux (Ubuntu), et Mac OS X. Quel que soit votre système d'exploitation, cet article devrait vous fournir le nécessaire pour commencer le développement d'applications Express.</dd>
+ <dt><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Tutorial_local_library_website">Tutoriel Express : le site d'une bibliothèque locale</a></dt>
+ <dd>Le premier article de notre série de tutoriels explique ce que vous allez apprendre et fournit l'aperçu d'un exemple de site de « bibliothèque locale » sur lequel nous allons travailler par le biais d'articles conséquents et évolutifs.</dd>
+ <dt><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/skeleton_website">2e partie du tutoriel Express : création d'un squelette de site internet</a></dt>
+ <dd>Cet article explique comment vous pouvez créer un « squelette » de projet de site web, que vous pouvez alors étoffer de <em>routes</em> spécifiques, de modèles de vues et de bases de données.</dd>
+ <dt><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/mongoose">3e partie du tutoriel Express : utilisation d'une base de données (avec Mongoose)</a></dt>
+ <dd>Cet article introduit brièvement le concept de base de données pour Node/Express. Il se poursuit en décrivant comment on peut utiliser <a href="http://mongoosejs.com/">Mongoose</a> pour fournir un accès à la base de données de notre site internet de Bibliothèque locale. Il explique comment les schémas de données et les modèles sont déclarées, les types principaux des champs de données, et les validations de base. Il donne aussi un aperçu rapide de quelques moyens d'accéder aux données.</dd>
+ <dt><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/routes">4e partie du tutoriel Express : les routes et les contrôleurs</a></dt>
+ <dd>Dans ce tutoriel nous programmerons des routes (traitements des URL) avec des fonctions factices de traitement pour tous les points de sortie dont nous pourrions éventuellement avoir besoin pour notre site web de la bibliothèque locale. Nous obtiendrons ainsi une structure modulaire pour notre code de traitement par les routes, que nous pourrons étendre avec de vraies fonctions de traitement dans les articles suivants. Nous acquiérerons de cette manière une réelle compréhension de la création modulaire des routes avec Express.</dd>
+ <dt><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Displaying_data">5e partie du tutoriel Express : affichage des données de la bibliothèque</a></dt>
+ <dd>Nous sommes prêts maintenant à ajouter des pages qui affireront les livres et autres données de notre bibliothèque locale sur son site internet. Ces pages incluront notamment une page d'accueil qui indiquera le nombre d'enregistrements pour chaque type de modèle de donnée, une liste et des pages de détail pour chacun de ces modèles. Chemin faisant, nous acquiérerons de l'expérience dans la récupération des données depuis la base, et l'utilisation des modèles de vue (<em>templates</em>).</dd>
+ <dt><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/forms">6e partie du tutoriel Express : travail avec les formulaires</a></dt>
+ <dd>Dans ce tutoriel nous verrons comment travailler avec les <a href="/en-US/docs/Web/Guide/HTML/Forms">HTML Forms</a> dans Express, à l'aide de Pug, et en particulier comment concevoir des formulaires pour créer, actualiser et détruire des documents dans la base de données.</dd>
+ <dt><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/deployment">7e partie du tutoriel Express : déploiement de l'application en production</a></dt>
+ <dd>Maintenant que nous avons créé un fantastique site internet pour notre bibliothèque locale, nous allons vouloir installer le serveur du site public pour qu'il soit accessible par les employés de la bibliothèques et les adhérents depuis n'importe où par le net. Cet article fournit un aperçu de comment trouver un hébergement pour déployer son site web et ce que vous avez à faire pour préparer votre site à la production.</dd>
+</dl>
+
+<h2 id="Voir_aussi">Voir aussi</h2>
+
+<dl>
+ <dt><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Installing_on_PWS_Cloud_Foundry">Installation de la LocalLibrary sur le cloud PWS/Cloud Foundry</a></dt>
+ <dd>Cet article fournit une démonstration concrète de l'installation de la <em>LocalLibrary</em> sur le cloud <a href="http://run.pivotal.io">Pivotal Web Services PaaS</a> — alternative à Heroku, open-source et complètement fonctionnelle, le service de cloud PaaS utilisé dans la 7e partie de ce tutoriel, listée ci-dessus. PWS/Cloud Foundry vaut définitivement la peine d'être envisagé si vous cherchez une alternative à Heroku (ou à un autre service de cloud PaaS), ou si vous êtes d'humeur à essayer quelque chose de différent.</dd>
+</dl>
+
+<h2 id="Ajout_de_tutoriels">Ajout de tutoriels</h2>
+
+<div>
+<p>C'est la fin des articles du tutoriel. Si vous avez envie de l'étendre, d'autres sujets intéressants à couvrir sont :</p>
+
+<ul>
+ <li>l'utilisation des sessions ;</li>
+ <li>l'authentication des utilisateurs ;</li>
+ <li>l'authentification des utilisateurs et leurs privilèges ;</li>
+ <li>le test d'une application web Express ;</li>
+ <li>applications web Express et sécurité.</li>
+</ul>
+
+<p>Et bien sûr, il serait excellent d'avoir une tâche d'évaluation !</p>
+</div>
diff --git a/files/fr/learn/server-side/express_nodejs/introduction/index.html b/files/fr/learn/server-side/express_nodejs/introduction/index.html
new file mode 100644
index 0000000000..5f87d9d77a
--- /dev/null
+++ b/files/fr/learn/server-side/express_nodejs/introduction/index.html
@@ -0,0 +1,537 @@
+---
+title: Introduction Express/Node
+slug: Learn/Server-side/Express_Nodejs/Introduction
+tags:
+ - Débutant
+ - Express
+ - Node
+ - Serveur
+ - nodejs
+translation_of: Learn/Server-side/Express_Nodejs/Introduction
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{NextMenu("Learn/Server-side/Express_Nodejs/development_environment", "Learn/Server-side/Express_Nodejs")}}</div>
+
+<p class="summary">Dans ce tout premier article consacré à Express, nous répondons aux questions « Qu'est-ce que Node ? » (réponse : une bibliothèque) et « Qu'est-ce que Express? », et vous donnons un aperçu de ce qui fait d'Express un framework web si spécial. Nous décrirons les principales fonctionnalités et vous montrerons quelques-uns des principaux composants d'une application Express (bien que vous ne disposiez pas encore d'un environnement de développement pour le tester).</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Prérequis :</th>
+ <td>Une culture de base en informatique, une compréhension globale de la <a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/First_steps">programmation côté serveur </a>et, en particulier, les mécanismes d'<a href="/en-US/docs/Learn/Server-side/First_steps/Client-Server_overview">interactions client-serveur dans un site web.</a></td>
+ </tr>
+ <tr>
+ <th scope="row">Objectif :</th>
+ <td>Devenir familier avec ce qu'est Express et comment il s'intégre dans Node, les fonctionnalités qu'il apporte, et les principales étapes pour construire une application Express.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Node_présentation">Node : présentation</h2>
+
+<p><a href="https://nodejs.org/">Node</a> (ou plus formellement <em>Node.js</em>) est un environnement d'exécution open-source, multi-plateforme, qui permet aux développeurs de créer toutes sortes d'applications et d'outils côté serveur en <a href="/en-US/docs/Glossary/JavaScript">JavaScript</a>. Cet environnement est destiné à être utilisé en dehors du navigateur (il s'exécute directement sur son ordinateur ou dans le système d'exploitation du serveur). Il ignore les API JavaScript liées au navigateur et ajoute du support pour des API plus traditionnelles, comprenant HTTP et des librairies de fichiers système.</p>
+
+<p>Dans la perpective d'un développement serveur web, Node possède de nombreux atouts :</p>
+
+<ul>
+ <li>D'excellentes performances ! Node a été créé pour optimiser le rendement et l'évolution des applications web et est une très bonne solution à de nombreux problèmes de développement web (applications en temps réel).</li>
+ <li>Le code est intégralement écrit en JavaScript ce qui signifie que l'on dépense moins d'énergie à basculer d'un langage à l'autre quand on code côté client et côté serveur.</li>
+ <li>Le JavaScript est un langage de programmation plutôt récent et bénéficie encore d'améliorations dans sa conception comparé à d'autres langages web côté serveur (Python, PHP, etc.). Beaucoup d'autres langages nouveaux et populaires compilent/convertissent en JavaScript pour pouvoir utiliser CoffeeScript, ClojureScript, Scala, LiveScript, etc.</li>
+ <li>Le gestionnaire de paquets (NPM) offre l'accès à des milliers de librairies réutilisables. Il a aussi la meilleure résolution de dépendances du marché et peut être utilisé pour automatiser la plupart des chaines de compilation.</li>
+ <li>Node.js est portable. Il est disponible sous Microsoft Windows, OS X, Linux, Solaris, FreeBSD, OpenBSD, WebOS, et NonStop OS. De plus, il est bien supporté par beaucoup d'hébergeurs web qui fournissent souvent une infrastructure spécifique et une documentation pour héberger des sites Node.</li>
+ <li>Node possède une communauté de développeurs et un écosystème très dynamique avec beaucoup de gens désireux d'aider.</li>
+</ul>
+
+<p>Vous pouvez utiliser Node.js pour créer un simple serveur web en utilisant le paquet Node HTTP.</p>
+
+<h3 id="Hello_Node.js">Hello Node.js</h3>
+
+<p>L'exemple qui suit crée un serveur web qui écoute toutes sortes de requêtes HTTP sur l'URL <code>http://127.0.0.1:8000/</code>. Quand une requête est reçue, le script répond avec la chaine "Salut tout le monde". Si vous avez déjà installé Node, suivez les étapes de l'exemple suivant :</p>
+
+<ol>
+ <li>Ouvrez un terminal de commande (sur Windows, ouvrez CMD),</li>
+ <li>Créez le dossier où vous voulez sauvegarder le programme, appelez-le par exemple <code>"test-node"</code> et placez-vous dedans en utilisant la commande suivante dans votre console :</li>
+</ol>
+
+<pre class="notranslate">cd test-node</pre>
+
+<ol start="3">
+ <li>Dans votre éditeur de texte favori, créez un fichier nommé <code>"hello.js"</code> et collez ce qui suit dedans :</li>
+</ol>
+
+<pre class="brush: js notranslate">// Charge le module HTTP
+const http = require("http");
+
+const hostname = "127.0.0.1";
+const port = 8000;
+
+// Crée un serveur HTTP
+const server = http.createServer((req, res) {
+
+ // Configure l'en-tête de la réponse HTTP avec le code du statut et le type de contenu
+ response.writeHead(200, {'Content-Type': 'text/plain'});
+
+ // Envoie le corps de la réponse "Salut tout le monde"
+ response.end('Salut tout le monde\n');
+})
+
+// Démarre le serveur à l'adresse 127.0.0.1 sur le port 8000
+// Affiche un message dès que le serveur commence à écouter les requêtes
+server.listen(port, hostname, () =&gt; {
+ console.log(`Le serveur tourne à l'adresse http://${hostname}:${port}/`);
+})
+</pre>
+
+<ol start="4">
+ <li>Sauvegardez le fichier dans le dossier créé plus haut.</li>
+ <li>Retournez au terminal et tapez :</li>
+</ol>
+
+<pre class="brush: bash notranslate">node hello.js</pre>
+
+<p>Puis saisissez l'URL <code>"http://localhost:8000"</code> dans votre navigateur. Vous devriez alors voir "<strong>Salut tout le monde</strong>" en haut à gauche d'une page web ne contenant rien d'autre que ce texte.</p>
+
+<h2 id="Les_cadres_applicatifs_Web">Les cadres applicatifs Web</h2>
+
+<p>D'autres tâches de développement web ne sont pas directement supportées par Node lui-même. Si vous voulez ajouter différentes manipulations pour divers requêtes HTTP (<code>GET</code>, <code>POST</code>, <code>DELETE</code>, etc.), gérer différemment des requêtes vers plusieurs chemins URL ("routes"), servir des pages statiques ou utiliser des modèles pour créer dynamiquement la réponse,  alors vous devrez écrire tout le code vous-même ou, pour éviter de réinventer la roue, vous servir des cadres applicatifs web (frameworks).</p>
+
+<h2 id="Introduction_à_Express">Introduction à Express</h2>
+
+<p><a href="https://expressjs.com/">Express</a> est le cadre applicatif actuellement le plus populaire dans Node et est la bibliothèque sous-jacente pour un grand nombre d'autres <a href="https://expressjs.com/en/resources/frameworks.html">cadres applicatifs web pour Node</a>. Il fournit des mécanismes pour :</p>
+
+<ul>
+ <li>Écrire des fonctions de traitement pour différentes requêtes HTTP répondant à différentes URI (par le biais des <em>routes</em>).</li>
+ <li>Intégrer avec les moteurs de rendu "view" dans le but de générer des réponses en insérant des données dans des gabarits ("templates") . Configurer certains paramétres d'applications comme le port à utiliser à la connexion et la localisation des gabarits nécessaires pour la mise en forme de la réponse.</li>
+ <li>Ajouter des requêtes de traitement "middleware" où vous le voulez dans le tunnel gestionnaire de la requête.</li>
+</ul>
+
+<p>Bien qu'Express soit assez minimaliste, les développeurs ont créé des <em>middlewares</em> (fonctions intermédiaires) compatibles pour résoudre quasiment tous les problèmes de développement web. Il existe des librairies pour se servir des cookies, gérer les sessions, la connexion utilisateur, les paramètres de l'URL, les données <code>POST</code>, les entêtes de sécurité et d'autres encore. Vous trouverez une liste des paquets maintenus par l'équipe Express ici : <a href="http://expressjs.com/en/resources/middleware.html">Express Middleware</a> (ainsi que la liste de paquets de tierce-parties populaires).</p>
+
+<div class="note">
+<p><strong>Note:</strong> Cette flexibilité est à double tranchant. Il y a une multitude de paquets pour résoudre chaque problème mais trouver le bon paquet à utiliser peut vite devenir un challenge. Il n'y a pas non plus de "bonne manière" pour structurer une application et beaucoup d'exemples que vous trouverez sur le net ne sont pas optimisés ou montrent seulement une infime partie de ce que vous devez faire pour développer une application web.</p>
+</div>
+
+<h2 id="Doù_viennent_Node_et_Express">D'où viennent Node et Express ?</h2>
+
+<p>À ses débuts en 2009, Node a été publié pour Linux uniquement. Le gestionnaire de paquets NPM est sorti en 2010, et le support natif de Windows fut ajouté en 2012. Aujourd'hui (juin 2020), la version courante ("current release") de Node est la 14.4.0 et la dernière version publiée est la 12.18.1. Ceci est un très court aperçu d'une aventure riche en rebondissements. Allez creuser ça sur <a href="https://en.wikipedia.org/wiki/Node.js#History">Wikipedia</a> si vous voulez en savoir plus.</p>
+
+<p>Express est sorti pour la première fois en Novembre 2010 et est aujourd'hui (juin 2020) à sa version 4.17.1 de l'API. Vous pouvez consulter la <a href="https://expressjs.com/en/changelog/4x.html">liste des modifications</a> pour plus d'informations sur la version courante et <a href="https://github.com/expressjs/express/blob/master/History.md">GitHub</a> pour plus de détails sur l'historique des publications.</p>
+
+<h2 id="Quelle_popularité_pour_Node_et_Express">Quelle popularité pour Node et Express?</h2>
+
+<p>La popularité d'un "framework" web est importante car elle conditionne la maintenance dans le temps et les ressources qu'il est raisonnable de mettre à disposition dans la documentation, les librairies d'extensions et le support technique.</p>
+
+<p>Il n'existe pas d'échelle de mesures définitive et fiable pour l'estimation de la popularité des "frameworks" côté serveur, bien que des sites comme <a href="http://hotframeworks.com/">Hot Frameworks</a> essaient d'estimer la popularité par le comptage du nombre de projets Github ou StackOverflow.  La question est : " Est-ce que Node et Express sont suffisamment populaires pour pouvoir s'affranchir des plateformes non-populaires ? Continuent-ils à évoluer ? Pouvez-vous avoir de l'aide si besoin ? Existe-til une opportunité pour vous de gagner de l'argent si vous apprenez Express ?".</p>
+
+<p>Si on se réfère à la<a href="https://expressjs.com/en/resources/companies-using-express.html"> liste de compagnies utilisant Express</a>, la quantité de gens contribuant au code et le nombre de gens fournissant un support payant ou bien gratuit, alors oui, <em>Express</em> est un framework populaire !</p>
+
+<h2 id="Express_est-il_dogmatique">Express est-il "dogmatique" ?</h2>
+
+<p>Les cadres logiciels web se décrivent souvent comme étant "opiniâtres" ou non (<em>opinionated</em> en anglais).</p>
+
+<p>Les cadres logiciels opiniâtres sont ceux qui ont un avis arrêté sur la "bonne manière" de gérer certaines tâches. Ils fournissent souvent un cadre permettant de développer rapidement <em>dans un domaine particulier </em>(résolvant des problèmes d'un type particulier) parce que la bonne manière de faire quoi que ce soit est généralement bien comprise et bien documentée. Toutefois, ils peuvent manquer de flexibilité pour la résolution de problèmes hors de de leur portée et tendent à offrir peu de choix concernant les composants et approches qu'ils peuvent utiliser.</p>
+
+<p>Les cadres logiciels non opiniâtres, par contraste, ont beaucoup moins de restrictions sur la meilleure manière d'assembler des composants ensemble pour atteindre un objectif, ou encore sur les composants que vous devriez utiliser. Ils laissent aux développeurs la possibilité d'utiliser les outils les plus adaptés pour achever une tâche particulière, bien que celà nécessite que vous cherchiez et trouviez ces composants par vous-même.<br>
+ <br>
+ Express n'est pas opiniâtre. Vous pouvez intégrer quasiment n'importe quelle fonction intermédiaire compatible que vous le désirez dans la pile de gestion de requête, dans quasiment n'importe quel ordre. Vous pouvez structurer l'application en un fichier comme en plusieurs, et utiliser n'importe quelle structure de dossiers. Vous pourrez même quelquefois vous sentir perdu par la liberté que vous avez de vous organiser comme vous le souhaitez !</p>
+
+<h2 id="À_quoi_ressemble_du_code_Express">À quoi ressemble du code Express ?</h2>
+
+<p>Dans un site web traditionnellement orienté données, une application web attend des requêtes HTTP du navigateur web (ou d'un autre client). Quand une requête est reçue, l'application cherche quelle action est requise en fonction du modèle de l'URL et des possibles informations associés contenues dans les données <code>POST</code> ou <code>GET</code>. Selon ce qui est requis, il pourra alors lire ou écrire des informations dans une une base de données ou effectuer d'autre tâches requises pour satisfaire la requête. L'application va alors retourner une réponse au navigateur web, souvent une page HTML créée dynamiquement pour le navigateur, en intégrant les données récupérées dans un modèle HTML.</p>
+
+<p>Express fournit des méthodes pour spécifier quelle fonction est appelée pour une méthode HTTP particulière (<code>GET</code>, <code>POST</code>, <code>SET</code>, etc.) et un modèle d'URL ("Route"), ainsi que des méthodes pour spécifier quel moteur de rendu de vues ("view") est utilisé, où sont les modèles de vues et quel modèle utiliser pour générer une réponse. Vous pouvez utiliser les fonctions intermédiaires d'Express pour ajouter un support pour les cookies, les sessions, les utilisateurs, obtenir les paramètres <code>POST</code>/<code>GET</code>, etc. Vous pouvez utliser n'importe que système de base données supporté par Node (Express ne définit aucun comportement relatif au bases de données).</p>
+
+<p>Les sections suivantes expliquent quelques choses communes que vous verrez en travaillant avec du code <em>Express</em> et <em>Node</em>.</p>
+
+<h3 id="Helloworld_Express">Helloworld Express</h3>
+
+<p>First lets consider the standard Express <a href="https://expressjs.com/en/starter/hello-world.html">Hello World</a> example (we discuss each part of this below, and in the following sections).</p>
+
+<div class="note">
+<p><strong>Tip:</strong> If you have Node and Express already installed (or if you install them as shown in the <a href="/en-US/docs/Learn/Server-side/Express_Nodejs/development_environment">next article</a>), you can save this code in a text file called <strong>app.js</strong> and run it in a bash command prompt by calling:   </p>
+
+<p><strong><code>./node ./app.js</code></strong></p>
+</div>
+
+<pre class="brush: js notranslate">var express = require('express');
+var app = express();
+
+<strong>app.get('/', function(req, res) {
+ res.send('Hello World!');
+});</strong>
+
+app.listen(3000, function() {
+ console.log('Example app listening on port 3000!');
+});
+</pre>
+
+<p>The first two lines <code>require()</code> (import) the express module and create an <a href="https://expressjs.com/en/4x/api.html#app">Express application</a>. This object, which is traditionally named <code>app</code>, has methods for routing HTTP requests, configuring middleware, rendering HTML views, registering a template engine, and modifying <a href="https://expressjs.com/en/4x/api.html#app.settings.table">application settings</a> that control how the application behaves (e.g. the environment mode, whether route definitions are case sensitive, etc.)</p>
+
+<p>The middle part of the code (the three lines starting with <code>app.get</code>) shows a <em>route definition</em>. The <code>app.get()</code> method specifies a callback function that will be invoked whenever there is an HTTP <code>GET</code> request with a path (<code>'/'</code>) relative to the site root. The callback function takes a request and a response object as arguments, and simply calls <code><a href="https://expressjs.com/en/4x/api.html#res.send">send()</a></code> on the response to return the string "Hello World!"</p>
+
+<p>The final block starts up the server on port '3000' and prints a log comment to the console. With the server running, you could go to <code>localhost:3000</code> in your browser to see the example response returned.</p>
+
+<h3 id="Créer_et_importer_des_modules">Créer et importer des modules</h3>
+
+<p>A module is a JavaScript library/file that you can import into other code using Node's <code>require()</code> function. <em>Express</em> itself is a module, as are the middleware and database libraries that we use in our <em>Express</em> applications.</p>
+
+<p>The code below shows how we import a module by name, using the <em>Express</em> framework as an example. First we invoke the <code style="font-style: normal; font-weight: normal;">require()</code> function, specifying the name of the module as a string (<code>'express'</code>), and calling the returned object to create an <a href="https://expressjs.com/en/4x/api.html#app">Express application</a>. We can then access the properties and functions of the application object.</p>
+
+<pre class="brush: js notranslate">var express = require('express');
+var app = express();
+</pre>
+
+<p>You can also create your own modules that can be imported in the same way.</p>
+
+<div class="note">
+<p><strong>Tip:</strong> You will <em>want </em>to create your own modules, because this allows you to organise your code into managable parts — a monolithic single-file application is hard to understand and maintain. Using modules also helps you manage your namespace, because only the variables you explicitly export are imported when you use a module.</p>
+</div>
+
+<p>To make objects available outside of a module you just need to assign them to the <code>exports</code> object. For example, the <strong>square.js</strong> module below is a file that exports <code>area()</code> and <code>perimeter()</code> methods:</p>
+
+<pre class="brush: js notranslate">exports.area = function(width) { return width * width; };
+exports.perimeter = function(width) { return 4 * width; };
+</pre>
+
+<p>We can import this module using <code>require()</code>, and then call the exported method(s) as shown:</p>
+
+<pre class="brush: js notranslate">var square = require('./square'); // Here we require() the name of the file without the (optional) .js file extension
+console.log('The area of a square with a width of 4 is ' + square.area(4));</pre>
+
+<div class="note">
+<p><strong>Note:</strong> You can also specify an absolute path to the module (or a name, as we did initially).</p>
+</div>
+
+<p>If you want to export a complete object in one assignment instead of building it one property at a time, assign it to <code>module.exports</code> as shown below (you can also do this to make the root of the exports object a constructor or other function):</p>
+
+<pre class="brush: js notranslate">module.exports = {
+ area: function(width) {
+ return width * width;
+ },
+
+ perimeter: function(width) {
+ return 4 * width;
+ }
+};
+</pre>
+
+<p>For a lot more information about modules see <a href="https://nodejs.org/api/modules.html#modules_modules">Modules</a> (Node API docs).</p>
+
+<h3 id="Using_asynchronous_APIs">Using asynchronous APIs</h3>
+
+<p>JavaScript code frequently uses asynchronous rather than synchronous APIs for operations that may take some time to complete. A synchronous API is one in which each operation must complete before the next operation can start. For example, the following log functions are synchronous, and will print the text to the console in order (First, Second).</p>
+
+<pre class="brush: js notranslate">console.log('First');
+console.log('Second');
+</pre>
+
+<p>By contrast, an asynchronous API is one in which the API will start an operation and immediately return (before the operation is complete). Once the operation finishes, the API will use some mechanism to perform additional operations. For example, the code below will print out "Second, First" because even though <code>setTimeout()</code> method is called first, and returns immediately, the operation doesn't complete for several seconds.</p>
+
+<pre class="brush: js notranslate">setTimeout(function() {
+ console.log('First');
+ }, 3000);
+console.log('Second');
+</pre>
+
+<p>Using non-blocking asynchronous APIs is even more important on Node than in the browser, because <em>Node</em> is a single threaded event-driven execution environment. "single threaded" means that all requests to the server are run on the same thread (rather than being spawned off into separate processes). This model is extremely efficient in terms of speed and server resources, but it does mean that if any of your functions call synchronous methods that take a long time to complete, they will block not just the current request, but every other request being handled by your web application.</p>
+
+<p>There are a number of ways for an asynchronous API to notify your application that it has completed. The most common way is to register a callback function when you invoke the asynchronous API, that will be called back when the operation completes. This is the approach used above.</p>
+
+<div class="note">
+<p><strong>Tip:</strong> Using callbacks can be quite "messy" if you have a sequence of dependent asynchronous operations that must be performed in order, because this results in multiple levels of nested callbacks. This problem is commonly known as "callback hell". This problem can be reduced by good coding practices (see <a href="http://callbackhell.com/">http://callbackhell.com/</a>), using a module like <a href="https://www.npmjs.com/package/async">async</a>, or even moving to ES6 features like <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise">Promises</a>.</p>
+</div>
+
+<div class="note">
+<p><strong>Note:</strong> A common convention for Node and Express is to use error-first callbacks. In this convention the first value in your <em>callback functions</em> is an error value, while subsequent arguments contain success data. There is a good explanation of why this approach is useful in this blog: <a href="http://fredkschott.com/post/2014/03/understanding-error-first-callbacks-in-node-js">The Node.js Way - Understanding Error-First Callbacks</a> (fredkschott.com).</p>
+</div>
+
+<h3 id="Creating_route_handlers">Creating route handlers</h3>
+
+<p>In our <em>Hello World</em> Express example (see above), we defined a (callback) route handler function for HTTP <code>GET</code> requests to the site root (<code>'/'</code>).</p>
+
+<pre class="brush: js notranslate">app.<strong>get</strong>('/', function(req, res) {
+ res.send('Hello World!');
+});
+</pre>
+
+<p>The callback function takes a request and a response object as arguments. In this case the method simply calls <code><a href="https://expressjs.com/en/4x/api.html#res.send">send()</a></code> on the response to return the string "Hello World!" There are a <a href="https://expressjs.com/en/guide/routing.html#response-methods">number of other response methods</a> for ending the request/response cycle, for example you could call <code><a href="https://expressjs.com/en/4x/api.html#res.json">res.json()</a></code> to send a JSON response or <code><a href="https://expressjs.com/en/4x/api.html#res.sendFile">res.sendFile()</a></code> to send a file.</p>
+
+<div class="note">
+<p><strong>JavaScript tip:</strong> You can use any argument names you like in the callback functions; when the callback is invoked the first argument will always be the request and the second will always be the response. It makes sense to name them such that you can identify the object you're working with in the body of the callback.</p>
+</div>
+
+<p>The <em>Express application</em> object also provides methods to define route handlers for all the other HTTP verbs, which are mostly used in exactly the same way: <code>post()</code>, <code>put()</code>, <code>delete()</code>, <code>options()</code>, <code>trace()</code>, <code>copy()</code>, <code>lock()</code>, <code>mkcol()</code>, <code>move()</code>, <code>purge()</code>, <code>propfind()</code>, <code>proppatch()</code>, <code>unlock()</code>, <code>report()</code>, <code>mkactivity()</code>, <code>checkout()</code>, <code>merge()</code>, <code>m-</code><code>search()</code>, <code>notify()</code>, <code>subscribe()</code>, <code>unsubscribe()</code>, <code>patch()</code>, <code>search()</code>, and <code>connect()</code>.</p>
+
+<p>There is a special routing method, <code>app.all()</code>, which will be called in response to any HTTP method. This is used for loading middleware functions at a particular path for all request methods. The following example (from the Express documentation) shows a handler that will be executed for requests to <code>/secret</code> irrespective of the HTTP verb used (provided it is supported by the <a href="https://nodejs.org/api/http.html#http_http_methods">http module</a>).</p>
+
+<pre class="brush: js notranslate">app.all('/secret', function(req, res, next) {
+ console.log('Accessing the secret section ...');
+ next(); // pass control to the next handler
+});</pre>
+
+<p>Routes allow you to match particular patterns of characters in a URL, and extract some values from the URL and pass them as parameters to the route handler (as attributes of the request object passed as a parameter).</p>
+
+<p>Often it is useful to group route handlers for a particular part of a site together and access them using a common route-prefix (e.g. a site with a Wiki might have all wiki-related routes in one file and have them accessed with a route prefix of <em>/wiki/</em>). In <em>Express</em> this is achieved by using the <code><a href="http://expressjs.com/en/guide/routing.html#express-router">express.Router</a></code> object. For example, we can create our wiki route in a module named <strong>wiki.js</strong>, and then export the <code>Router</code> object, as shown below:</p>
+
+<pre class="brush: js notranslate">// wiki.js - Wiki route module
+
+var express = require('express');
+var router = express.Router();
+
+// Home page route
+router.get('/', function(req, res) {
+ res.send('Wiki home page');
+});
+
+// About page route
+router.get('/about', function(req, res) {
+ res.send('About this wiki');
+});
+
+module.exports = router;
+</pre>
+
+<div class="note">
+<p><strong>Note:</strong> Adding routes to the <code>Router</code> object is just like adding routes to the <code>app</code> object (as shown previously).</p>
+</div>
+
+<p>To use the router in our main app file we would then <code>require()</code> the route module (<strong>wiki.js</strong>), then call <code>use()</code> on the <em>Express</em> application to add the Router to the middleware handling path. The two routes will then be accessible from <code style="font-style: normal; font-weight: normal;">/wiki/</code> and <code style="font-style: normal; font-weight: normal;">/wiki/about/</code>.</p>
+
+<pre class="brush: js notranslate">var wiki = require('./wiki.js');
+// ...
+app.use('/wiki', wiki);</pre>
+
+<p>We'll show you a lot more about working with routes, and in particular about using the <code>Router</code>, later on in the linked section<a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Express_Nodejs/routes"> Routes and controllers .</a></p>
+
+<h3 id="Using_middleware">Using middleware</h3>
+
+<p>Middleware is used extensively in Express apps, for tasks from serving static files to error handling, to compressing HTTP responses. Whereas route functions end the HTTP request-response cycle by returning some response to the HTTP client, middleware functions <em>typically</em> perform some operation on the request or response and then call the next function in the "stack", which might be more middleware or a route handler. The order in which middleware is called is up to the app developer.</p>
+
+<div class="note">
+<p><strong>Note:</strong> The middleware can perform any operation, execute any code, make changes to the request and response object, and it can<em> also end the request-response cycle</em>. If it does not end the cycle then it must call <code>next()</code> to pass control to the next middleware function (or the request will be left hanging).</p>
+</div>
+
+<p>Most apps will use <em>third-party</em> middleware in order to simplify common web development tasks like working with cookies, sessions, user authentication, accessing request <code>POST</code> and JSON data, logging, etc. You can find a <a href="http://expressjs.com/en/resources/middleware.html">list of middleware packages maintained by the Express team</a> (which also includes other popular 3rd party packages). Other Express packages are available on the NPM package manager.</p>
+
+<p>To use third party middleware you first need to install it into your app using NPM. For example, to install the <a href="http://expressjs.com/en/resources/middleware/morgan.html">morgan</a> HTTP request logger middleware, you'd do this:</p>
+
+<pre class="brush: bash notranslate"><code>$ npm install morgan
+</code></pre>
+
+<p>You could then call <code>use()</code> on the <em>Express application object</em> to add the middleware to the stack:</p>
+
+<pre class="brush: js notranslate">var express = require('express');
+<strong>var logger = require('morgan');</strong>
+var app = express();
+<strong>app.use(logger('dev'));</strong>
+...</pre>
+
+<div class="note">
+<p><strong>Note:</strong> Middleware and routing functions are called in the order that they are declared. For some middleware the order is important (for example if session middleware depends on cookie middleware, then the cookie handler must be added first). It is almost always the case that middleware is called before setting routes, or your route handlers will not have access to functionality added by your middleware.</p>
+</div>
+
+<p>You can write your own middleware functions, and you are likely to have to do so (if only to create error handling code). The <strong>only</strong> difference between a middleware function and a route handler callback is that middleware functions have a third argument <code>next</code>, which middleware functions are expected to call if they are not that which completes the request cycle (when the middleware function is called, this contains the <em>next</em> function that must be called).</p>
+
+<p>You can add a middleware function to the processing chain with either <code>app.use()</code> or <code>app.add()</code>, depending on whether you want to apply the middleware to all responses or to responses with a particular HTTP verb (<code>GET</code>, <code>POST</code>, etc). You specify routes the same in both cases, though the route is optional when calling <strong>app.use()</strong>.</p>
+
+<p>The example below shows how you can add the middleware function using both methods, and with/without a route.</p>
+
+<pre class="brush: js notranslate">var express = require('express');
+var app = express();
+
+// An example middleware function
+var a_middleware_function = function(req, res, <em>next</em>) {
+  // ... perform some operations
+  next(); // Call next() so Express will call the next middleware function in the chain.
+}
+
+// Function added with use() for all routes and verbs
+app.use(a_middleware_function);
+
+// Function added with use() for a specific route
+app.use('/someroute', a_middleware_function);
+
+// A middleware function added for a specific HTTP verb and route
+app.get('/', a_middleware_function);
+
+app.listen(3000);</pre>
+
+<div class="note">
+<p><strong>JavaScript Tip:</strong> Above we declare the middleware function separately and then set it as the callback. In our previous route handler function we declared the callback function when it was used. In JavaScript, either approach is valid.</p>
+</div>
+
+<p>The Express documentation has a lot more excellent documentation about <a href="https://expressjs.com/en/guide/using-middleware.html">using</a> and <a href="http://expressjs.com/en/guide/writing-middleware.html">writing</a> Express middleware.</p>
+
+<h3 id="Serving_static_files">Serving static files</h3>
+
+<p>You can use the <a href="http://expressjs.com/en/4x/api.html#express.static">express.static</a> middleware to serve static files, including your images, CSS and JavaScript (<code>static()</code> is the only middleware function that is actually <strong>part</strong> of <em>Express</em>). For example, you would use the line below to serve images, CSS files, and JavaScript files from a directory named '<strong>public'</strong> at the same level as where you call node:</p>
+
+<pre class="brush: js notranslate">app.use(express.static('public'));
+</pre>
+
+<p>Any files in the public directory are served by adding their filename (<em>relative</em> to the base "public" directory) to the base URL. So for example:</p>
+
+<pre class="notranslate"><code>http://localhost:3000/images/dog.jpg
+http://localhost:3000/css/style.css
+http://localhost:3000/js/app.js
+http://localhost:3000/about.html
+</code></pre>
+
+<p>You can call <code>static()</code> multiple times to serve multiple directories. If a file cannot be found by one middleware function then it will simply be passed on to the subsequent middleware (the order that middleware is called is based on your declaration order).</p>
+
+<pre class="brush: js notranslate">app.use(express.static('public'));
+app.use(express.static('media'));
+</pre>
+
+<p>You can also create a virtual prefix for your static URLs, rather than having the files added to the base URL. For example, here we <a href="http://expressjs.com/en/4x/api.html#app.use">specify a mount path</a> so that the files are loaded with the prefix "/media":</p>
+
+<pre class="brush: js notranslate">app.use('/media', express.static('public'));
+</pre>
+
+<p>Now, you can load the files that are in the <code>public</code> directory from the <code>/media</code> path prefix.</p>
+
+<pre class="notranslate"><code>http://localhost:3000/media/images/dog.jpg
+http://localhost:3000/media/video/cat.mp4
+http://localhost:3000/media/cry.mp3</code>
+</pre>
+
+<p>For more information, see <a href="Serving static files in Express">Serving static files in Express</a>.</p>
+
+<h3 id="Handling_errors">Handling errors</h3>
+
+<p>Errors are handled by one or more special middleware functions that have four arguments, instead of the usual three: <code>(err, req, res, next)</code>. For example:</p>
+
+<pre class="brush: js notranslate">app.use(function(err, req, res, next) {
+ console.error(err.stack);
+ res.status(500).send('Something broke!');
+});
+</pre>
+
+<p>These can return any content required, but must be called after all other <code>app.use()</code> and routes calls so that they are the last middleware in the request handling process!</p>
+
+<p>Express comes with a built-in error handler, which takes care of any remaining errors that might be encountered in the app. This default error-handling middleware function is added at the end of the middleware function stack. If you pass an error to <code>next()</code> and you do not handle it in an error handler, it will be handled by the built-in error handler; the error will be written to the client with the stack trace.</p>
+
+<div class="note">
+<p><strong>Note:</strong> The stack trace is not included in the production environment. To run it in production mode you need to set the the environment variable <code>NODE_ENV</code> to '<code>production'</code>.</p>
+</div>
+
+<div class="note">
+<p><strong>Note:</strong> HTTP404 and other "error" status codes are not treated as errors. If you want to handle these, you can add a middleware function to do so. For more information see the <a href="http://expressjs.com/en/starter/faq.html#how-do-i-handle-404-responses">FAQ</a>.</p>
+</div>
+
+<p>For more information see <a href="http://expressjs.com/en/guide/error-handling.html">Error handling</a> (Express docs).</p>
+
+<h3 id="Using_databases">Using databases</h3>
+
+<p><em>Express</em> apps can use any database mechanism supported by <em>Node</em> (<em>Express</em> itself doesn't define any specific additional behaviour/requirements for database management). There are many options, including PostgreSQL, MySQL, Redis, SQLite, MongoDB, etc.</p>
+
+<p>In order to use these you have to first install the database driver using NPM. For example, to install the driver for the popular NoSQL MongoDB you would use the command:</p>
+
+<pre class="brush: bash notranslate"><code>$ npm install mongodb
+</code></pre>
+
+<p>The database itself can be installed locally or on a cloud server. In your Express code you require the driver, connect to the database, and then perform create, read, update, and delete (CRUD) operations. The example below (from the Express documentation) shows how you can find "mammal" records using MongoDB.</p>
+
+<pre class="brush: js notranslate">//this works with older versions of mongodb version ~ 2.2.33
+var MongoClient = require('mongodb').MongoClient;
+
+MongoClient.connect('mongodb://localhost:27017/animals', function(err, db) {
+ if (err) throw err;
+
+ db.collection('mammals').find().toArray(function (err, result) {
+ if (err) throw err;
+
+ console.log(result);
+ });
+});
+
+
+//for mongodb version 3.0 and up
+let MongoClient = require('mongodb').MongoClient;
+MongoClient.connect('mongodb://localhost:27017/animals', function(err, client){
+ if(err) throw err;
+
+  let db = client.db('animals');
+  db.collection('mammals').find().toArray(function(err, result){
+ if(err) throw err;
+  console.log(result);
+  client.close();
+  });
+}
+</pre>
+
+<p>Another popular approach is to access your database indirectly, via an Object Relational Mapper ("ORM"). In this approach you define your data as "objects" or "models" and the ORM maps these through to the underlying database format. This approach has the benefit that as a developer you can continue to think in terms of JavaScript objects rather than database semantics, and that there is an obvious place to perform validation and checking of incoming data. We'll talk more about databases in a later article.</p>
+
+<p>For more information see <a href="https://expressjs.com/en/guide/database-integration.html">Database integration</a> (Express docs).</p>
+
+<h3 id="Rendering_data_views">Rendering data (views)</h3>
+
+<p>Template engines (referred to as "view engines" by <em>Express</em>) allow you to specify the <em>structure</em> of an output document in a template, using placeholders for data that will be filled in when a page is generated. Templates are often used to create HTML, but can also create other types of documents. Express has support for <a href="https://github.com/expressjs/express/wiki#template-engines">a number of template engines</a>, and there is a useful comparison of the more popular engines here: <a href="https://strongloop.com/strongblog/compare-javascript-templates-jade-mustache-dust/">Comparing JavaScript Templating Engines: Jade, Mustache, Dust and More</a>.</p>
+
+<p>In your application settings code you set the template engine to use and the location where Express should look for templates using the 'views' and 'view engines' settings, as shown below (you will also have to install the package containing your template library too!)</p>
+
+<pre class="brush: js notranslate">var express = require('express');
+var app = express();
+
+// Set directory to contain the templates ('views')
+app.set('views', path.join(__dirname, 'views'));
+
+// Set view engine to use, in this case 'some_template_engine_name'
+app.set('view engine', 'some_template_engine_name');
+</pre>
+
+<p>The appearance of the template will depend on what engine you use. Assuming that you have a template file named "index.&lt;template_extension&gt;" that contains placeholders for data variables named 'title' and "message", you would call <code><a href="http://expressjs.com/en/4x/api.html#res.render">Response.render()</a></code> in a route handler function to create and send the HTML response:</p>
+
+<pre class="brush: js notranslate">app.get('/', function(req, res) {
+ res.render('index', { title: 'About dogs', message: 'Dogs rock!' });
+});</pre>
+
+<p>For more information see <a href="http://expressjs.com/en/guide/using-template-engines.html">Using template engines with Express</a> (Express docs).</p>
+
+<h3 id="File_structure">File structure</h3>
+
+<p>Express makes no assumptions in terms of structure or what components you use. Routes, views, static files, and other application-specific logic can live in any number of files with any directory structure. While it is perfectly possible to have the whole <em>Express</em> application in one file, typically it makes sense to split your application into files based on function (e.g. account management, blogs, discussion boards) and architectural problem domain (e.g. model, view or controller if you happen to be using an <a href="/en-US/docs/Web/Apps/Fundamentals/Modern_web_app_architecture/MVC_architecture">MVC architecture</a>).</p>
+
+<p>In a later topic we'll use the <em>Express Application Generator</em>, which creates a modular app skeleton that we can easily extend for creating web applications.</p>
+
+<ul>
+</ul>
+
+<h2 id="Summary">Summary</h2>
+
+<p>Congratulations, you've completed the first step in your Express/Node journey! You should now understand Express and Node's main benefits, and roughly what the main parts of an Express app might look like (routes, middleware, error handling, and template code). You should also understand that with Express being an unopinionated framework, the way you pull these parts together and the libraries that you use are largely up to you!</p>
+
+<p>Of course Express is deliberately a very lightweight web application framework, so much of its benefit and potential comes from third party libraries and features. We'll look at those in more detail in the following articles. In our next article we're going to look at setting up a Node development environment, so that you can start seeing some Express code in action.</p>
+
+<h2 id="See_also">See also</h2>
+
+<ul>
+ <li><a href="https://medium.com/@ramsunvtech/manage-multiple-node-versions-e3245d5ede44">Venkat.R - Manage Multiple Node versions</a></li>
+ <li><a href="https://nodejs.org/api/modules.html#modules_modules">Modules</a> (Node API docs)</li>
+ <li><a href="https://expressjs.com/">Express</a> (home page)</li>
+ <li><a href="http://expressjs.com/en/starter/basic-routing.html">Basic routing</a> (Express docs)</li>
+ <li><a href="http://expressjs.com/en/guide/routing.html">Routing guide</a> (Express docs)</li>
+ <li><a href="http://expressjs.com/en/guide/using-template-engines.html">Using template engines with Express</a> (Express docs)</li>
+ <li><a href="https://expressjs.com/en/guide/using-middleware.html">Using middleware</a> (Express docs)</li>
+ <li><a href="http://expressjs.com/en/guide/writing-middleware.html">Writing middleware for use in Express apps</a> (Express docs)</li>
+ <li><a href="https://expressjs.com/en/guide/database-integration.html">Database integration</a> (Express docs)</li>
+ <li><a href="http://expressjs.com/en/starter/static-files.html">Serving static files in Express</a> (Express docs)</li>
+ <li><a href="http://expressjs.com/en/guide/error-handling.html">Error handling</a> (Express docs)</li>
+</ul>
+
+<div>{{NextMenu("Learn/Server-side/Express_Nodejs/development_environment", "Learn/Server-side/Express_Nodejs")}}</div>
+
+<h2 id="In_this_module">In this module</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Introduction">Express/Node introduction</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/development_environment">Setting up a Node (Express) development environment</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Tutorial_local_library_website">Express Tutorial: The Local Library website</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/skeleton_website">Express Tutorial Part 2: Creating a skeleton website</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/mongoose">Express Tutorial Part 3: Using a Database (with Mongoose)</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/routes">Express Tutorial Part 4: Routes and controllers</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Displaying_data">Express Tutorial Part 5: Displaying library data</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/forms">Express Tutorial Part 6: Working with forms</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/deployment">Express Tutorial Part 7: Deploying to production</a></li>
+</ul>
diff --git a/files/fr/learn/server-side/index.html b/files/fr/learn/server-side/index.html
new file mode 100644
index 0000000000..a93e27f476
--- /dev/null
+++ b/files/fr/learn/server-side/index.html
@@ -0,0 +1,58 @@
+---
+title: Programmation de Sites Web côté serveur
+slug: Learn/Server-side
+tags:
+ - Beginner
+ - CodingScripting
+ - Intro
+ - Landing
+ - Learn
+ - Server
+ - Server-side programming
+ - Topic
+ - TopicStub
+translation_of: Learn/Server-side
+---
+<div>{{LearnSidebar}}</div>
+
+<p class="summary">Le sujet abordant les sites <strong>web dynamiques / la programmation coté serveur</strong> est une série de modules vous montrant comment créer un site web dynamique (sites web intereagissant avec vous de manière à vous donner des informations personnelles en réponse aux requêtes HTTP). Les modules fournissent une introduction universelle à la programmation coté serveur à travers des guides spécifiques pour les debutants vous montrant comment vous servir des infrastructure d'application (aussi appelé frameworks) Django (fait en Python) et Express(fait en Node.js/JavaScript) afin de créer des applications basiques.</p>
+
+<p>La plupart des sites web utilisent une technologie (frameworks, serveurs, languages, etc.) côté serveur afin d'afficher dynamiquement les différentes informations requises. Par exemple, imaginez combien de produits sont disponibles sur Amazon, et imaginez combien de post ont été publiés sur Facebook depuis son commencement ? Afficher tout ceci en utilisant uniquement des pages 'statiques' aurait été absolument inutile et complétement infernal, au lieu de ça les sites dynamiques utilisent des templates (sorte de page statique servant de 'modèle', programmé en utilisant le <a href="https://developer.mozilla.org/en-US/docs/Learn/HTML">HTML</a>, le <a href="https://developer.mozilla.org/en-US/docs/Learn/CSS">CSS </a>et le <a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript">JavaScript</a> dans lequel on viendra y insérer les informations voulues ; par exemple, chaque page d'article amazon est la même, il s'agit juste d'un template dans lequel viennent se placer les informations du produit sélectionné).</p>
+
+<p>De nos jours, dans le monde du web, apprendre la programmation côté serveur est indispensable.</p>
+
+<h2 id="Lapprentissage">L'apprentissage</h2>
+
+<p>Se lancer dans la programmation côté serveur est souvent plus facile que de se lancer dans la programmation côté client, parce que les sites dynamiques ont tendance à faire toujours la même chose (recevoir des données d'une base de données, et l'afficher dans une page, valider les entrées de l'utilisateur et les sauvegarder dans la base de données, vérifier les permissions utilisateur ainsi que les connections etc.), et sont en général construits autour d'un framework web rendant les opérations assez faciles.</p>
+
+<p>Des connaissances minimales en concepts de programmation pourront être utiles, mais pas essentielles. Les connaissances en développement côté client sont également utiles mais pas indispensables, considérez néamoins que cela vous aiderai à mieux travailler avec des développeurs qui créeront la partie côté client du site aussi appelé "front-end".</p>
+
+<p>Vous allez avoir besoin de comprendre "comment le fonctionne le Web". Nous vous recommandons premièremement de lire les sujets suivants :</p>
+
+<ul>
+ <li><a href="https://developer.mozilla.org/fr/Apprendre/Qu_est-ce_qu_un_serveur_web">Qu'est-ce qu'un serveur web</a></li>
+ <li><a href="https://developer.mozilla.org/fr/Apprendre/Quels_logiciels_sont_n%C3%A9cessaires_pour_construire_un_site_web">De quel logiciels ai-je besoin afin de faire des sites web ?</a></li>
+ <li><a href="https://developer.mozilla.org/fr/Apprendre/Transf%C3%A9rer_des_fichiers_vers_un_serveur_web">Comment transférer des fichiers à un serveur web ?</a></li>
+</ul>
+
+<p>Ces articles vous donnerons les outils nécessaires afin de travailler avec les modules de cette section.</p>
+
+<h2 id="Modules">Modules</h2>
+
+<p>Ce sujet contient les modules suivants. Vous feriez mieux de commencer par le premier module, pour ensuite faire les autres qui vous montrerons comment travailler à l'aide des 2 languages de programmation côté serveur les plus populaire en utilisant les frameworks web appropriés.</p>
+
+<dl>
+ <dt><a href="https://developer.mozilla.org/fr/docs/Learn/Server-side/First_steps">Les premiers pas en programmation de site web côté serveur </a></dt>
+ <dd>Ce module fournit les informations de base sur la programmation de site web côté serveur en répondant à des questions telles que "Qu'est-ce que c'est ?", "En quoi est-ce différent de la prgrammation côté client ?" ou encore "Pourquoi est-ce si utile ?" ainsi qu'un aperçu de quelques frameworks côté serveur et comment choisir le vôtre en fonction de vos besoin ou des besoins de votre site web. Finalement nous allons vous présenter les principes de sécurité en serveur web.</dd>
+ <dt><a href="https://developer.mozilla.org/fr/docs/Learn/Server-side/Django">Le framework Web Django (Python)</a></dt>
+ <dd>Django est une infrastructure d'application (framework) côté serveur extrêmement populaire et dotée de son lot de fonctionnalités, écrite en Python. Ce module vous expliquera pourquoi Django fait un si bon framework pour serveurs, comment l'installer et s'en servir.</dd>
+ <dt><a href="https://developer.mozilla.org/fr/docs/Learn/Server-side/Express_Nodejs">Express Web Framework (Node.js/JavaScript)</a></dt>
+ <dd>Express est une infrastructure d'application (framework) assez populaire, écrite en JavaScript et fonctionnant à l'aide de Node.js. Ce module explique les avantages dont bénéficie ce framework, comment l'installer ainsi que comment s'en servir.</dd>
+</dl>
+
+<h2 id="Voir_aussi">Voir aussi</h2>
+
+<dl>
+ <dt><a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Node_server_without_framework">Serveur Node sans infrastucture d'application (framework) </a><sub>(anglais)</sub></dt>
+ <dd>Cet article comprend un serveur statique réalisé avec Node.js seul, pour ceux qui ne veulent pas utiliser de frameworks.</dd>
+</dl>
diff --git a/files/fr/learn/server-side/premiers_pas/client-serveur/index.html b/files/fr/learn/server-side/premiers_pas/client-serveur/index.html
new file mode 100644
index 0000000000..f20b96e64d
--- /dev/null
+++ b/files/fr/learn/server-side/premiers_pas/client-serveur/index.html
@@ -0,0 +1,316 @@
+---
+title: La relation Client-Serveur
+slug: Learn/Server-side/Premiers_pas/Client-Serveur
+translation_of: Learn/Server-side/First_steps/Client-Server_overview
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/Server-side/First_steps/Introduction", "Learn/Server-side/First_steps/Web_frameworks", "Learn/Server-side/First_steps")}}</div>
+
+<p class="summary">Maintenant que vous connaissez le but et le bénéfice de la programmation côté serveur, nous allons analyser en détails ce qui se passe quand un serveur reçoit une requête dynamique de la part d'un navigateur. Comme la plupart des sites gèrent le code côté serveur (requêtes et réponses) de la même manière, cela vous aidera à comprendre ce que vous devrez faire ensuite en écrivant votre propre code.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Prérequis :</th>
+ <td>Compréhension basique des notions informatiques et de ce qu'est un serveur web.</td>
+ </tr>
+ <tr>
+ <th scope="row">Objectif :</th>
+ <td>Comprendre les interactions client-serveur sur un site dynamique et particulièrement quelles opérations devront être effectuées par le code côté serveur.</td>
+ </tr>
+ </tbody>
+</table>
+
+<p>Il n'y a pas de code "réel" dans la suite de cette présentation parce que nous n'avons pas encore choisi un framework web à utiliser pour écrire notre code ! Ce tutoriel est quand même trés pertinent car les comportements décrits doivent être implémentés par votre code côté serveur, sans qu'il ait à se soucier (le serveur...)   de quel langage de programmation ou framework vous vous servez.</p>
+
+<h2 id="Serveurs_Web_et_HTTP_un_avant-goût">Serveurs Web et HTTP (un avant-goût)</h2>
+
+<p>Les navigateurs web communiquent avec les serveurs web avec le protocole <a href="/en-US/docs/Web/HTTP">HTTP</a><strong> : H</strong>yper<strong>T</strong>ext<strong>T</strong>ransfer <strong>P</strong>rotocol. Quand vous cliquez un lien sur une page, soumettez un formulaire ou lancez une recherche, le navigateur envoie une requête HTTP (<em>HTTP Request) </em>au serveur.</p>
+
+<p>Cette requête inclut :</p>
+
+<ul>
+ <li>Une URL identifiant la cible et la ressource (un fichier HTML, un point particulier de données sur le serveur ou un outil à lancer).</li>
+ <li>Une méthode qui définit l'action requise ( par exemple récupérer un fichier ou sauvegarder certaines données ou mises à jour). Les différentes méthodes/verbes et les actions associées sont listées ci-dessous :
+ <ul>
+ <li><code>GET</code>: Récupérer une ressource spécifique, par exemple un fichier html contenant des informations sur un produit ou une liste de produits.</li>
+ <li><code>POST</code>: Crée une ressource comme un nouvel article dans un wiki, ajouter un contact dans une base de données, enregistrer les données d'un formulaire d'inscription...</li>
+ <li>
+ <p><code>HEAD</code>: Récupérer les informations "metadata" d'une ressource spécifique sans le "body" comme ferait GET. Vous pouvez utiliser une requête HEAD pour, par exemple, la date de dernière mise à jour d'une ressource puis, utiliser GET (plus "coûteuse") seulement si la ressource a été changée.</p>
+ </li>
+ <li><code>PUT</code>: Met à jour une ressource existante ou en crée une si elle n'existe pas.</li>
+ <li><code>DELETE</code>: Supprime la ressource spécifiée.</li>
+ <li><code>TRACE</code>, <code>OPTIONS</code>, <code>CONNECT</code>, <code>PATCH</code>: ces verbes sont utilisés pour des tâches moins communes ou plus avancées nous ne les couvrirons donc pas ici.</li>
+ </ul>
+ </li>
+ <li>Des informations complémentaires peuvent être encodées avec la requête (des données de formulaire HTML par exemple). Ces informations peuvent être encodées comme :
+ <ul>
+ <li>Paramètres URL : les requêtes  <code>GET</code> encodent les données dans l'URL envoyée au serveur en ajoutant des paires nom/valeur en fin de celle-ci. Exemple : <code>http://mysite.com<strong>?name=Fred&amp;age=11</strong></code>.    Il y a toujours un point d'interrogation (<code>?</code>) séparant le début de l'URL des paramètres passés. Ainsi qu'un signe égal (<code>=</code>) séparant le nom de la valeur associée et une esperluette (<code>&amp;</code>) séparant chaque paire. Les paramètres URL ne sont pas sécurisés car ils peuvent être changés et soumis une deuxième fois par l'utilisateur. Pour cette raison, les requêtes URL paramètres/<code>GET</code> requests ne sont pas utilisées pour des requêtes mettant à jour des données sur un serveur.</li>
+ </ul>
+ </li>
+ <li><code>POST</code> data.  Les requêtes <code>POST</code> ajoutent de nouvelles ressources dont les données sont encodées dans le corps de la requête.</li>
+ <li>Cookies côté Client.  Contient les données de session du client, incluant les clés dont peut se servir le serveur pour déterminer le statut de login et les accés/permissions aux ressources.</li>
+</ul>
+
+<p>Les serveurs Web attendent une requête du client puis la traitent quand elle arrive. Il répond ensuite au navigateur avec un message HTTP Response. La réponse contient un statut <a href="/en-US/docs/Web/HTTP/Status">HTTP Response </a>indiquant si, oui ou non, la requête a abouti. (ex : "<code>200 OK</code>" pour un succés, "<code>404 Not Found</code>" si la ressource ne peut être trouvée, "<code>403 Forbidden</code>" si l'utilisateur n'est pas autorisé à voir la ressource etc. Le corps d'une réponse aboutie à une requête  <code>GET</code> contiendrait la ressource demandée.</p>
+
+<p>Quand une page HTML est retournée, elle est affichée par le navigateur. Le navigateur, nativement, pourra découvrir des liens vers d'autres ressources (ex : une page HTML intégre habituellement des pages JavaScript et CSS ), et enverra des requêtes séparées pour télécharger ces fichiers.</p>
+
+<p>Les sites web dynamiques ou statiques (voir sections suivantes) utilisent les mêmes protocoles/modèles de communication.</p>
+
+<h3 id="Exemple_de_requêteréponse_GET">Exemple de requête/réponse GET </h3>
+
+<p>Vous faites une simple requête <code>GET</code> en cliquant sur un lien ou en faisant une recherche sur un site (sur une page de moteur de recherche par exemple). Une requête HTTP envoyée lorsque vous effectuez une recherche sur MDN pour les termes : "La relation Client-Serveur" ressemblera beaucoup à ce qui suit mais ne sera pas identique car des parties du message dépendent des paramètres de votre navigateur.</p>
+
+<div class="note">
+<p>Le format des messsages HTTP est défini par un standard web  (<a href="http://www.rfc-editor.org/rfc/rfc7230.txt">RFC7230</a>). Vous n'avez pas besoin de connaître ce niveau de détails mais vous saurez au moins d'où vient tout ça !</p>
+</div>
+
+<h4 id="La_requête">La requête</h4>
+
+<p>Chaque ligne de la requête contient des informations sur celle-ci. La première partie est appelée l'en-tête ( <strong>header</strong>) et contient beaucoup de données utiles. De la même manière qu'un <a href="/en-US/docs/Learn/HTML/Introduction_to_HTML/The_head_metadata_in_HTML">HTML head</a> contient des informations utiles (pas le contenu réel qui lui, se trouve dans le corps (body) :</p>
+
+<pre>GET https://developer.mozilla.org/en-US/search?q=la+relation+Client+-+serveur&amp;topic=apps&amp;topic=html&amp;topic=css&amp;topic=js&amp;topic=api&amp;topic=webdev HTTP/1.1
+Host: developer.mozilla.org
+Connection: keep-alive
+Pragma: no-cache
+Cache-Control: no-cache
+Upgrade-Insecure-Requests: 1
+User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36
+Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
+Referer: https://developer.mozilla.org/en-US/
+Accept-Encoding: gzip, deflate, sdch, br
+<code>Accept-Charset: ISO-8859-1,UTF-8;q=0.7,*;q=0.7</code>
+Accept-Language: en-US,en;q=0.8,es;q=0.6
+Cookie: sessionid=6ynxs23n521lu21b1t136rhbv7ezngie; csrftoken=zIPUJsAZv6pcgCBJSCj1zU6pQZbfMUAT; dwf_section_edit=False; dwf_sg_task_completion=False; _gat=1; _ga=GA1.2.1688886003.1471911953; ffo=true
+</pre>
+
+<p>Les premières et secondes lignes contiennent la plupart des données déjà évoquées précédemment :</p>
+
+<ul>
+ <li>Le type de la requête (<code>GET</code>).</li>
+ <li>La cible de la  ressource URL (<code>/en-US/search</code>).</li>
+ <li>Les paramètres URL (<code>q=La%2relation%2Client%2-%2Bserveur&amp;topic=apps&amp;topic=html&amp;topic=css&amp;topic=js&amp;topic=api&amp;topic=webdev</code>).</li>
+ <li>Le site web cible/hôte (developer.mozilla.org).</li>
+ <li>La fin de la première ligne inclut aussi une petite chaîne identifiant la version spécifique du protocole (<code>HTTP/1.1</code>).</li>
+</ul>
+
+<p>La dernière ligne contient des données sur les cookies côté client — vous observerez que dans ce cas, le cookie a une id pour gérer la session :    (<code>Cookie: sessionid=6ynxs23n521lu21b1t136rhbv7ezngie; ...</code>).</p>
+
+<p>Les lignes restantes concernent le navigateur utilisé et les sortes de réponses qu'il peut accepter. Par exemple, vous pouvez voir ceci :</p>
+
+<ul>
+ <li>Mon navigateur (<code>User-Agent</code>) est Mozilla Firefox (<code>Mozilla/5.0</code>).</li>
+ <li>Il accepte les données compressées (<code>Accept-Encoding: gzip</code>).</li>
+ <li>Il accepte les familles de caractères suivantes :  (<code>Accept-Charset: ISO-8859-1,UTF-8;q=0.7,*;q=0.7</code>) et pour les langages : (<code>Accept-Language: de,en;q=0.7,en-us;q=0.3</code>).</li>
+ <li>La ligne <code>Referer</code> indique l'adresse de la page web qui contenait le lien vers cette ressource (Par ex. l'origine de la requête : <code>https://developer.mozilla.org/en-US/</code>).</li>
+</ul>
+
+<p>Les requêtes HTTP peuvent aussi avoir un corps mais dans ce cas précis, il est vide.</p>
+
+<h4 id="La_réponse">La réponse</h4>
+
+<p>La première partie de la réponse à cette requête est détaillée ci-dessous. L'en-tête contient les données suivantes :</p>
+
+<ul>
+ <li>La première ligne embarque le code <code>200 OK</code>, qui nous dit que la requête a abouti.</li>
+ <li>Nous pouvons voir que la réponse est formatée en  <code>text/html</code> (<code>Content-Type</code>).</li>
+ <li>On remarque qu'elle utilise l'ensemble des caractères UTF-8 (<code>Content-Type: text/html; charset=utf-8</code>).</li>
+ <li>L'en-tête indique aussi la taille (<code>Content-Length: 41823</code>).</li>
+</ul>
+
+<p>À la fin du message nous avons le contenu du corps  — lequel contient le "vrai" HTML demandé par la requête.</p>
+
+<pre class="brush: html">HTTP/1.1 200 OK
+Server: Apache
+X-Backend-Server: developer1.webapp.scl3.mozilla.com
+Vary: Accept,Cookie, Accept-Encoding
+Content-Type: text/html; charset=utf-8
+Date: Wed, 07 Sep 2016 00:11:31 GMT
+Keep-Alive: timeout=5, max=999
+Connection: Keep-Alive
+X-Frame-Options: DENY
+Allow: GET
+X-Cache-Info: caching
+Content-Length: 41823
+
+
+
+&lt;!DOCTYPE html&gt;
+&lt;html lang="en-US" dir="ltr" class="redesign no-js"  data-ffo-opensanslight=false data-ffo-opensans=false &gt;
+&lt;head prefix="og: http://ogp.me/ns#"&gt;
+  &lt;meta charset="utf-8"&gt;
+  &lt;meta http-equiv="X-UA-Compatible" content="IE=Edge"&gt;
+  &lt;script&gt;(function(d) { d.className = d.className.replace(/\bno-js/, ''); })(document.documentElement);&lt;/script&gt;
+  ...
+</pre>
+
+<p>Le reste de l'en-tête de la réponse contient des informations sur la réponse elle-même (quand elle a été générée), sur le serveur et comment le navigateur doit gérer la page ( <code>X-Frame-Options: DENY</code> cette ligne dit au navigateur de ne pas autoriser cette page a être intégrée dans une  {{htmlelement("iframe")}} dans un autre site).</p>
+
+<h3 id="Exemple_de_requêteréponse_POST">Exemple de requête/réponse POST</h3>
+
+<p>Un <code>POST</code> HTTP est effectué lorsque vous soumettez un formulaire contenant des données à sauvegarder sur le serveur.</p>
+
+<h4 id="La_requête_2">La requête</h4>
+
+<p>Le texte ci-dessous montre une requête HTTP faite quand un utlisateur soumet un nouveaux profil sur ce site. Le format de la requête est presque le même que celui de la requête <code>GET</code> vue précédemment, bien que la première ligne identifie cette requête comme un <code>POST</code>. </p>
+
+<pre class="brush: html">POST https://developer.mozilla.org/en-US/profiles/hamishwillee/edit HTTP/1.1
+Host: developer.mozilla.org
+Connection: keep-alive
+Content-Length: 432
+Pragma: no-cache
+Cache-Control: no-cache
+Origin: https://developer.mozilla.org
+Upgrade-Insecure-Requests: 1
+User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36
+Content-Type: application/x-www-form-urlencoded
+Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
+Referer: https://developer.mozilla.org/en-US/profiles/hamishwillee/edit
+Accept-Encoding: gzip, deflate, br
+Accept-Language: en-US,en;q=0.8,es;q=0.6
+Cookie: sessionid=6ynxs23n521lu21b1t136rhbv7ezngie; _gat=1; csrftoken=zIPUJsAZv6pcgCBJSCj1zU6pQZbfMUAT; dwf_section_edit=False; dwf_sg_task_completion=False; _ga=GA1.2.1688886003.1471911953; ffo=true
+
+csrfmiddlewaretoken=zIPUJsAZv6pcgCBJSCj1zU6pQZbfMUAT&amp;user-username=hamishwillee&amp;user-fullname=Hamish+Willee&amp;user-title=&amp;user-organization=&amp;user-location=Australia&amp;user-locale=en-US&amp;user-timezone=Australia%2FMelbourne&amp;user-irc_nickname=&amp;user-interests=&amp;user-expertise=&amp;user-twitter_url=&amp;user-stackoverflow_url=&amp;user-linkedin_url=&amp;user-mozillians_url=&amp;user-facebook_url=</pre>
+
+<p>La principale différence est que l'URL ne comporte pas de paramètres.  Comme vous voyez, l'information du formulaire est encodée dans le corps de la requête (par exemple : le nom complet du nouvel utilisateur est paramétré avec  <code>&amp;user-fullname=Hamish+Willee</code>).</p>
+
+<h4 id="La_réponse_2">La réponse</h4>
+
+<p>La réponse à la requête est expliquée dessous. Le statut "<code>302 Found</code>" dit au navigateur que le post a abouti et qu'il peut délivrer une deuxième requête HTTP pour charger la page spécifiée dans le champ  <code>Location</code>. L'information est donc en cela similaire à une réponse de requête <code>GET</code>.</p>
+
+<pre class="brush: html">HTTP/1.1 302 FOUND
+Server: Apache
+X-Backend-Server: developer3.webapp.scl3.mozilla.com
+Vary: Cookie
+Vary: Accept-Encoding
+Content-Type: text/html; charset=utf-8
+Date: Wed, 07 Sep 2016 00:38:13 GMT
+Location: https://developer.mozilla.org/en-US/profiles/hamishwillee
+Keep-Alive: timeout=5, max=1000
+Connection: Keep-Alive
+X-Frame-Options: DENY
+X-Cache-Info: not cacheable; request wasn't a GET or HEAD
+Content-Length: 0
+</pre>
+
+<div class="note">
+<p><strong>Note </strong>: Les requêtes et réponses montrées dans ces exemples ont été capturées avec l'application <a href="https://www.telerik.com/download/fiddler">Fiddler</a> , mais vous pouvez avoir des informations similaires en utilisant des "renifleurs" web  (e.g. <a href="http://websniffer.cc/">Websniffer</a>, <a href="https://www.wireshark.org/">Wireshark</a>) ou des extensions de navigateur comme  <a href="https://addons.mozilla.org/en-US/firefox/addon/httpfox/">HttpFox</a>. Vous pouvez essayer seul. Utilisez tous les outils recommandés, naviguez sur des sites et  éditez des profils de données pour explorer les différentes requêtes et réponses. La plupart des navigateurs modernes ont aussi des outils qui gérent les requêtes réseau, par exemple le <a href="/en-US/docs/Tools/Network_Monitor">Network Monitor</a> dans Firefox).</p>
+</div>
+
+<h2 id="Les_sites_statiques">Les sites statiques</h2>
+
+<p>Un site statique renvoie le même contenu codé en dur depuis le serveur quelle que soit la ressource demandée. Si vous avez une page concernant un produit à l'adresse  <code>/static/myproduct1.html</code>, cette même page sera retournée à chaque utilisateur. Si vous ajoutez un nouveau produit, vous devez ajouter une nouvelle page (par ex : <code>myproduct2.html</code>) et ainsi de suite. Cela peut être vraiment inefficace — Comment faire quand vous avez des milliers de pages "produit" à faire ? Vous allez répéter beaucoup de code identique dans chaque page (le modèle de base de la page, sa structure, etc.) et si vous voulez changer quoique ce soit dans la structure de la page — comme une section "produits dérivés" par exemple — alors, il faudra changer chaque page individuellement..</p>
+
+<div class="note">
+<p><strong>Note </strong>: Les sites statiques sont trés efficace quand vous avez un petit nombre de pages et que vous voulez envoyer le même contenu à chaque utilisateur. De toutes façons, ils peuvent avoir un coût certain de maintenance au fur et à mesure de l'augmentation du nombre de pages.</p>
+</div>
+
+<p>Voyons comment tout cela marche en révisant un diagramme d'architecture de site statique vu dans l'article précédent.</p>
+
+<p><img alt="A simplified diagram of a static web server." src="https://mdn.mozillademos.org/files/13841/Basic%20Static%20App%20Server.png"></p>
+
+<p>Quand un utilisateur veut naviguer jusqu'à une page, le navigateur envoie une requête HTTP <code>GET</code> spécifiant l'URL de sa page HTML. Le serveur retourne le document demandé depuis son système de fichiers et retourne une réponse  HTTP contenant le document et un  <a href="/en-US/docs/Web/HTTP/Status">HTTP Response status code</a> ( statut codé de la réponse HTTP) qui est  "<code>200 OK</code>" (indiquant le succés de l'opération). Le serveur peut retourner un statut différent, par exemple "<code>404 Not Found</code>"  si le fichier est absent sur le serveur , ou bien "<code>301 Moved Permanently</code>" si le fichier existe mais a été déplacé vers une nouvelle localisation.</p>
+
+<p>Le serveur d'un site statique n'aura à faire face qu'à des requêtes  GET vu qu'il ne stocke aucune donnée modifiable. Il ne change pas non plus ses réponses basées sur les données des requêtes HTTP (c'est à dire les paramètres URL ou les cookies). </p>
+
+<p>Comprendre comment fonctionnent les sites statiques est sans aucun doute trés utile à l'apprentissage de la programmation côté serveur car les sites dynamiques gèrent les requêtes pour les fichiers statiques (CSS, JavaScript, images statiques , etc.) exactement de la même manière.</p>
+
+<h2 id="Les_sites_dynamiques">Les sites dynamiques</h2>
+
+<p>Un site dynamique peut générer et retourner du contenu basé sur une requête URL spécifique et les données (plutôt que de toujours renvoyer le même fichier codé en dur à une URL particulière).  Toujours avec l'exemple d'un site "produits", le serveur stockera les données du produit dans une base de données plutôt que dans un fichier HTML individuel. Quand il reçoit une requête HTTP <code>GET</code> pour un produit, le serveur détermine l'ID du produit, va chercher les données dans la base de données puis construit la page HTML pour la réponse en intégrant les données dans un gabarit (template) HTML. C'est un avantage indéniable sur un site statique :</p>
+
+<p>Utiliser une base de données permet à l'information "produit" d'être stockée efficacement, en étant modifiable, extensible et bien indexée.</p>
+
+<p>Employer des gabarits HTML facilite la façon de changer la structure HTML parce que c'est fait en un seul endroit, dans un seul gabarit (template) et non pas sur potentiellement des milliers de pages statiques.</p>
+
+<h3 id="Anatomie_dun_requête_dynamique">Anatomie d'un requête dynamique</h3>
+
+<p>Cette section présente une vue d'ensemble du cycle dynamique HTTP de requête/réponse, construit avec ce que nous avons vu précédemment avec de plus amples détails. Toujours dans l'optique de "faire les choses en réel" nous utiliserons le contexte du site d'une équipe de sport où l'entraîneur peut sélectionner le nom de l'équipe et le nombre de joueurs dans un formulaire HTML et avoir en retour une suggestion "Meilleure composition" pour le prochain match.</p>
+
+<p><span style='color: rgba(0, 0, 0, 0.87); font-family: "Roboto",arial,sans-serif; font-size: 18px; font-style: normal; font-variant: normal; font-weight: 400; letter-spacing: normal; text-align: left; text-decoration: none; text-indent: 0px; text-transform: none; white-space: pre-wrap;' title="">Le diagramme ci-dessous montre les principaux éléments du site Web "entraîneur d'équipe", ainsi que des étiquettes numérotées pour la séquence des opérations lorsque l'entraîneur accède à la liste "meilleure équipe".</span><span style='background-color: #f5f5f5; color: rgba(0, 0, 0, 0.87); display: inline !important; float: none; font-family: "Roboto",arial,sans-serif; font-size: 18px; font-style: normal; font-variant: normal; font-weight: 400; letter-spacing: normal; line-height: 28px; text-align: left; text-decoration: none; text-indent: 0px; text-transform: none; white-space: pre-wrap;'> </span><span style='color: rgba(0, 0, 0, 0.87); font-family: "Roboto",arial,sans-serif; font-size: 18px; font-style: normal; font-variant: normal; font-weight: 400; letter-spacing: normal; text-align: left; text-decoration: none; text-indent: 0px; text-transform: none; white-space: pre-wrap;' title="">Les parties du site qui le rendent dynamique sont l’application Web (c’est ainsi que nous nous référerons au code côté serveur qui traite les requêtes HTTP et renvoie les réponses HTTP), la base de données, qui contient des informations sur les joueurs, les équipes, les entraîneurs et leurs partenaires.</span><span style='background-color: #f5f5f5; color: rgba(0, 0, 0, 0.87); display: inline !important; float: none; font-family: "Roboto",arial,sans-serif; font-size: 18px; font-style: normal; font-variant: normal; font-weight: 400; letter-spacing: normal; line-height: 28px; text-align: left; text-decoration: none; text-indent: 0px; text-transform: none; white-space: pre-wrap;'> </span><span style='color: rgba(0, 0, 0, 0.87); font-family: "Roboto",arial,sans-serif; font-size: 18px; font-style: normal; font-variant: normal; font-weight: 400; letter-spacing: normal; text-align: left; text-decoration: none; text-indent: 0px; text-transform: none; white-space: pre-wrap;' title="">relations, et les modèles HTML.</span></p>
+
+<p><img alt="This is a diagram of a simple web server with step numbers for each of step of the client-server interaction." src="https://mdn.mozillademos.org/files/13829/Web%20Application%20with%20HTML%20and%20Steps.png" style="height: 584px; width: 1226px;"></p>
+
+<p><font color="#001000" face="Arial,x-locale-body,sans-serif">Une fois que l’entraîneur a soumis le formulaire avec le nom de l’équipe et le nombre de joueurs, la séquence des opérations est la suivante:</font></p>
+
+<ol>
+ <li>Le navigateur Web crée une requête HTTP GET au serveur en utilisant l’URL de base de la ressource (/ best) et en codant l’équipe et le numéro du joueur sous forme de paramètres d’URL (par exemple / best? team=my_team_name&amp;show = 11) ou dans le cadre de l’URL modèle (par exemple / best / my_team_name / 11 /). Une requête GET est utilisée car la requête extrait uniquement des données (sans les modifier).</li>
+ <li>Le serveur Web détecte que la demande est "dynamique" et la transmet à l'application Web pour traitement (le serveur Web détermine comment gérer différentes URL en fonction des règles de correspondance de modèle définies dans sa configuration).</li>
+ <li>L'application Web identifie l'objectif de la demande d'obtenir la "meilleure liste d'équipes" en fonction de l'URL (/ best /) et recherche le nom d'équipe requis et le nombre de joueurs à partir de l'URL. L'application Web obtient alors les informations requises de la base de données (en utilisant des paramètres "internes" supplémentaires pour définir quels joueurs sont les "meilleurs", et éventuellement en obtenant également l'identité de l'entraîneur connecté à partir d'un cookie côté client).</li>
+ <li>L'application Web crée dynamiquement une page HTML en plaçant les données (de la base de données) dans des espaces réservés dans un modèle HTML.</li>
+ <li>L'application Web renvoie le code HTML généré au navigateur Web (via le serveur Web), ainsi qu'un code d'état HTTP de 200 ("success"). Si quoi que ce soit empêche le code HTML d'être renvoyé, l'application Web renvoie un autre code, par exemple "404" pour indiquer que l'équipe n'existe pas.</li>
+ <li><span style='background-color: #f5f5f5; color: rgba(0, 0, 0, 0.87); display: inline !important; float: none; font-family: "Roboto",arial,sans-serif; font-size: 18px; font-style: normal; font-variant: normal; font-weight: 400; letter-spacing: normal; text-align: left; text-decoration: none; text-indent: 0px; text-transform: none; white-space: pre-wrap;'>Le navigateur Web commence alors à traiter le code HTML renvoyé, en envoyant des demandes distinctes pour obtenir tous les fichiers CSS ou JavaScript qu’il référence (voir étape 7).</span></li>
+ <li><span style='background-color: #f5f5f5; color: rgba(0, 0, 0, 0.87); display: inline !important; float: none; font-family: "Roboto",arial,sans-serif; font-size: 18px; font-style: normal; font-variant: normal; font-weight: 400; letter-spacing: normal; text-align: left; text-decoration: none; text-indent: 0px; text-transform: none; white-space: pre-wrap;'>Le serveur Web charge les fichiers statiques à partir du système de fichiers et les renvoie directement au navigateur (là encore, le traitement correct des fichiers est basé sur les règles de configuration et la correspondance des types d'URL).</span></li>
+</ol>
+
+<p><span style='background-color: #f5f5f5; color: rgba(0, 0, 0, 0.87); display: inline !important; float: none; font-family: "Roboto",arial,sans-serif; font-size: 18px; font-style: normal; font-variant: normal; font-weight: 400; letter-spacing: normal; text-align: left; text-decoration: none; text-indent: 0px; text-transform: none; white-space: pre-wrap;'>Une opération de mise à jour d'un enregistrement dans la base de données serait gérée de la même manière, sauf que, comme toute mise à jour de base de données, la demande HTTP du navigateur devrait être codée en tant que demande POST.</span></p>
+
+<h3 id="que_faire_dautre">que faire d'autre?</h3>
+
+<p>Le travail d'une application Web consiste à recevoir des requêtes HTTP et à renvoyer des réponses HTTP. Bien que l'interaction avec une base de données pour obtenir ou mettre à jour des informations soit une tâche très courante, le code peut faire d'autres choses en même temps, ou ne pas interagir du tout avec une base de données.Un bon exemple de tâche supplémentaire qu'une application Web pourrait exécuter serait l'envoi d'un courrier électronique aux utilisateurs pour confirmer leur inscription sur le site. Le site peut également effectuer une journalisation ou d’autres opérations.</p>
+
+<h3 id="Renvoyer_autre_chose_que_du_HTML">Renvoyer autre chose que  du HTML</h3>
+
+<p>Le code de site Web côté serveur ne doit pas nécessairement renvoyer des extraits / fichiers HTML dans la réponse. Au lieu de cela, il peut créer et renvoyer de manière dynamique d'autres types de fichiers (texte, PDF, CSV, etc.) ou même des données (JSON, XML, etc.).L'idée de renvoyer des données à un navigateur Web afin qu'il puisse mettre à jour de manière dynamique son propre contenu ({{glossary ("AJAX")}}) existe depuis un certain temps. Plus récemment, les "applications à page unique" sont devenues populaires, le site Web entier étant écrit avec un seul fichier HTML mis à jour de manière dynamique en cas de besoin. Les sites Web créés à l'aide de ce style d'application génèrent des coûts de calcul considérables entre le serveur et le navigateur Web, ce qui peut donner l'impression que les sites Web se comportent beaucoup plus comme des applications natives (très réactives, etc.).</p>
+
+<h2 id="Les_frameworks_Web_simplifient_la_programmation_Web_côté_serveur">Les frameworks Web simplifient la programmation Web côté serveur</h2>
+
+<p>Les infrastructures Web côté serveur facilitent beaucoup la rédaction de code permettant de gérer les opérations décrites ci-dessus.L’une des opérations les plus importantes qu’ils effectuent consiste à fournir des mécanismes simples pour mapper les URL de différentes ressources / pages à des fonctions de gestionnaire spécifiques. Cela facilite la séparation du code associé à chaque type de ressource. Cela présente également des avantages en termes de maintenance, car vous pouvez modifier l'URL utilisée pour fournir une fonctionnalité particulière à un endroit, sans avoir à changer la fonction de gestionnaire.Par exemple, considérons le code Django (Python) suivant qui mappe deux modèles d'URL à deux fonctions d'affichage. Le premier modèle garantit qu'une requête HTTP avec une URL de ressource / best sera transmise à une fonction nommée index () dans le module views. Une demande qui a pour motif "/ best / junior" sera plutôt transmise à la fonction d'affichage junior ().</p>
+
+<pre class="brush: python"># file: best/urls.py
+#
+
+from django.conf.urls import url
+
+from . import views
+
+urlpatterns = [
+ # example: /best/
+ url(r'^$', views.index),
+ # example: /best/junior/
+ url(r'^junior/$', views.junior),
+]</pre>
+
+<div class="note">
+<p><strong>Note</strong>: Les premiers paramètres des fonctions url () peuvent paraître un peu bizarres (par exemple, r '^ junior / $') car ils utilisent une technique de correspondance de modèle appelée "expressions régulières" (RegEx ou RE). Vous n'avez pas besoin de savoir comment fonctionnent les expressions régulières à ce stade, car elles nous permettent également de faire correspondre les modèles de l'URL (plutôt que les valeurs codées en dur ci-dessus) et de les utiliser comme paramètres dans nos fonctions d'affichage. À titre d'exemple, un RegEx très simple pourrait dire "faire correspondre une seule lettre majuscule, suivie de 4 à 7 lettres minuscules".</p>
+</div>
+
+<div>L'infrastructure Web permet également à une fonction d'affichage d'extraire facilement des informations de la base de données. La structure de nos données est définie dans des modèles, qui sont des classes Python qui définissent les champs à stocker dans la base de données sous-jacente. Si nous avons un modèle nommé Team avec un champ "team_type", nous pouvons utiliser une syntaxe de requête simple pour récupérer toutes les équipes ayant un type particulier.</div>
+
+<div>L’exemple ci-dessous donne la liste de toutes les équipes ayant le type d’équipe exact (sensible à la casse) de "junior" - notez le format: nom du champ (team_type) suivi du  double underscore, puis du type de match à utiliser (ici nous utilisons: exact). ). Il existe de nombreux autres types de match et nous pouvons les enchaîner. Nous pouvons également contrôler l'ordre et le nombre de résultats retournés.</div>
+
+<div></div>
+
+<pre class="brush: python">#best/views.py
+
+from django.shortcuts import render
+
+from .models import Team
+
+
+def junior(request):
+    list_teams = Team.objects.filter(team_type__exact="junior")
+    context = {'list': list_teams}
+    return render(request, 'best/index.html', context)
+</pre>
+
+<p>Une fois que la fonction junior () a obtenu la liste des équipes juniors, elle appelle la fonction render () en transmettant la requête HttpRequest d'origine, un modèle HTML et un objet "context" définissant les informations à inclure dans le modèle. La fonction render () est une fonction pratique qui génère du HTML à l'aide d'un context et d'un template HTML, puis le renvoie dans un objet HttpResponse.De toute évidence, les frameworks Web peuvent vous aider dans de nombreuses autres tâches. Nous discutons beaucoup plus d'avantages et de choix de frameworks Web populaires dans le prochain article.</p>
+
+<h2 id="Summary">Summary</h2>
+
+<p>À ce stade, vous devez avoir une bonne vue d'ensemble des opérations que le code côté serveur doit effectuer et connaître certaines des manières dont une infrastructure Web côté serveur peut faciliter cela.</p>
+
+<p>Dans un module suivant, nous vous aiderons à choisir le meilleur framework Web pour votre premier site.</p>
+
+<p><span style="background-color: #ffffff; color: #333333; display: inline !important; float: none; font-family: Arial,x-locale-body,sans-serif; font-size: 16px; font-style: normal; font-variant: normal; font-weight: 400; letter-spacing: normal; text-align: left; text-decoration: none; text-indent: 0px; text-transform: none; white-space: normal;">{{PreviousMenuNext("Learn/Server-side/First_steps/Introduction", "Learn/Server-side/First_steps/Web_frameworks", "Learn/Server-side/First_steps")}}</span></p>
+
+<h2 id="In_this_module">In this module</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/Server-side/First_steps/Introduction">Introduction to the server side</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/First_steps/Client-Server_overview">Client-Server overview</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/First_steps/Web_frameworks">Server-side web frameworks</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/First_steps/Website_security">Website security</a></li>
+</ul>
diff --git a/files/fr/learn/server-side/premiers_pas/index.html b/files/fr/learn/server-side/premiers_pas/index.html
new file mode 100644
index 0000000000..a8caf88e4d
--- /dev/null
+++ b/files/fr/learn/server-side/premiers_pas/index.html
@@ -0,0 +1,45 @@
+---
+title: Premiers pas dans la programmation d'un site côté serveur
+slug: Learn/Server-side/Premiers_pas
+tags:
+ - Débutant
+ - Encodage
+ - Guide
+ - Intro
+ - Programmation côté serveur
+translation_of: Learn/Server-side/First_steps
+---
+<div>{{LearnSidebar}}</div>
+
+<p>Dans ce module nous répondrons à quelques questions fondamentales sur la programmation côté serveur — "Qu'est-ce que c'est ?", "En quoi diffère-t-elle de la programmation côté client ?" et "Pourquoi est-ce si utile ?". Nous fournirons ensuite un aperçu de certaines infrastructures d'applications web (aussi appelé frameworks) côté serveurs parmi les plus populaires, ainsi que des conseils pour sélectionner la plus approprié pour créer votre premier site. Enfin un article vous présentera les questions de sécurité pour un serveur web.   </p>
+
+<h2 id="Prérequis">Prérequis</h2>
+
+<p>Pour suivre ce module, aucune connaissance en programmation web côté serveur ou tout autre type de programmation n'est nécessaire.</p>
+
+<p>Vous aurez besoin de comprendre "comment fonctionne le web". Nous vous recommandons de lire d'abord les sujets suivants :</p>
+
+<ul>
+ <li><a href="https://developer.mozilla.org/fr/Apprendre/Qu_est-ce_qu_un_serveur_web">Qu'est-ce qu'un serveur web</a></li>
+ <li><a href="https://developer.mozilla.org/fr/Apprendre/Quels_logiciels_sont_n%C3%A9cessaires_pour_construire_un_site_web">De quel logiciel ai-je besoin pour créer un site web ?</a></li>
+ <li><a href="https://developer.mozilla.org/fr/Apprendre/Transf%C3%A9rer_des_fichiers_vers_un_serveur_web">Comment transférer des fichiers sur un serveur web ?</a></li>
+</ul>
+
+<p>Avec cette compréhension de base, vous serez prêts à parcourir les modules de cette section.</p>
+
+<h2 id="Guides">Guides</h2>
+
+<dl>
+ <dt><a href="https://developer.mozilla.org/fr/docs/Learn/Server-side/Premiers_pas/Introduction">Introduction au côté serveur</a></dt>
+ <dd>Bienvenue au cours de programmation débutant de MDN ! Dans ce premier article, nous examinerons la programmation côté serveur, répondant à des questions comme «En quoi consiste-t-elle ?», «En quoi diffère-t-elle de la programmation côté client ?» et «Pourquoi est-ce si utile ?». Après avoir lu cet article, vous comprendrez comment la programmation côté serveur donne aux sites web toute leur puissance.</dd>
+ <dt><a href="/fr/docs/Learn/Server-side/Premiers_pas/Client-Serveur">Présentation client-serveur</a></dt>
+ <dd>Maintenant que vous connaissez le but et les avantages potentiels de la programmation côté serveur, nous allons examiner en détail ce qui se passe lorsqu'un serveur reçoit une "requête dynamique" d'un navigateur. Comme la plupart des codes côté serveur traitent les demandes et les réponses de la même manière, cela vous aidera à comprendre ce que vous devez faire lorsque vous écrivez votre propre code.</dd>
+ <dt><a href="/fr/docs/Learn/Server-side/Premiers_pas/Web_frameworks">Frameworks web côté serveur</a></dt>
+ <dd>Le dernier article vous a montré ce qu'une application web côté serveur doit faire pour répondre aux demandes d'un navigateur web. Nous allons maintenant vous montrer comment les frameworks web peuvent simplifier ces tâches ; nous vous aiderons à choisir le bon framework pour coder votre première application web côté serveur.</dd>
+ <dt><a href="https://developer.mozilla.org/fr/docs/Learn/Server-side/First_steps/Website_security">Sécurité de votre site web</a></dt>
+ <dd>La sécurité de votre site web requiert une vigilance dans tous les aspects de sa conception et de son utilisation. Cet article d'introduction ne fera pas de vous un gourou de la sécurité des sites web, mais il vous aidera à comprendre les premières mesures importantes à prendre pour mettre votre application web à l'abri des menaces les plus courantes.</dd>
+</dl>
+
+<h2 id="Évaluations">Évaluations</h2>
+
+<p>Ce module "aperçu" n'a aucune évaluation car nous ne vous avons pas encore montré de code. Nous espérons à ce stade que vous avez une bonne compréhension des types de fonctionnalités que vous pouvez fournir en utilisant la programmation côté serveur et que vous avez pris une décision quant à l'infrastructure web côté serveur que vous utiliserez pour créer votre premier site web.</p>
diff --git a/files/fr/learn/server-side/premiers_pas/introduction/index.html b/files/fr/learn/server-side/premiers_pas/introduction/index.html
new file mode 100644
index 0000000000..d61d1d18c4
--- /dev/null
+++ b/files/fr/learn/server-side/premiers_pas/introduction/index.html
@@ -0,0 +1,234 @@
+---
+title: Présentation du côté serveur
+slug: Learn/Server-side/Premiers_pas/Introduction
+tags:
+ - Apprendre
+ - Débutant
+ - Guide
+ - Intro
+ - Programmation côté serveur
+ - Serveur
+translation_of: Learn/Server-side/First_steps/Introduction
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{NextMenu("Learn/Server-side/First_steps/Client-Server_overview", "Learn/Server-side/First_steps")}}</div>
+
+<p class="summary"><span class="seoSummary">Bienvenue au cours pour débutant de MDN sur la programmation côté serveur. Dans ce premier article, nous allons regarder la programmation côté serveur sans rentrer dans les détails techniques, en répondant aux questions telles que "qu'est-ce que c'est?", "quelle est la différence avec la programmation côté client?", et "pourquoi est-ce utile?". Après avoir lu cet article vous comprendrez commment la programmation côté serveur donne toute leur puissance aux sites web.</span></p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Prérequis:</th>
+ <td>Connaissances de base en informatique. Une compréhension de base de ce qu'est un serveur web.</td>
+ </tr>
+ <tr>
+ <th scope="row">Objectif:</th>
+ <td>Se familiariser avec la programmation côté serveur, ce qu'elle peut faire, et en quoi elle diffère de la programmation côté client.</td>
+ </tr>
+ </tbody>
+</table>
+
+<p>La plupart des sites web à grande échelle utilisent du code côté serveur pour afficher dynamiquement différentes données lorsque nécessaire ; ces données sont généralement extraites d'une base de données stockée sur un serveur et envoyées au client pour être affichées avec du code (HTML et/ou JavaScript). </p>
+
+<p>L'avantage le plus significatif du code côté serveur est sans doute qu'il permet d'adapter le contenu du site web à chaque utilisateur. Les sites dynamiques peuvent mettre en évidence du contenu pertinent en fonction des préférences et des habitudes de l'utilisateur. Il peut également faciliter l'utililsation des sites web en stockant des données, des informations personnelles — par exemple donner la possibilité d'enregistrer une carte de crédit pour les achats suivants.</p>
+
+<p>Cela peut même permettre une interaction avec les utilisateurs du site, en envoyant des notifications et mises à jour par email ou via d'autres canaux. Toutes ces capacités rendent possible un engagement plus important avec l'utilisateur.</p>
+
+<p>Dans le monde moderne du développement web, apprendre le développement côté serveur est fortement recommandé.</p>
+
+<h2 id="Quest-ce_que_la_programmation_côté_serveur">Qu'est-ce que la programmation côté serveur?</h2>
+
+<p>Les navigateurs web communiquent avec les <a href="/fr/Apprendre/Qu_est-ce_qu_un_serveur_web">serveurs web</a> en utilisant le protocole {{glossary("HTTP")}} (<strong>H</strong>yper<strong>T</strong>ext <strong>T</strong>ransfer <strong>P</strong>rotocol). Quand vous cliquez sur un lien dans une page web, envoyez un formulaire, ou encore lancez une recherche, une <strong>requête HTTP</strong> est envoyée du navigateur au serveur cible.</p>
+
+<p>Une requête inclut <em>une URL</em> pour identifier la ressource demandée, <em>une méthode</em> pour définir l'action désirée (comme GET pour obtenir, DELETE pour supprimer ou POST pour publier) et peut également inclure des informations supplémentaires encodées dans <em>les paramètres</em> de l'URL (des paires clés/valeurs envoyées via une chaîne de recherche — <a href="https://en.wikipedia.org/wiki/Query_string">query string</a> en anglais), les données POST (données envoyées par la <a href="/fr/docs/Web/HTTP/M%C3%A9thode/POST">méthode HTTP POST</a>), ou les {{glossary("Cookie", "cookies associés")}}.</p>
+
+<p>Les serveurs web attendent des requêtes du client, les traitent quand elles arrivent, et répondent au navigateur web avec une <strong>réponse HTTP</strong>. La réponse contient <em>un statut</em> qui indique si la requête a pu être traitée avec succès ou non (exemple "HTTP/1.1 200 OK" pour indiquer le succès). </p>
+
+<p>Le corps de la réponse, si la requête réussit, contient alors la ressource demandée (comme une page HTML, une image, etc...), que le navigateur web peut alors afficher.</p>
+
+<h3 id="Sites_statiques">Sites statiques</h3>
+
+<p>Le diagramme ci-dessous montre l'architecture d'un serveur web basique pour un <em>site statique</em> (un site statique est un site qui renvoie du contenu codé en dur, c'est à dire le contenu d'un fichier, quand une ressource donnée est demandée). Quand un utilisateur veut naviguer sur une page, le navigateur envoie une requête HTTP "GET" spécifiant son URL.</p>
+
+<p>Le serveur récupère le document demandé du système de fichiers et retourne une réponse HTTP contenant le document et le <a href="/fr/docs/Web/HTTP/Status#R%C3%A9ponses_de_succ%C3%A8s">statut de la réponse</a> (habituellement, 200 OK). Si le fichier ne peut pas être recupéré pour une raison x ou y, le statut d'erreur est retourné (voir <a href="/fr/docs/Web/HTTP/Status#R%C3%A9ponses_d'erreur_c%C3%B4t%C3%A9_client">réponses d'erreur client</a> et <a href="/fr/docs/Web/HTTP/Status#R%C3%A9ponses_d'erreur_c%C3%B4t%C3%A9_serveur">réponse d'erreur serveur</a>).</p>
+
+<p><img alt="A simplified diagram of a static web server." src="https://mdn.mozillademos.org/files/13841/Basic%20Static%20App%20Server.png" style="height: 223px; width: 800px;"></p>
+
+<h3 id="Sites_dynamiques">Sites dynamiques</h3>
+
+<p>Un site web dynamique, quant à lui, est un site dont une partie des réponses sont générées <em>dynamiquement</em>, à la demande. Sur les sites dynamiques, les pages HTML sont normalement crées en insérant des données d'une base de données dans des espaces réservés à l'intérieur de templates HTML (c'est une manière beaucoup plus efficace que des fichiers statiques pour stocker de grandes quantités de contenu). </p>
+
+<p>Un site dynamique peut retourner des données différentes pour une URL, en se basant sur les informations fournies par l'utilisateur ou les préférences stockées et peut effectuer des opérations avant de retourner la réponse.</p>
+
+<p>La plupart du code pour maintenir un site web dynamique doit s'exécuter sur le serveur. La création de ce code est ce qu'on appelle la "<strong>programmation côté serveur</strong>" (ou parfois "<strong>codage back-end</strong>").</p>
+
+<p>Le diagramme ci-dessous montre une architecture simple pour un <em>site web dynamique</em>. Comme dans le diagramme précédent, les navigateurs envoient des requêtes HTTP au serveur, qui les traite et retourne les réponses HTTP appropriées.</p>
+
+<p>Les requêtes pour les ressources <em>statiques</em> sont toujours gérées de la même manière que pour les sites statiques (les ressources statiques sont tous les fichiers qui ne changent pas —typiquement : CSS, JavaScript, Images, fichiers PDF etc).</p>
+
+<p><img alt="A simplified diagram of a web server that uses server-side programming to get information from a database and construct HTML from templates. This is the same diagram as is in the Client-Server overview." src="https://mdn.mozillademos.org/files/13839/Web%20Application%20with%20HTML%20and%20Steps.png"></p>
+
+<p>Les requêtes pour les ressources <em>dynamiques</em>, elles, sont transmises (2) au code côté serveur (indiqué dans le diagramme comme <em>Web Application</em>). Le serveur interprète la requête, lit les informations correspondantes dans la base de données (3), combine les données récupérées avec les templates HTML (4), et renvoie la réponse avec le HTML généré (5,6). </p>
+
+<div>
+<h2 id="La_programmation_côté_serveur_cest_pareil_que_côté_client">La programmation côté serveur c'est pareil que côté client?</h2>
+</div>
+
+<p>Voyons maintenant le code impliqué dans la programmation côté serveur et côté client. Dans chaque cas, le code est significativement différent :</p>
+
+<ul>
+ <li>Ils ont des objectifs et des préoccupations différents.</li>
+ <li>Ils n'utilisent généralement pas les mêmes langages de programmation (exception faite de JavaScript, qui peut être utilisé côté serveur et côté client).</li>
+ <li>Ils s'exécutent dans des environnements différents du système d'exploitation.</li>
+</ul>
+
+<p>Le code exécuté par le navigateur est connu sous le nom de <strong>code côté client</strong> (ou <strong>front-end</strong>) et se préoccupe principalement de l'apparence et du comportement des pages web affichées. Cela inclut sélectionner et styliser les composants de l'interface utilisateur, créer la mise en page, la navigation, valider les formulaires, etc. D'un autre côté, la programmation côté serveur implique de définir le contenu retourné au navigateur en réponse aux requêtes. Le code côté serveur gère des tâches telles que la validation des données envoyées, l'utilisation des bases de données pour stocker et récupérer des données et l'envoi de données générées au client tel qu'attendu.</p>
+
+<p>Le code client est écrit en <a href="/fr/Apprendre/HTML">HTML</a>, <a href="/fr/Apprendre/CSS">CSS</a>, et <a href="/fr/Apprendre/JavaScript">JavaScript</a> — il est exécuté dans un navigateur web et a peu ou pas accès au système d'exploitation de l'utilisateur (inclut un accès limité au système de fichiers).</p>
+
+<p>Les développeurs web ne peuvent pas contrôler quel navigateur est utilisé par l'utilisateur pour voir le site web  — or les navigateurs fournissent des niveaux de compatibilité inconsistants quant aux fonctionnalités du code côté client, et une partie du challenge de la programmation côté client consiste à gérer les différences de support des navigateurs.</p>
+
+<p>Le code côté serveur peut être écrit dans nombre de langages de programmation — les langages les plus populaires pour la programmation web côté serveur sont en autres PHP, Python, Ruby, C#, et NodeJS(JavaScript). Le code côté serveur a plein accès au système d'exploitation du serveur et le développeur est libre de choisir le langage (et la version) qu'il veut utiliser.</p>
+
+<p>Typiquement, les développeurs écrivent leur code en utilisant des <strong>frameworks web</strong>. Les frameworks web sont des ensembles de fonctions, objets, règles et autres constructions de code conçus pour résoudre des problèmes courants, accélérer le développement et simplifier les différents types de tâches rencontrées dans un domaine particulier.</p>
+
+<p>Encore une fois, bien que le code côté client et côté serveur utilisent des frameworks, les domaines d'application sont très différents et par conséquent les frameworks aussi. Les frameworks web côté client simplifient les tâches de mise en page et de présentation tandis que les frameworks web côté serveur fournissent des fonctionnalités "courantes" que vous auriez probablement à implémenter vous-même autrement (comme le support des sessions, des utilisateurs et de l'authentification, l'accès à la base de données, les bibliothèques de templates, etc.).</p>
+
+<div class="note">
+<p><strong>Note </strong>: Les frameworks côté client sont souvent utilisés pour accélérer le développement du code côté client, mais vous pouvez également choisir d'écrire tout le code à la main ; en vérité, écrire votre code à la main peut être plus rapide et plus efficace si vous n'avez besoin que d'une petite interface web très simple.</p>
+
+<p>En revanche, vous ne penseriez presque jamais à écrire les composants côté serveur d'une application web sans framework — implémenter des fonctionnalités vitales comme un serveur HTTP est très difficile à faire à partir de rien, comme disons en Python, alors que les frameworks web Python comme Django le fournissent tout prêt à l'emploi, accompagné d'autres outils très utiles.</p>
+</div>
+
+<div>
+<h2 id="Que_peut-on_faire_côté_serveur">Que peut-on faire côté serveur?</h2>
+
+<p>La programmation côté serveur est très utile parce qu'elle nous permet de délivrer efficacement de l'information taillée sur mesure pour l'utilisateur et ainsi créer une bien meilleure expérience utilisateur.</p>
+</div>
+
+<p>Des compagnies comme Amazon utilisent la programmation côté serveur pour construire la recherche de produits, faire des suggestions de produit ciblées sur les préférences du client et ses habitudes d'achat, simplifier les achats, etc.</p>
+
+<p>Les banques l'utilisent pour stocker les informations du compte ainsi que faire des transactions et n'autoriser à les consulter que les utilisateurs reconnus. D'autres services comme Facebook, Twitter, Instagram, et Wikipedia utilisent la programmation côté serveur pour mettre en avant, partager et contrôler l'accès au contenu.</p>
+
+<p>Les utilisations les plus courantes et les plus bénéfiques de la programmation côté serveur sont listées ci-dessous. Vous verrez qu'il y a quelques recoupements :</p>
+
+<h3 id="Stockage_et_distribution_de_linformation_plus_efficaces">Stockage et distribution de l'information plus efficaces</h3>
+
+<p>Imaginez combien de produits sont disponibles sur Amazon et combien de posts ont été écrits sur Facebook. Créer une page statique distincte pour chaque produit ou article serait totalement impossible.</p>
+
+<p>La programmation côté serveur nous permet plutôt de stocker l'information dans une base de données et de construire et retourner dynamiquement le HTML ainsi que d'autres types de fichiers (comme les PDF, images, etc.). Il est également possible de simplement retourner des données ({{glossary("JSON")}}, {{glossary("XML")}}, etc.) pour les afficher avec des frameworks côté client (cela réduit la charge de travail du serveur et la quantité de données qui doit être retournée).</p>
+
+<p>Le serveur ne se limite pas à l'envoi d'informations à partir de bases de données, il peut retourner le résultat d'autres outils logiciels, ou les données de services de communication. Le contenu peut même être ciblé pour le type d'appareil client qui le reçoit.</p>
+
+<p>Comme les informations se trouvent dans une base de données, elles peuvent également être partagées et mises à jour plus facilement avec d'autres systèmes (par exemple, quand des produits sont vendus en ligne ou dans un magasin, le magasin peut mettre à jour son inventaire).</p>
+
+<div class="note">
+<p><strong>Note </strong>: Votre imagination n'a pas à travailler dur pour voir les bénéfices du code côté serveur pour le stockage et distribution de l'information:</p>
+
+<ol>
+ <li>Allez sur <a href="https://www.amazon.com">Amazon</a> ou tout autre site e-commerce.</li>
+ <li>Cherchez un certain nombre de mot-clés et remarquez que la structure de la page de change pas, même si les résultats oui. </li>
+ <li>Ouvrez deux ou trois produits. Remarquez que la structure et la disposition de la page sont identiques, mais que le contenu pour les différents produits a été extrait de la base de données.</li>
+</ol>
+
+<p>Pour un terme de recherche courant  ("poisson", disons) vous pouvez voir littéralement des millions de valeurs retournées. Utiliser une base de données permet à ces données d'être stockées et partagées efficacement, et permet de contrôler la présentation de l'information à partir d'un seul endroit.</p>
+</div>
+
+<h3 id="Expérience_utilisateur_personnalisée">Expérience utilisateur personnalisée</h3>
+
+<p>Les serveurs peuvent stocker et utiliser des informations sur les clients pour fournir une expérience utilisateur personnalisée. Par exemple, beaucoup de sites proposent d'enregistrer une carte de crédit pour que les détails n'aient pas à être saisis de nouveau. Des sites comme Google Maps peuvent utiliser les emplacement enregistrés ou l'emplacement en cours pour fournir des informations d'itinéraire et chercher ou utiliser l'historique des voyages précédents pour trouver des boutiques locales dans les résultats de recherche.</p>
+
+<p>Une analyse plus approfondie des habitudes des utilisateurs peut être utilisée pour anticiper leurs intérêts et personnaliser les réponses ou les notifications du serveur, par exemple pour fournir une liste des lieux précédemment visités ou les plus populaires que vous pourriez vouloir chercher sur la carte.</p>
+
+<div class="note">
+<p><strong>Note : </strong><a href="https://maps.google.com/">Google Maps</a> sauvegarde vos recherches et votre historique de visites. Les emplacement fréquemment visités ou fréquemment recherchés sont plus mis en avant que les autres.</p>
+
+<p>Les résultats de recherche Google sont optimisés en fonction des recherches précédentes.</p>
+
+<ol>
+ <li> Allez sur <a href="https:\\google.com">Google</a>.</li>
+ <li> Recherchez "football".</li>
+ <li> Maintenant tapez "favoris" dans la barre de recherche et regardez les prédictions de recherche de l'autocomplete.</li>
+</ol>
+
+<p>Coïncidence ? Nada!</p>
+</div>
+
+<h3 id="Accès_contrôlé_au_contenu">Accès contrôlé au contenu</h3>
+
+<p>La programmation côté serveur permet aux sites de restreindre l'accès aux utilisateurs autorisés et de ne servir que les informations qu'un utilisateur à la permission de voir.</p>
+
+<p>Quelques exemples du monde réel incluent :</p>
+
+<ul>
+ <li>Les réseaux sociaux comme Facebook permettent aux utilisateurs de contrôler entièrement leurs propres données, mais permettent seulement à leurs amis de les voir ou des les commenter. L'utilisateur détermine qui peut voir ses données, et par extension, dans le flux de qui elles apparaissent —  l'autorisation est une partie centrale de l'expérience utilisateur !</li>
+ <li>
+ <p>Le site sur lequel vous êtes en ce moment même contrôle l'accès au contenu : les articles sont visibles à tout le monde, mais seuls les utilisateurs identifiés peuvent éditer le contenu. Essayez de cliquer sur le bouton <strong>Modifier</strong> en haut de cette page — si vous êtes identifié, vous verrez la vue d'édition ; sinon, vous serez redirigé vers la page d'inscription.</p>
+ </li>
+</ul>
+
+<div class="note">
+<p><strong>Note </strong>: Il existe de nombreux autres exemples où l'accès au contenu est contrôlé. Par exemple, que voyez-vous si vous allez sur le site en ligne de votre banque ? Connectez-vous à votre compte — quelles autres informations pouvez-vous voir et modifier ? Quelles informations pouvez-vous voir que seule la banque peut changer ?</p>
+</div>
+
+<h3 id="Stocker_les_informations_de_sessiondétat">Stocker les informations de session/d'état</h3>
+
+<p>La programmation côté serveur permet aux développeurs d'utiliser des <strong>sessions</strong> — en gros, un mécanisme qui permet au serveur de stocker des informations sur l'utilisation en cours d'un site et d'envoyer des réponses différentes selon cette information.</p>
+
+<p>Cela permet, par exemple, à un site de savoir qu'un utilisateur s'est déjà identifié et afficher des messages qui lui sont destinés, d'afficher son historique de commande, ou peut-être encore, dans le cas d'un jeu, lui permettre de reprendre là où il en est resté.</p>
+
+<div class="note">
+<p><strong>Note </strong>: Visitez le site d'un journal qui a une offre d'abonnement et ouvrez des pages (par exemple <a href="http://www.theage.com.au/">The Age</a>). Si vous continuez à visiter le site quelques heures/jours, éventuellement, vous commencerez à être redirigé vers des pages expliquant comment vous abonner, et vous ne pourrez plus accéder aux articles. Cette information est un exemple de session stockée dans des cookies.</p>
+</div>
+
+<h3 id="Notifications_et_communication">Notifications et communication</h3>
+
+<p>Les serveurs peuvent envoyer des notifications générales ou personnalisées à l'utilisateur via le site web lui-même ou par email, SMS, messagerie instantannée, conversations vidéo ou autres services de communication.</p>
+
+<p>Quelques exemples incluent :</p>
+
+<ul>
+ <li>Facebook et Twitter envoient des emails et SMS pour notifier des nouvelles communications.</li>
+ <li>Amazon envoie régulièrement des emails qui suggèrent des produits similaires à ceux que vous avez déjà acheté ou vu, par lesquels vous pourriez être intéressé.</li>
+ <li>Un serveur web peut envoyer des messages d'alerte aux administrateurs du site pour les prévenir en cas de mémoire insuffisante sur le serveur ou d'activité suspecte de l'utilisateur.</li>
+</ul>
+
+<div class="note">
+<p><strong>Note </strong>: Le type de notification le plus courant est la "confirmation d'inscription". Choisissez presque n'importe quel site qui vous intéresse (Google, Amazon, Instagram, etc.) et créez un nouveau compte en utilisant votre adresse email. Vous recevrez rapidement un email qui confirme votre inscription, ou qui exige une confirmation pour activer votre compte.</p>
+</div>
+
+<h3 id="Analyse_des_données">Analyse des données</h3>
+
+<p>Un site web peut collecter beaucoup de données sur les utilisateurs : ce qu'ils cherchent, ce qu'ils achètent, ce qu'ils recommandent, combien de temps ils restent sur chaque page. La programmation côté serveur peut être utilisée pour affiner les réponses en fonction de l'analyse de ces données.</p>
+
+<p>Par exemple, Amazon et Google font tous deux de la publicité pour des produits en se basant sur les recherches précédentes, sur les achats que vous avez faits.</p>
+
+<div class="note">
+<p><strong>Note </strong>: Si vous êtes un utilisateur de Facebook, allez sur votre flux principal et regardez les posts. Notez que certains posts ne sont pas classés par ordre numérique — en particulier, les posts qui ont le plus de "likes" sont souvent placés plus haut dans la liste que les posts plus récents.</p>
+
+<p>Observez également quels types de publicités vous voyez — vous pourrez voir des publicités pour des choses que vous avez regardé sur d'autres sites. L'algorithme de Facebook pour mettre en avant du contenu et faire de la publicité est un peu un mystérieux, mais il est clair qu'il prend en compte vos likes et ce que vous avez l'habitude de regarder !</p>
+</div>
+
+<h2 id="Sommaire">Sommaire</h2>
+
+<p>Félicitations, vous avez atteint la fin du premier article sur la programmation côté serveur. </p>
+
+<p>Vous avez maintenant appris que le code côté serveur est exécuté sur un serveur web et que son rôle principal est de contrôler <em>quelle</em> information est envoyée à l'utilisateur (tandis que le code côté client gère principalement la structure et la présentation des données pour l'utilisateur).</p>
+
+<p>Vous devez également comprendre que c'est utile pour créer des sites web qui délivrent de l'information <em>efficacement</em>, adaptée à chaque utilisateur et avoir une bonne idée de quelques choses que vous seriez capable de faire quand vous serez programmeur back-end.</p>
+
+<p>Finalement, vous devez comprendre que le code côté serveur peut être écrit dans de nombreux langages de programmation et que l'on peut utiliser des frameworks web pour rendre ce processus plus facile.</p>
+
+<p>Dans un futur article,  nous vous aiderons à choisir le framework le plus adapté pour la création d'un premier site. Ensuite, nous vous présenterons les principales interactions client-serveur plus en détails.</p>
+
+<p>{{NextMenu("Learn/Server-side/First_steps/Client-Server_overview", "Learn/Server-side/First_steps")}}</p>
+
+<h2 id="Dans_ce_module">Dans ce module</h2>
+
+<ul>
+ <li><a href="/fr/docs/Learn/Server-side/First_steps/Introduction">Introduction au côté serveur</a></li>
+ <li><a href="/fr/docs/Learn/Server-side/First_steps/Client-Server_overview">Vue d'ensemble Client-Serveur</a></li>
+ <li><a href="/fr/docs/Learn/Server-side/First_steps/Web_frameworks">Frameworks web côté serveur</a></li>
+ <li><a href="/fr/docs/Learn/Server-side/First_steps/Website_security">La sécurité d'un site web</a></li>
+</ul>
diff --git a/files/fr/learn/server-side/premiers_pas/web_frameworks/index.html b/files/fr/learn/server-side/premiers_pas/web_frameworks/index.html
new file mode 100644
index 0000000000..b75c70fa0f
--- /dev/null
+++ b/files/fr/learn/server-side/premiers_pas/web_frameworks/index.html
@@ -0,0 +1,306 @@
+---
+title: Les frameworks web côté serveur
+slug: Learn/Server-side/Premiers_pas/Web_frameworks
+tags:
+ - Débutant
+ - Guide
+ - Server
+ - Web
+translation_of: Learn/Server-side/First_steps/Web_frameworks
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/Server-side/First_steps/Client-Server_overview", "Learn/Server-side/First_steps/Website_security", "Learn/Server-side/First_steps")}}</div>
+
+<p class="summary">L'article précédent nous a montré à quoi ressemble la communication entre les clients et les serveurs web, la nature des demandes et des réponses HTTP et ce qu’une application web côté serveur doit faire pour répondre aux demandes d’un navigateur web. Avec ces connaissances en main, il est temps d'explorer comment les frameworks peuvent nous simplifier la tâche.  En chemin, vous comprendrez comment choisir le framework le mieux adapté pour votre première application web côté serveur.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Prérequis :</th>
+ <td>Connaissance informatique de base.</td>
+ </tr>
+ <tr>
+ <th scope="row">Objectif :</th>
+ <td>Comprendre comment les frameworks simplifient le développement/la maintenance du code côté serveur et vous faire réfléchir à propos de la sélection d'un framework pour votre propre développement.</td>
+ </tr>
+ </tbody>
+</table>
+
+<p>Les sections suivantes proposent des illustrations avec des fragments de codes utilisés par des frameworks réels. Ne soyez pas inquiété si vous ne comprenez pas tout directement. Les explications viendront au fur et à mesure.</p>
+
+<h2 id="Vue_densemble">Vue d'ensemble</h2>
+
+<p>Les frameworks web côté serveur (c-à-d "web application frameworks") facilitent l'écriture, la maintenance et la mise à l'échelle d'applications web. Ils fournissent des outils et des bibliothèques qui simplifient les tâches courantes de développement web, notamment l'acheminement des URL vers les gestionnaires appropriés, l'interaction avec les bases de données, les sessions et l'autorisation des utilisateurs, le formatage de la sortie (HTML, JSON, XML, par exemple) et l'amélioration de la sécurité contre les attaques web.</p>
+
+<p>Dans la section suivante, nous allons voir un peu plus de détails comment les frameworks facilite le développement d'applications web. Nous verrons alors les critères utilisés pour choisir un framework adapté.</p>
+
+<h2 id="Que_peut_faire_un_framework_web_pour_vous">Que peut faire un framework web pour vous ?</h2>
+
+<p>Les frameworks web fournissent des outils et des bibliothèques pour simplifier les opérations de développement web courantes. Utiliser un framework web côté serveur n'est pas obligatoire, mais fortement conseillé... Cela vous facilitera grandement la vie. Cette section présente certaines des fonctionnalités parmi les plus souvent fournies par les frameworks web.</p>
+
+<h3 id="Travailler_directement_avec_les_requêtes_et_les_réponses_HTTP">Travailler directement avec les requêtes et les réponses HTTP</h3>
+
+<p>Comme nous l'avons vu dans le dernier article, les serveurs web et les navigateurs communiquent via le protocole HTTP — les serveurs attendent les requêtes HTTP du navigateur, puis renvoient des informations dans les réponses HTTP. Les infrastructures web vous permettent d'écrire une syntaxe simplifiée qui générera un code côté serveur pour travailler avec ces demandes et réponses. Cela signifie que vous aurez un travail plus facile, en interagissant avec un code plus facile, de niveau supérieur, plutôt que des primitives de réseau de niveau inférieur.</p>
+
+<p>L'exemple ci-dessous montre comment cela fonctionne dans le framework web Django (Python). Chaque fonction "view" (un gestionnaire de demandes) reçoit un objet HttpRequest contenant les informations de la demande et doit renvoyer un objet HttpResponse avec la sortie formatée (dans ce cas une chaîne).</p>
+
+<pre class="brush: python"># Django view function
+from django.http import HttpResponse
+
+def index(request):
+ # Get an HttpRequest (request)
+ # perform operations using information from the request.
+ # Return HttpResponse
+ return HttpResponse('Output string to return')
+</pre>
+
+<h3 id="Acheminer_les_requettes_au_gestionnaire_approprié">Acheminer les requettes au gestionnaire approprié</h3>
+
+<p>La plupart des sites fournissent un certain nombre de ressources différentes, accessibles via des URL distinctes. Il est difficile de gérer toutes ces fonctions en une seule fois. Par conséquent, les infrastructures web fournissent des mécanismes simples pour mapper les modèles d'URL vers des fonctions de gestionnaire spécifiques. Cette approche présente également des avantages en termes de maintenance, car vous pouvez modifier l'URL utilisée pour fournir une fonctionnalité particulière sans avoir à modifier le code sous-jacent.</p>
+
+<p>Différents frameworks utilisent différents mécanismes pour la cartographie. Par exemple, l'infrastructure web Flask (Python) ajoute des itinéraires pour afficher les fonctions à l'aide d'un décorateur.</p>
+
+<pre class="brush: python">@app.route("/")
+def hello():
+ return "Hello World!"</pre>
+
+<p>Alors que Django attend des développeurs qu'ils définissent une liste de mappages d'URL entre un modèle d'URL et une fonction d'affichage.</p>
+
+<pre class="brush: python">urlpatterns = [
+ url(r'^$', views.index),
+ # example: /best/myteamname/5/
+ url(r'^(?P&lt;team_name&gt;\w.+?)/(?P&lt;team_number&gt;[0-9]+)/$', views.best),
+]
+</pre>
+
+<h3 id="Faciliter_laccès_aux_données_via_la_requête">Faciliter l'accès aux données via la requête</h3>
+
+<p>Les données peuvent être encodées dans une requête HTTP de différentes manières. Une demande HTTP GET pour obtenir des fichiers ou des données du serveur peut coder les données requises dans les paramètres d'URL ou dans la structure d'URL. Une demande HTTP POST de mise à jour une ressource sur le serveur inclura plutôt les informations de mise à jour en tant que "données POST" dans le corps de la demande. La requête HTTP peut également inclure des informations sur la session ou l'utilisateur en cours dans un cookie côté client. Les frameworks web fournissent des mécanismes appropriés au langage de programmation pour accéder à ces informations. Par exemple, l'objet HttpRequest que Django transmet à chaque fonction d'affichage contient des méthodes et des propriétés permettant d'accéder à l'URL cible, le type de demande (par exemple, un HTTP GET), les paramètres GET ou POST, les données de cookie et de session, etc. Django peut également transmettre informations codées dans la structure de l'URL en définissant des "modèles de capture" dans le mappeur d'URL (voir le dernier fragment de code dans la section ci-dessus).</p>
+
+<h3 id="extraction_et_simplification_de_l’accès_à_la_base_de_données">extraction et simplification de l’accès à la base de données</h3>
+
+<p>Les sites web utilisent des bases de données pour stocker des informations à partager avec les utilisateurs et sur les utilisateurs. Les infrastructures web fournissent souvent une couche de base de données qui extrait les opérations de lecture, d'écriture, de requête et de suppression de base de données. Cette couche d'extraction est appelée ORM (Object-Relational Mapper).</p>
+
+<p>L'utilisation d'un ORM présente deux avantages :   </p>
+
+<ol>
+ <li>Vous pouvez remplacer la base de données sous-jacente sans avoir nécessairement besoin de changer le code qui l'utilise. Cela permet aux développeurs d’optimiser les caractéristiques des différentes bases de données en fonction de leur utilisation.   </li>
+ <li>La validation de base des données peut être mise en œuvre avec le framework. Il est ainsi plus facile et plus sûr de vérifier que les données sont stockées dans le type de champ de base de données approprié, qu’elles ont le format correct (par exemple une adresse électronique) et qu’elles ne sont en aucun cas malveillantes (les pirates peuvent utiliser certains modèles de code pour agir mal, telles que la suppression des enregistrements de la base de données).</li>
+</ol>
+
+<p>Par exemple, le framework web Django fournit un ORM et fait référence à l'objet utilisé pour définir la structure d'un enregistrement en tant que modèle. Le modèle spécifie les types de champs à stocker, ce qui peut fournir une validation au niveau du champ sur les informations pouvant être stockées (par exemple, un champ de courrier électronique autoriserait uniquement les adresses de courrier électronique valides). Les définitions de champ peuvent également spécifier leur taille maximale, leurs valeurs par défaut, leurs options de liste de sélection, leur aide pour la documentation, leur libellé pour les formulaires, etc. Le modèle ne spécifie aucune information sur la base de données sous-jacente, il s'agit d'un paramètre de configuration susceptible d'être modifié séparément de notre code.</p>
+
+<p>Le premier extrait de code ci-dessous montre un modèle Django très simple pour un objet Team. Ceci stocke le nom et le niveau de l'équipe en tant que champs de caractères et spécifie un nombre maximal de caractères à stocker pour chaque enregistrement. Team_level étant un champ de choix, nous fournissons également un mappage entre les choix à afficher et les données à stocker, ainsi qu'une valeur par défaut.</p>
+
+<pre class="brush: python">#best/models.py
+
+from django.db import models
+
+class Team(models.Model):
+ team_name = models.CharField(max_length=40)
+
+ TEAM_LEVELS = (
+ ('U09', 'Under 09s'),
+ ('U10', 'Under 10s'),
+ ('U11, 'Under 11s'),
+ ... #list our other teams
+ )
+ team_level = models.CharField(max_length=3,choices=TEAM_LEVELS,default='U11')
+</pre>
+
+<p>Le modèle Django fournit une API de requête simple pour la recherche dans la base de données. Cela peut correspondre à plusieurs champs à la fois en utilisant différents critères (par exemple, exact, insensible à la casse, supérieur à, etc.), et peut prendre en charge des instructions complexes (par exemple, vous pouvez spécifier une recherche sur les équipes U11 ayant un nom d'equipe (team name) qui commence par "Fr" ou se termine par "al").</p>
+
+<p>Le deuxième extrait de code montre une fonction d'affichage (gestionnaire de ressources) permettant d'afficher toutes nos équipes U09. Dans ce cas, nous spécifions que nous voulons filtrer tous les enregistrements où le champ team_level a exactement le texte 'U09' (notez dans l exemple ci dessous comment ce critère est transmis à la fonction filter () sous forme d'argument avec le nom du champ et le type de correspondance séparés par un double. underscores: team_level__exact).</p>
+
+<pre class="brush: python">#best/views.py
+
+from django.shortcuts import render
+from .models import Team
+
+def youngest(request):
+ <strong>list_teams = Team.objects.filter(team_level__exact="U09")</strong>
+ context = {'youngest_teams': list_teams}
+ return render(request, 'best/index.html', context)
+</pre>
+
+<dl>
+</dl>
+
+<h3 id="Rendering_data">Rendering data</h3>
+
+<p>Les frameworks web fournissent souvent des systèmes de templates. Ceux-ci vous permettent de spécifier la structure d'un document de sortie, en utilisant des espaces réservés pour les données qui seront ajoutées lors de la génération d'une page. Les modèles sont souvent utilisés pour créer du HTML, mais peuvent également créer d'autres types de documents.</p>
+
+<p>Les frameworks web fournissent souvent un mécanisme facilitant la génération d'autres formats à partir de données stockées, notamment {{glossary ("JSON")}} et {{glossary ("XML")}}.</p>
+
+<p>Par exemple, le système de templates Django vous permet de spécifier des variables en utilisant une syntaxe "double-handlebars" (par exemple,<code>{</code><code>{ <em>variable_name</em> </code><code>}</code><code>}</code> ), qui sera remplacée par les valeurs transmises à partir de la fonction d'affichage lors du rendu d'une page. Le système de templates prend également en charge les expressions (avec la syntaxe:<code>{% <em>expression</em> %}</code> ), qui permettent aux templates d'effectuer des opérations simples, telles que l'itération des valeurs de liste transmises au modèle.</p>
+
+<div class="note">
+<p><strong>Note </strong>: Many other templating systems use a similar syntax, e.g.: Jinja2 (Python), handlebars (JavaScript), moustache (JavaScript), etc.</p>
+</div>
+
+<p>L'extrait de code ci-dessous montre comment cela fonctionne. En reprenant l'exemple "youngest_teams" de la section précédente, le modèle HTML se voit transmettre par la vue une variable de liste nommée youngest_teams. Dans le squelette HTML, nous avons une expression qui vérifie d'abord si la variable youngest_teams existe, puis itère dans une boucle for. À chaque itération, le modèle affiche la valeur team_name de l'équipe dans un élément de liste.</p>
+
+<pre class="brush: html">#best/templates/best/index.html
+
+&lt;!DOCTYPE html&gt;
+&lt;html lang="en"&gt;
+&lt;body&gt;
+
+ {% if youngest_teams %}
+ &lt;ul&gt;
+ {% for team in youngest_teams %}
+ &lt;li&gt;\{\{ team.team_name \}\}&lt;/li&gt;
+ {% endfor %}
+ &lt;/ul&gt;
+{% else %}
+ &lt;p&gt;No teams are available.&lt;/p&gt;
+{% endif %}
+
+&lt;/body&gt;
+&lt;/html&gt;
+</pre>
+
+<h2 id="Comment_choisir_un_framework_web"><span style='background-color: #f5f5f5; color: rgba(0, 0, 0, 0.87); display: inline !important; float: none; font-family: "Roboto",arial,sans-serif; font-size: 24px; font-style: normal; font-variant: normal; font-weight: 400; letter-spacing: normal; text-align: left; text-decoration: none; text-indent: 0px; text-transform: none; white-space: pre-wrap;'>Comment choisir un framework web</span></h2>
+
+<p>Il existe de nombreux frameworks web pour presque tous les langages de programmation que vous souhaitez utiliser (nous énumérons quelques-uns des frameworks les plus populaires dans la section suivante). Avec autant de choix, il peut devenir difficile de déterminer quel framework constitue le meilleur point de départ pour votre nouvelle application web.</p>
+
+<p>Certains des facteurs qui peuvent affecter votre décision sont les suivants:</p>
+
+<ul>
+ <li><strong>Effort d'apprentissage </strong>: L'effort d'apprentissage d'un framework web dépend de votre familiarité avec le langage de programmation sous-jacent, de la cohérence de son API, de la qualité de sa documentation ainsi que de la taille et de l'activité de sa communauté. Si vous avez peu d'eqperience en programmation, pensez à Django (l’un des plus faciles à apprendre en fonction des critères ci-dessus). Si vous faites partie d'une équipe de développement qui possède déjà une expérience significative avec un framework web ou un langage de programmation particulier, il est logique de s'en tenir à cela.</li>
+ <li><strong>Productivité </strong>: la productivité mesure la rapidité avec laquelle vous pouvez créer de nouvelles fonctionnalités une fois que vous êtes familiarisé avec le framework. Elle inclut à la fois les efforts d'écriture et de maintenance du code (car vous ne pouvez pas écrire de nouvelles fonctionnalités alors que les anciennes sont endommagées). Un grand nombre des facteurs qui affectent la productivité sont similaires à ceux de "Effort d'apprentissage" - par ex. documentation, communauté, expérience en programmation, etc. - les autres facteurs incluent:
+ <ul>
+ <li><em>Objectif / origine du framework </em>: certains frameworks web ont été créés à l'origine pour résoudre certains types de problèmes, et restent meilleurs pour créer des applications web avec des contraintes similaires. Par exemple, Django a été créé pour soutenir le développement d'un site web de journal. Il est donc bon pour les blogs et les autres sites impliquant la publication d'éléments. En revanche, Flask est un cadre beaucoup plus léger et est idéal pour créer des applications web s'exécutant sur des périphériques intégrés.</li>
+ <li><em>Populaire vs Impopulaire</em>: Un framework populaire est un frameqork dans lequel il est recommandé de "meilleures" manières de résoudre un problème particulier. Les frameworks populaire ont tendance à être plus productifs lorsque vous essayez de résoudre des problèmes courants, car ils vous orientent dans la bonne direction, mais ils sont parfois moins flexibles.</li>
+ <li><em>Ressource incluses vs. l'obtenir vous-même </em>: certains frameworks web incluent des outils / bibliothèques qui traitent tous les problèmes que leurs développeurs peuvent penser "par défaut", tandis que des frameworks plus légers attendent des développeurs web qu'ils choisissent la solution aux problèmes de bibliothèques séparées (Django est un exemple inclue " tout " tandis que  Flask est un exemple de framework très léger). Les frameworks qui incluent tout sont souvent plus faciles à démarrer car vous avez déjà tout ce dont vous avez besoin, et il est probable qu’il soit bien intégré et bien documenté. Cependant, si une structure plus petite contient tout ce dont vous avez besoin (le cas échéant), elle peut alors s'exécuter dans des environnements plus restreints et disposer d'un sous-ensemble de choses plus petites et plus faciles à apprendre.</li>
+ <li><em>Si le framework encourage ou non les bonnes pratiques de développement </em>: par exemple, un cadre qui encourage une architecture Model-View-Controller où on sépare le code en fonctions logiques engendrera un code plus facile à maintenir qu'un code qui n'a pas d'attente de la part des développeurs. De même, la conception de la structure peut avoir un impact important sur la facilité de test et de réutilisation du code.</li>
+ </ul>
+ </li>
+ <li><strong>Performances du framework/langage de programmation </strong>: généralement, la <em>vitesse</em> n’est pas le facteur le plus important dans la sélection car même des exécutions relativement lentes, comme Python, sont plus que <em>suffisantes</em> pour les sites de taille moyenne fonctionnant avec un matériel raisonnablement performant. Les avantages perçus en termes de vitesse par rapport à un autre langage comme C++ ou JavaScript peuvent être compensés par les coûts d’apprentissage et de maintenance.</li>
+ <li><strong>Mise en cache </strong>: la popularité de votre site web grandit, vous constatez peut-être que le serveur ne peut plus gérer toutes les requêtes. À ce stade, vous pouvez envisager d’ajouter un support pour la mise en cache : une optimisation dans laquelle vous stockez tout ou partie de la réponse à une requête web afin qu'il ne soit pas nécessaire de la recalculer la prochaine fois. Retourner la réponse en cache à une requête est beaucoup plus rapide que d'en calculer une. La mise en cache peut être implémentée dans votre code ou sur le serveur (voir proxy inverse). Les infrastructures web auront différents niveaux de prise en charge pour définir le contenu pouvant être mis en cache.</li>
+ <li><strong>Adpatation </strong>: votre site web connaît un succès fantastique, vous avez épuisé les avantages de la mise en cache, vous atteignez même les limites de la mise à l'échelle verticale (exécuter votre application Web sur un matériel plus puissant). À ce stade, il est temps de penser à une mise à l’échelle horizontale (partager la charge en répartissant votre site sur un certain nombre de serveurs web et de bases de données) ou «géographiquement», car certains de vos clients sont très éloignés de votre serveur. L'infrastructure web que vous choisissez peut faire toute la différence en termes de facilité d'adaptation de votre site.</li>
+ <li><strong>Sécurité web </strong>: certains environnements web offrent une meilleure prise en charge de la gestion des attaques web courantes. Django, par exemple, supprime toutes les entrées utilisateur des modèles HTML afin que le code JavaScript saisi par l'utilisateur ne puisse pas être exécuté. D'autres frameworks offrent une protection similaire, mais celle-ci n'est pas toujours activée par défaut.</li>
+</ul>
+
+<p>Il existe de nombreux autres facteurs possibles, y compris les licences, que le cadre soit ou non en cours de développement actif, etc.</p>
+
+<p>Si vous débutez en programmation, vous choisirez probablement un framework facile à prendre en main. Une documentation riche et une communauté active sont également des critères pertinents pour votre choix. Pour la suite de ce cours, nous avons choisi Django (Python) et Express (Node/JavaScript) principalement parce que ces frameworks sont faciles à apprendre et bénéficient d'un bon soutien.</p>
+
+<div class="note">
+<p><strong>Note</strong>: Let's go to the main websites for <a href="https://www.djangoproject.com/">Django</a> (Python) and <a href="http://expressjs.com/">Express</a> (Node/JavaScript) and check out their documentation and community.</p>
+
+<ol>
+ <li>Navigate to the main sites (linked above)
+ <ul>
+ <li>Click on the Documentation menu links (named things like "Documentation, Guide, API Reference, Getting Started".</li>
+ <li>Can you see topics showing how to set up URL routing, templates, and databases/models?</li>
+ <li>Are the documents clear?</li>
+ </ul>
+ </li>
+ <li>Navigate to mailing lists for each site (accessible from Community links).
+ <ul>
+ <li>How many questions have been posted in the last few days</li>
+ <li>How many have responses?</li>
+ <li>Do they have an active community?</li>
+ </ul>
+ </li>
+</ol>
+</div>
+
+<h2 id="A_few_good_web_frameworks">A few good web frameworks?</h2>
+
+<p>Let's now move on, and discuss a few specific server-side web frameworks.</p>
+
+<p>The server-side frameworks below represent <em>a few </em>of the most popular available at the time of writing. All of them have everything you need to be productive — they are open source, are under active development, have enthusiastic communities creating documentation and helping users on discussion boards, and are used in large numbers of high-profile websites. There are many other great server-side frameworks that you can discover using a basic internet search.</p>
+
+<div class="note">
+<p><strong>Note</strong>: Descriptions come (partially) from the framework websites!</p>
+</div>
+
+<h3 id="Django_Python">Django (Python)</h3>
+
+<p><a href="https://www.djangoproject.com/">Django</a> is a high-level Python Web framework that encourages rapid development and clean, pragmatic design. Built by experienced developers, it takes care of much of the hassle of web development, so you can focus on writing your app without needing to reinvent the wheel. It’s free and open source.</p>
+
+<p>Django follows the "Batteries included" philosophy and provides almost everything most developers might want to do "out of the box". Because everything is included, it all works together, follows consistent design principles, and has extensive and up-to-date documentation. It is also fast, secure, and very scalable. Being based on Python, Django code is easy to read and to maintain.</p>
+
+<p>Popular sites using Django (from Django home page) include: Disqus, Instagram, Knight Foundation, MacArthur Foundation, Mozilla, National Geographic, Open Knowledge Foundation, Pinterest, Open Stack.</p>
+
+<h3 id="Flask_Python">Flask (Python)</h3>
+
+<p><a href="http://flask.pocoo.org/">Flask</a> is a microframework for Python.</p>
+
+<p>While minimalist, Flask can create serious websites out of the box. It contains a development server and debugger, and includes support for <a href="https://github.com/pallets/jinja">Jinja2</a> templating, secure cookies, <a href="https://en.wikipedia.org/wiki/Unit_testing">unit testing</a>, and <a href="http://www.restapitutorial.com/lessons/restfulresourcenaming.html">RESTful</a> request dispatching. It has good documentation and an active community.</p>
+
+<p>Flask has become extremely popular, particularly for developers who need to provide web services on small, resource-constrained systems (e.g. running a web server on a <a href="https://www.raspberrypi.org/">Raspberry Pi</a>, <a href="http://blogtarkin.com/drone-definitions-learning-the-drone-lingo/">Drone controllers</a>, etc.)</p>
+
+<h3 id="Express_Node.jsJavaScript">Express (Node.js/JavaScript)</h3>
+
+<p><a href="http://expressjs.com/">Express</a> is a fast, unopinionated, flexible and minimalist web framework for <a href="https://nodejs.org/en/">Node.js</a> (node is a browserless environment for running JavaScript). It provides a robust set of features for web and mobile applications and delivers useful HTTP utility methods and <a href="/en-US/docs/Glossary/Middleware">middleware</a>.</p>
+
+<p>Express is extremely popular, partially because it eases the migration of client-side JavaScript web programmers into server-side development, and partially because it is resource-efficient (the underlying node environment uses lightweight multitasking within a thread rather than spawning separate processes for every new web request).</p>
+
+<p>Because Express is a minimalist web framework it does not incorporate every component that you might want to use (for example, database access and support for users and sessions are provided through independent libraries). There are many excellent independent components, but sometimes it can be hard to work out which is the best for a particular purpose!</p>
+
+<p>Many popular server-side and full stack frameworks (comprising both server and client-side frameworks) are based on Express, including <a href="http://feathersjs.com/">Feathers</a>, <a href="https://www.itemsapi.com/">ItemsAPI</a>, <a href="http://keystonejs.com/">KeystoneJS</a>, <a href="http://krakenjs.com/">Kraken</a>, <a href="http://loopback.io/">LoopBack</a>, <a href="http://mean.io/">MEAN</a>, and <a href="http://sailsjs.org/">Sails</a>.</p>
+
+<p>A lot of high profile companies use Express, including: Uber, Accenture, IBM, etc. (a list is provided <a href="http://expressjs.com/en/resources/companies-using-express.html">here</a>).</p>
+
+<h3 id="Ruby_on_Rails_Ruby">Ruby on Rails (Ruby)</h3>
+
+<p><a href="http://rubyonrails.org/">Rails</a> (usually referred to as "Ruby on Rails") is a web framework written for the Ruby programming language.</p>
+
+<p>Rails follows a very similar design philosophy to Django. Like Django it provides standard mechanisms for routing URLs, accessing data from a database, generating HTML from templates and formatting data as {{glossary("JSON")}} or {{glossary("XML")}}. It similarly encourages the use of design patterns like DRY ("dont repeat yourself" — write code only once if at all possible), MVC (model-view-controller) and a number of others.</p>
+
+<p>There are of course many differences due to specific design decisions and the nature of the languages.</p>
+
+<p>Rails has been used for high profile sites, including:<strong> </strong><a href="https://basecamp.com/">Basecamp</a>, <a href="https://github.com/">GitHub</a>, <a href="https://shopify.com/">Shopify</a>, <a href="https://airbnb.com/">Airbnb</a>, <a href="https://twitch.tv/">Twitch</a>, <a href="https://soundcloud.com/">SoundCloud</a>, <a href="https://hulu.com/">Hulu</a>, <a href="https://zendesk.com/">Zendesk</a>, <a href="https://square.com/">Square</a>, <a href="https://highrisehq.com/">Highrise</a>.</p>
+
+<h3 id="Laravel_PHP">Laravel (PHP)</h3>
+
+<p><a href="https://laravel.com/">Laravel</a> is a web application framework with expressive, elegant syntax. Laravel attempts to take the pain out of development by easing common tasks used in the majority of web projects, such as:</p>
+
+<ul>
+ <li><a href="https://laravel.com/docs/routing" rel="nofollow">Simple, fast routing engine</a>.</li>
+ <li><a href="https://laravel.com/docs/container" rel="nofollow">Powerful dependency injection container</a>.</li>
+ <li>Multiple back-ends for <a href="https://laravel.com/docs/session" rel="nofollow">session</a> and <a href="https://laravel.com/docs/cache" rel="nofollow">cache</a> storage.</li>
+ <li>Expressive, intuitive <a href="https://laravel.com/docs/eloquent" rel="nofollow">database ORM</a>.</li>
+ <li>Database agnostic <a href="https://laravel.com/docs/migrations" rel="nofollow">schema migrations</a>.</li>
+ <li><a href="https://laravel.com/docs/queues" rel="nofollow">Robust background job processing</a>.</li>
+ <li><a href="https://laravel.com/docs/broadcasting" rel="nofollow">Real-time event broadcasting</a>.</li>
+</ul>
+
+<p>Laravel is accessible, yet powerful, providing tools needed for large, robust applications.</p>
+
+<h3 id="ASP.NET">ASP.NET</h3>
+
+<p><a href="http://www.asp.net/">ASP.NET</a> is an open source web framework developed by Microsoft for building modern web applications and services. With ASP.NET you can quickly create web sites based on HTML, CSS, and JavaScript, scale them for use by millions of users and easily add more complex capabilities like Web APIs, forms over data, or real time communications.</p>
+
+<p>One of the differentiators for ASP.NET is that it is built on the <a href="https://en.wikipedia.org/wiki/Common_Language_Runtime">Common Language Runtime</a> (CLR), allowing programmers to write ASP.NET code using any supported .NET language (C#, Visual Basic, etc.). Like many Microsoft products it benefits from excellent tools (often free), an active developer community, and well-written documentation.</p>
+
+<p>ASP.NET is used by Microsoft, Xbox.com, Stack Overflow, and many others.</p>
+
+<h3 id="Mojolicious_Perl">Mojolicious (Perl)</h3>
+
+<p><a href="http://mojolicious.org/">Mojolicious</a> is a next generation web framework for the Perl programming language.</p>
+
+<p>Back in the early days of the web, many people learned Perl because of a wonderful Perl library called <a href="https://metacpan.org/module/CGI">CGI</a>. It was simple enough to get started without knowing much about the language and powerful enough to keep you going. Mojolicious implements this idea using bleeding edge technologies.</p>
+
+<p>Some of the features provided by Mojolicious are: <strong>Real-time web framework</strong>, to easily grow single file prototypes into well-structured MVC web applications; RESTful routes, plugins, commands, Perl-ish templates, content negotiation, session management, form validation, testing framework, static file server, CGI/<a href="http://plackperl.org">PSGI</a> detection, first class Unicode support; Full stack HTTP and WebSocket client/server implementation with IPv6, TLS, SNI, IDNA, HTTP/SOCKS5 proxy, UNIX domain socket, Comet (long polling), keep-alive, connection pooling, timeout, cookie, multipart and gzip compression support; JSON and HTML/XML parsers and generators with CSS selector support; Very clean, portable and object-oriented pure-Perl API with no hidden magic; Fresh code based upon years of experience, free and open source.</p>
+
+<h2 id="Summary">Summary</h2>
+
+<p>This article has shown that web frameworks can make it easier to develop and maintain server-side code. It has also provided a high level overview of a few popular frameworks, and discussed criteria for choosing a web application framework. You should now have at least an idea of how to choose a web framework for your own server-side development. If not, then don't worry — later on in the course we'll give you detailed tutorials on Django and Express to give you some experience of actually working with a web framework.</p>
+
+<p>For the next article in this module we'll change direction slightly and consider web security.</p>
+
+<p>{{PreviousMenuNext("Learn/Server-side/First_steps/Client-Server_overview", "Learn/Server-side/First_steps/Website_security", "Learn/Server-side/First_steps")}}</p>
+
+<h2 id="In_this_module">In this module</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/Server-side/First_steps/Introduction">Introduction to the server side</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/First_steps/Client-Server_overview">Client-Server overview</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/First_steps/Web_frameworks">Server-side web frameworks</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/First_steps/Website_security">Website security</a></li>
+</ul>
diff --git a/files/fr/learn/server-side/premiers_pas/website_security/index.html b/files/fr/learn/server-side/premiers_pas/website_security/index.html
new file mode 100644
index 0000000000..bc47ab4042
--- /dev/null
+++ b/files/fr/learn/server-side/premiers_pas/website_security/index.html
@@ -0,0 +1,162 @@
+---
+title: La sécurité d'un site Web
+slug: Learn/Server-side/Premiers_pas/Website_security
+tags:
+ - Débutant
+ - Guide
+ - Sécurité
+ - Sécurité Web
+translation_of: Learn/Server-side/First_steps/Website_security
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenu("Learn/Server-side/First_steps/Web_frameworks", "Learn/Server-side/Premiers_pas")}}</div>
+
+<p class="summary">La sécurité d'un site web exige de la vigilance dans tous les aspects de sa conception et de son utilisation. Cet article d'introduction ne fera pas de vous un gourou de la sécurité des sites web, mais il vous aidera à comprendre d'où viennent les menaces et ce que vous pouvez faire pour renforcer votre application web contre les attaques les plus courantes.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Pré-requis :</th>
+ <td>Connaissances de base en informatique.</td>
+ </tr>
+ <tr>
+ <th scope="row">Objectif :</th>
+ <td>Comprendre les menaces les plus courantes à la sécurité des applications web et ce que vous pouvez faire pour réduire le risque de piratage de votre site.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Quest-ce_que_la_sécurité_dun_site_web">Qu'est-ce que la sécurité d'un site web?</h2>
+
+<p>Internet est un endroit dangereux ! Fréquemment, nous entendons parler de sites web devenus indisponibles en raison d'attaques par déni de service, ou affichant des informations modifiées (et souvent préjudiciables) sur leurs pages d'accueil. Dans d'autres cas, très médiatisés, des millions de mots de passe, d'adresses électroniques et de détails sur des cartes de crédit sont divulgués au public, exposant les utilisateurs du site web à la fois à l'embarras personnel et au risque de pertes financières.</p>
+
+<p>L'objectif de la sécurité des sites web est de prévenir ces types d'attaques. Plus formellement, la sécurité des sites web est l'acte de protéger les sites web contre l'accès, l'utilisation, la modification, la destruction ou la perturbation non autorisées.</p>
+
+<p>La sécurité efficace d'un site web nécessite un effort de conception sur l'ensemble du site : dans votre application web, dans la configuration du serveur web, dans vos politiques de création et de renouvellement des mots de passe et dans le code côté-client. Bien que tout cela semble très inquiétant, la bonne nouvelle est que si vous utilisez un framework web côté serveur, il incluera certainement par défaut des mécanismes de défense solides et bien pensés contre un certain nombre des attaques les plus courantes. D'autres attaques peuvent être atténuées grâce à la configuration de votre serveur web, par exemple en activant HTTPS. Enfin, les outils d'analyse de vulnérabilité accessibles au public peuvent vous aider à découvrir d'éventuelles erreurs dans votre conception.</p>
+
+<p>Le reste de cet article détaille les menaces les plus courantes qui pèsent sur les sites web et quelques étapes simples pour protèger votre site.</p>
+
+<div class="note">
+<p><strong>Note </strong>: ceci est un article d'introduction, conçu pour vous aider à réflechir à la sécurité de votre site web. Il n'est en rien exhaustif.</p>
+</div>
+
+<h2 id="Menaces_visant_la_sécurité_des_sites_web">Menaces visant la sécurité des sites web</h2>
+
+<p>Cette section n'énumère que quelques-unes des menaces les plus courantes visant les sites web et la façon dont elles sont tenues à distance. À mesure que vous lisez, notez comment les menaces apparaissent lorsque l'application web fait confiance ou n'est pas assez méfiante vis-à-vis des données provenant du navigateur !</p>
+
+<h3 id="Cross-Site_Scripting_XSS">Cross-Site Scripting (XSS)</h3>
+
+<p>XSS est un terme utilisé pour décrire une classe d'attaque qui permet à l'attaquant d'injecter des scripts, exécutés côté-client, <em>au travers</em> du site web pour viser le navigateur web des autres utilisateurs. Comme le code injecté provient du site web le navigateur web le considère comme sûr, il peut de ce fait faire des choses comme transmettre le cookie d'authentification de l'utilisateur à l'attaquant. Une fois que l'attaquant obtient ce cookie il peut se connecter sur le site comme si il était l'utilisateur attaqué et peut faire tout ce que l'utilisateur pourrait faire. En fonction du site sur lequel l'attaque se produit, cela peut inclure l'accès aux détails de carte bancaire, les informations des contacts, la modification du mot de passe, etc.</p>
+
+<div class="note">
+<p><strong>Note </strong>: les vulnérabilités XSS ont historiquement été les plus courantes.</p>
+</div>
+
+<p>Il y a deux manières principales pour demander au site de retourner un script injecté vers un navigateur web — elles sont désignées en tant que vulnérabilités XSS <em>réfléchie</em> et <em>persistante</em>.</p>
+
+<ul>
+ <li>Une vulnérabilité XSS  réfléchie se produit quand le contenu de l'utilisateur transmis au serveur est immédiatement retourné, sans avoir été modifié, pour être affiché dans le navigateur — tout les scripts présents dans le contenu d'origine seront exécutés quand la nouvelle page sera chargée!<br>
+ On prendra par exemple une fonction de recherche dans un site où les termes recherchés sont encodés en tant que paramètres dans l'URL, et que ces termes sont affichés en permanence avec les résultats. Un attaquant peut construire un lien de recherche contenant un script malicieux en tant que paramètre (ex: <code>http://mysite.com?q=beer&lt;script%20src="http://sitedangereux.com/malicieux.js"&gt;&lt;/script&gt;</code>) et le transmettre par e-mail à un autre utilisateur. Si l'utilisateur ciblé clique sur ce "lien intéressant", le script sera exécuté quand les résultats de la recherche seront affichés. Comme vu auparavant, cela donne à l'attaquant toute les informations dont il a besoin pour se connecter sur le site avec le compte de la victime — potentiellement faire des achats en tant que cet utilisateur ou accèder à la liste de contacts..</li>
+ <li>Une vulnérabilité XSS <em>persistante</em> sera celle où le script malicieux est stocké sur le site web puis affiché, sans modification, un peu plus tard par les autres utilisateurs et exécuté à leur insu.<br>
+ Par exemple, un écran de discussion qui accepte les commentaires contenant du code HTML pur peuvent stocker le script malicieux de l'attaquant. Quand les commentaires sont affichés le script est exécuté et peut ensuite transmettre à l'attaquant les informations nécessaires pour accèder au compte de l'utilisateur. Cette méthode d'attaque est extrêmement courante et efficace, parce que l'attaquant n'a pas besoin d'avoir une relation directe avec les victimes.<br>
+ <br>
+ Alors que l'envoi de données avec <code>POST</code> ou <code>GET</code> est la source la plus commune de vulnérabilité XSS, toute donnée en provenance du navigateur web est potentiellement vulnérable (cela inclut l'affichage des données des cookies par le navigateur, ou les fichiers de l'utilisateur qui sont chargés et affichés).</li>
+</ul>
+
+<p>La meilleur défense contre les vulnérabilités XSS est de supprimer ou désactiver toutes les balises qui peuvent potentiellement contenir des instructions pour exécuter du code. Pour HTML cela inclut les tags comme <code>&lt;script&gt;</code>, <code>&lt;object&gt;</code>, <code>&lt;embed&gt;</code>, et <code>&lt;link&gt;</code>.</p>
+
+<div>
+<p>Il est nécessaire de traiter les données saisies par l'utilisateur pour être sûr qu'il ne puisse ni exécuter de scripts ni pertuber le fonctionnement normal du site (ce procédé est appelé <em>input sanitization</em> en anglais). De nombreux frameworks proposent par défaut cette vérification sur les entrées des formulaires.</p>
+</div>
+
+<h3 id="Injection_SQL">Injection SQL</h3>
+
+<p>L'injection SQL est une vulnérabilité qui permet à un attaquant d'exécuter du code SQL frauduleux sur une base de données, permettant l'accès, la modification ou la suppression des données quelque soit le droit de l'utilisateur. Une attaque par injection réussie peut permettre l'usurpation d'un compte, la création d'un compte avec les droits administrateur, l'accès à toute les données du serveur, ou la modification / destruction des données pour le rendre inutilisable.</p>
+
+<p>Cette vulnérabilité est présente quand la saisie de l'utilisateur est transmise à une requête SQL sous-jacente qui peut modifier le sens de la requête. Par exemple, dans le code ci-dessous qui devrait lister l'ensemble des utilisateurs avec un nom particulier (<code>userName</code>) et qui provient d'un formulaire HTML:</p>
+
+<pre class="brush: sql">statement = "SELECT * FROM users WHERE name = '" + <strong>userName</strong> + "';"</pre>
+
+<p>Si l'utilisateur entre un nom correct cela marchera comme voulu. Cependant un utilisateur malveillant peut changer complètement le sens de cette requête SQL pour obtenir la requête qui suit, simplement en ajoutant le texte, <strong>en gras</strong> ci dessous, en tant que nom, cette requête, modifiée, va créer une requête SQL valide qui va supprimer la table <code>users</code> et sélectionner toute les données de la table <code>userinfo</code> (révèlant les informations de chaque utilisateur). Tout cela est rendu possible à cause du début du texte injecté  (<code>'a';</code>) qui va complèter la requête d'origine (<code>' </code>est le symbole pour délimiter une chaine de texte en SQL).</p>
+
+<pre class="brush: sql">SELECT * FROM users WHERE name = '<strong>a';DROP TABLE users; SELECT * FROM userinfo WHERE 't' = 't</strong>';
+</pre>
+
+<p>Le moyen pour éviter ce type d'attaque est de s'assurer que toute saisie de l'utilisateur transmise à une requête SQL ne peut pas changer la nature de cette requête. Un moyen de faire cela est d'<a href="https://fr.wikipedia.org/wiki/Caract%C3%A8re_d%27%C3%A9chappement">échapper</a> tous les caractères de la saisie utilisateur quand ils ont un sens particulier en SQL.</p>
+
+<div class="note">
+<p><strong>Note </strong>: la requête SQL considère le symbole ' comme le début et la fin d'une chaine de texte. En ajoutant le caractère \ nous allons "échapper" ce symbole, et dire à SQL de le traiter comme une simple partie de la chaîne de caractères.</p>
+</div>
+
+<p>Dans la requête ci-dessous nous avons échappé le caractère '. Le SQL va donc interpréter la chaine complète (en gras) comme un nom (un nom étrange en effet, mais pas nuisible).</p>
+
+<pre class="brush: sql">SELECT * FROM users WHERE name = '<strong>a\';DROP TABLE users; SELECT * FROM userinfo WHERE \'t\' = \'t'</strong>;
+
+</pre>
+
+<p>Les frameworks web se chargent bien souvent d'échapper ces caractères à votre place. Django, par exemple, s'assure que toute saisie d'un utilisateur transmise au modèle est bien échappée.</p>
+
+<div class="note">
+<p><strong>Note</strong>: Cette section s'inspire beaucoup des informations de <a href="https://en.wikipedia.org/wiki/SQL_injection">Wikipedia ici</a>.</p>
+</div>
+
+<h3 id="Falsification_de_requête_inter-sites_CSRF">Falsification de requête inter-sites (CSRF)</h3>
+
+<p>Les attaques CSRF permettent à un utilisateur malveillant d'éxécuter des actions à l'a ide des identifiants d'un autre utilisateur sans que cet utilisateur ne soit informé ou consentant.</p>
+
+<p>Ce type d'attaque s'explique mieux avec un exemple. John est l'utilisateur malveillant qui sait qu'un site particulier permet à des utilisateurs authentifiés d'envoyer de l'argent vers un compte particulier en utilisant des requêtes HTTP POST qui incluent le numéro de compte et le montant. John construit un formulaire qui inclut son numéro de compte et un montant dans des champs cachés (invisibles) et le transmet à un autre utilisateur du site (avec le bouton de validation déguisé en un lien vers un site "pour devenir riche".</p>
+
+<p>Si un utilisateur clique sur le bouton de validation, une requête HTTP POST, contenant les informations de transaction, va être transmise au serveur ainsi que le cookie que le navigateur web associe au site (l'ajout à la requête du cookie associé au site est le comportement normal du navigateur). Le serveur va vérifier le cookie d'authentification, et l'utiliser pour déterminer si l'utilisateur est ou n'est pas connecté et donc permet ou non la transaction.</p>
+
+<p>Au final tout utilisateur qui va cliquer sur le bouton de validation, alors qu'il sera connecté sur le site d'échange d'argent, va autoriser la transaction. John va devenir riche !</p>
+
+<div class="note">
+<p><strong>Note </strong>: l'astuce ici est que John n'a pas besoin d'accéder aux cookies de l'utilisateur (ou à ses identifiants), le navigateur web stocke cette information et l'inclut automatiquement dans toute les requêtes destinées au serveur associé.</p>
+</div>
+
+<p>Un moyen de prévenir ce type d'attaque est que le serveur demande que chaque requête POST possède un secret généré par le serveur et spécifique à l'utilisateur (le secret serait transmis par le serveur lors de l'envoi du formulaire de transaction). Cette approche empêche John de créer son propre formulaire car il n'est pas capable de connaitre le secret que le serveur founit à l'utilisateur. Même si il venait à trouver ce secret et créer un formulaire pour un utilisateur particulier, il ne pourrait pas utiliser ce formulaire pour attaquer d'autres utilisateurs</p>
+
+<p>Les framework web incluent souvent des mécanismes afin de prévenir les attaques CSRF.</p>
+
+<h3 id="Autre_menaces">Autre menaces</h3>
+
+<p>Les autres attaques et vulnérabilités courantes incluent:</p>
+
+<ul>
+ <li><a href="https://www.owasp.org/index.php/Clickjacking">Clickjacking</a>. Dans cette attaque un utilisateur malveillant détourne les clics destinés à un site visible et les envoie dans une page cachée en dessous. Cette technique peut être utilisée, par exemple, pour afficher le site légitime d'une banque mais capturer les identifiants d'authentification dans une &lt;iframe&gt; invisible controlée par l'attaquant. Sinon cela peut être utilisé pour obtenir de l'utilisateur qu'il clique sur le bouton visible d'un site, mais en le faisant il va en fait cliquer involontairement sur un bouton différent. Comme défense, votre site peut se prévenir d'être inclut dans une iframe d'un autre site en configurant les bonnes en-têtes HTTP.</li>
+ <li><a href="/fr/docs/Glossaire/Déni_de_service_distribué">Déni de Service</a> (DoS). Le déni de service est souvent pratiqué en surchargeant de fausses requêtes un site cible avec afin que l'accès au site soit perturbé pour les usagers légitimes. Les requêtes peuvent simplement être nombreuses, ou elles peuvent individuellement nécessiter une grande quantité de ressource (ex: chargement de fichiers lourds, etc). La défense contre cette attaque se base souvent sur l'identification et le blocage du mauvais trafic tout en autorisant l'arrivée des messages légitimes. Ces défenses sont généralement intégrées ou en amont du serveur web (elle ne font pas partie de l'application web).</li>
+ <li><a href="https://en.wikipedia.org/wiki/Directory_traversal_attack">Découverte via la navigation dans les répertoires et fichiers</a>. Dans cette famille d'attaque un utilisateur malveillant va tenter d'accèder aux fichiers du serveur web auxquels il ne devrait pas avoir accès. Cette vulnérabilité se produit quand l'utilisateur peut transmettre le nom d'un fichier qui comprend les caractères de navigation dans le système de fichier (par exemple: <code>../../</code>). La solution est de désinfecter la saisie avant de l'utiliser.</li>
+ <li><a href="https://fr.wikipedia.org/wiki/Remote_File_Inclusion">Inclusion de fichiers</a>. Dans cette attaque un utilisateur est capable de spécifier un fichier "involontaire" pour être affiché ou exécuté dans les données transmises au serveur. Une fois chargé ce fichier peut être exécuté sur le serveur web ou du côté client (menant à une attaque XSS). La solution est de vérifier les saisies avant de les utiliser.</li>
+ <li><a href="https://www.owasp.org/index.php/Command_Injection">Injection de commandes</a>. Les attaques par injection de commande permettent à un utilisateur malveillant d'exécuter des commandes systèmes frauduleuses sur le système hôte. La solution est de vérifier chaque saisie des utilisateurs avant de les utiliser dans les appels systèmes.</li>
+</ul>
+
+<p>Il y en a beaucoup d'autres. Pour une liste plus exhaustive vous pouvez consulter la catégorie <a href="https://en.wikipedia.org/wiki/Category:Web_security_exploits">failles de sécurité Web</a> (Wikipedia) et <a href="https://www.owasp.org/index.php/Category:Attack">la catégorie Attaques</a> (du projet OWASP).</p>
+
+<h2 id="Quelques_messages_clés">Quelques messages clés</h2>
+
+<p>La majorité des attaques citées précédement réusissent lorsque l'application web fait confiance aux données provenant du navigateur web. Quoique vous fassiez d'autre pour améliorer la sécurité de votre site web, vous devez désinfecter toutes les saisies des utilisateurs avant de les afficher, de les utiliser dans les requêtes SQL ou de les transmettre dans les appels du système ou du système de fichier.</p>
+
+<div class="warning">
+<p><strong>Important</strong> : la leçon la plus importante à retenir concernant la sécurité d'un site web est de ne <strong>jamais faire confiance aux données du navigateur web</strong>. Cela comprend les requêtes <code>GET</code> avec la présence des paramètres dans l'URL, les données envoyées avec les <code>POST</code>, les en-têtes HTTP, les cookies, les fichiers chargés par l'utilisateur, etc. Il faut toujours vérifier et assainir les données. Il faut toujours s'attendre au pire.</p>
+</div>
+
+<p>Quelques autres points que vous pouvez mettre en place :</p>
+
+<ul>
+ <li>Utilisez une politique de gestion des mots de passe efficace. Encouragez les mots de passe solides avec leur renouvellement fréquent. Prenez en compte une authentification à deux facteurs sur votre site (l'utilisateur, en plus du mot de passe, devra fournir un autre code d'authentification généralement fourni par un matériel physique, que seul l'utilisateur possède, comme un code envoyé sur le téléphone par SMS).</li>
+ <li>Configurez vos serveurs web pour utiliser <a href="/en-US/docs/Glossary/https">HTTPS</a> et <a href="/en-US/docs/Web/Security/HTTP_strict_transport_security">HTTP Strict Transport Security</a> (HSTS). HTTPS chiffre les données transmises entre le client et le serveur. Cela garantit que les données d'authentification, les cookies, les données transistant avec <code>POST</code> et les informations d'en-têtes deviennent moins disponibles pour l'attaquant.</li>
+ <li>Tenez vous informé des dernières menaces (<a href="/en-US/docs/">la liste actuelle d'OWASP est ici</a>) et préoccupez vous toujours des vulnerabilités les plus courantes en premier.</li>
+ <li>Utilisez <a href="https://www.owasp.org/index.php/Category:Vulnerability_Scanning_Tools">des outils de recherche de vulnérabilités </a> pour faire automatiquement des recherches de bug sur votre site (votre site pourra également proposer un programme de <em>buf bounty </em>pour déceler des bugs, <a href="https://www.mozilla.org/en-US/security/bug-bounty/faq-webapp/">comme le fait Mozilla ici</a>).</li>
+ <li>Ne stockez et n'affichez que les données nécessaires. Par exemple, si votre utilisateur doit stocker des données sensibles comme des informations bancaires, affichez seulement ce qui sera suffisant pour être identifié par l'utilisateur, mais pas suffisament pour être copié par un attaquant et être utilisé sur un autre site. La méthode la plus courante en ce moment est de n'afficher que les quatre derniers chiffres du numéro de carte bancaire.</li>
+</ul>
+
+<p>Les frameworks web peuvent aider à atténuer beaucoup des vulnérabilités les plus courantes.</p>
+
+<h2 id="Résumé">Résumé</h2>
+
+<p>Cet article a présenté le concept de sécurité web et quelques-unes des menaces courantes vis-à-vis desquelles il faut se protéger. Le plus important à comprendre est qu'une application web ne peut pas faire confiance aux données provenant du navigateur ! Les données des utilisateurs doivent toutes être nettoyées avant d'être affichées ou utilisées dans les requêtes SQL ou dans les appels systèmes.</p>
+
+<p>C'est la fin de <a href="/fr/docs/Learn/Server-side/First_steps">ce module</a>, couvrant vos premiers pas dans le développement d'un site web côté serveur. Nous espérons que vous avez apprécié apprendre les concepts fondamentaux. Vous êtes désormais apte à choisir un framework web et à commencer à programmer.</p>
+
+<p>{{PreviousMenu("Learn/Server-side/First_steps/Web_frameworks", "Learn/Server-side/First_steps")}}</p>
diff --git a/files/fr/learn/tools_and_testing/client-side_javascript_frameworks/index.html b/files/fr/learn/tools_and_testing/client-side_javascript_frameworks/index.html
new file mode 100644
index 0000000000..b905f66546
--- /dev/null
+++ b/files/fr/learn/tools_and_testing/client-side_javascript_frameworks/index.html
@@ -0,0 +1,175 @@
+---
+title: Understanding client-side JavaScript frameworks
+slug: Learn/Tools_and_testing/Client-side_JavaScript_frameworks
+tags:
+ - Beginner
+ - Frameworks
+ - JavaScript
+ - Learn
+ - TopicStub
+ - client-side
+translation_of: Learn/Tools_and_testing/Client-side_JavaScript_frameworks
+---
+<div>{{LearnSidebar}}</div>
+
+<p class="summary">Les frameworks JavaScript sont une partie essentielle du développement web front-end moderne, fournissant aux développeurs des outils éprouvés pour construire des applications web évolutives et interactives. De nombreuses entreprises modernes utilisent des frameworks comme un élément normé de leur outillage, de sorte que de nombreux emplois de développement front-end requièrent désormais une expérience avec ces frameworks.</p>
+
+<p class="summary">En tant que futur développeur front-end, il peut être difficile de savoir par où commencer lors de l'apprentissage des frameworks – il y a tant de frameworks si différents les uns des autres et de nouveaux qui apparaissent sans cesse, ils fonctionnent généralement de manière similaire mais font certaines choses différemment, et il y a certaines choses spécifiques à avoir en tête lors de leur utilisation.</p>
+
+<p class="summary"><span class="tlid-translation translation" lang="fr"><span title="">Dans cet ensemble d'articles, nous chercherons à vous donner un point de départ confortable pour vous aider à commencer votre apprentissage </span></span>des frameworks. <span class="tlid-translation translation" lang="fr"><span title="">Nous ne visons pas à vous enseigner exhaustivement tout ce que vous devez savoir sur React / ReactDOM, Vue ou quelque autre framework particulier</span></span> ; <span class="tlid-translation translation" lang="fr"><span title="">les documentations fournises par les équipes de développement des frameworks font déjà ce travail.</span> N<span title="">ous souhaitons plutôt faire simple et répondre d'abord à des questions plus fondamentales telles que </span></span>:</p>
+
+<ul>
+ <li class="summary">Pourquoi devrais-je utiliser un framework ? Quels problèmes résolvent-ils pour moi ?</li>
+ <li class="summary">Quelles questions devrais-je me poser pour choisir un framework ? Ai-je au moins besoin d'un framework ?</li>
+ <li class="summary">Quelles fonctionnalités proposent les frameworks ? Comment fonctionnent-ils en général et comment diffèrent leurs  implantations de ces fonctionnalités ?</li>
+ <li class="summary">Comment se rapportent-ils au JavaScript "vanilla" ou à l'HTML ?</li>
+</ul>
+
+<p class="summary">Après ceci, nous vous fournirons quelques tutoriels couvrant les notions fondamentales de certains des principaux frameworks afin de vous fournir suffisamment de contexte et de familiarité pour commencer à approfondir par vous-même. Nous voulons que vous puissiez progresser et en apprendre plus sur les frameworks de manière pragmatique sans oublier les bonnes pratiques fondamentales du web telles que l'accessibilité.</p>
+
+<p class="summary"><strong><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Introduction">Commencez dès maintenant, avec "Introduction aux frameworks côté client"</a></strong></p>
+
+<h2 id="Prérequis">Prérequis</h2>
+
+<p>Vous devez vraiment connaitre les bases des principaux langages du web (<a href="/en-US/docs/Learn/HTML">HTML</a>, <a href="/en-US/docs/Learn/CSS">CSS</a>, et particulièrement <a href="/en-US/docs/Learn/JavaScript">JavaScript</a>) avant d'essayer de vous lancer dans l'apprentissage des frameworks côté client.</p>
+
+<p>Votre code n'en sera que plus qualitatif et plus professionnel, et vous serez en mesure de résoudre vos problèmes avec plus de confiance si vous comprenez les fonctionnalités fondamentales du web sur lesquelles les frameworks s'appuient.</p>
+
+<h3 id="Vous_voulez_devenir_développeur_web_front-end">Vous voulez devenir développeur web front-end ?</h3>
+
+<p>Nous avons créé un cours qui inclut toutes les informations essentielles dont vous avez besoin pour atteindre votre objectif.</p>
+
+<p><a class="cta primary" href="/docs/Learn/Front-end_web_developer">Commencer</a></p>
+
+<h2 id="Guides_dintroduction">Guides d'introduction</h2>
+
+<dl>
+ <dt><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Introduction">1. Introduction aux frameworks côté client</a></dt>
+ <dd>Nous commençons notre aperçu des frameworks par un tour d'horizon général du domaine, notamment en regardant un bref historique de JavaScript et des frameworks, la raison pour laquelle les frameworks existent et ce qu'ils nous proposent, comment commencer à réfléchir au choix d'un framework à apprendre et quelles alternatives il y a aux frameworks côté client.</dd>
+ <dt><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Main_features">2. Principales caractéristiques du Framework</a></dt>
+ <dd>Chaque framework JavaScript majeur a une approche différente de la mise à jour du DOM, de la gestion des évènements du navigateur et de la manière dont rendre l'expérience de développement agréable. Cet article explorera les principales caractéristiques des 4 grands frameworks, <span class="tlid-translation translation" lang="fr"><span title="">en examinant comment les frameworks ont tendance à fonctionner à un haut niveau et les différences entre eux.</span></span></dd>
+</dl>
+
+<h2 id="Tutoriels_sur_React">Tutoriels sur React</h2>
+
+<div class="blockIndicator note">
+<p><strong>Note</strong>: Les tutoriels sur React ont été essayés pour la dernière fois en mai 2020, avec React/ReactDOM 16.13.1 et create-react-app 3.4.1.</p>
+
+<p>Si vous avez besoin de vérifier votre code par rapport à notre version, vous pouvez trouver une version finale de l'exemple de code d'application React dans notre <a href="https://github.com/mdn/todo-react">todo-react repository</a>. Pour une version exécutable en direct, voir <a href="https://mdn.github.io/todo-react-build/">https://mdn.github.io/todo-react-build/</a>.</p>
+</div>
+
+<dl>
+ <dt><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_getting_started">1. Premier pas avec React</a></dt>
+ <dd>Dans cet article, nous dirons bonjour à React. Nous découvrirons les prémices de son fonctionnement et de ses cas d'utilisation, configurerons une chaine d'outils React de base sur notre ordinateur local et créerons et jouerons avec une application de démarrage simple, en apprenant un peu plus sur le fonctionnement de React dans le processus.</dd>
+ <dt><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_todo_list_beginning">2. Début de notre liste de tâches React</a></dt>
+ <dd>Supposons que nous ayons été chargés de créer une preuve de concept dans React – une application qui permet aux utilisateurs d'ajouter, de modifier et de supprimer les tâches sur lesquelles ils souhaitent travailler, ainsi que de marquer les tâches comme terminées sans les supprimer. Cet article vous guidera tout au long de la mise en place de la structure et du style des composants de base de l'application, prêts pour la définition et l'interactivité des composants individuels, que nous ajouterons plus tard.</dd>
+ <dt><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_components">3. Diviser notre application React en composants</a></dt>
+ <dd>À ce stade, notre application est un monolithe. Avant de pouvoir lui faire faire des choses, nous devons le diviser en composants descriptifs gérables. React n'a pas de règles strictes pour ce qui est et n'est pas un composant - c'est à vous de décider ! Dans cet article, nous allons vous montrer un moyen judicieux de diviser notre application en composants.</dd>
+ <dt><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_interactivity_events_state">4. Interactivité de React: évènements et états</a></dt>
+ <dd>Une fois notre plan de composants élaboré, il est maintenant temps de commencer à faire évoluer notre application d'une interface utilisateur complètement statique vers une interface qui nous permet réellement d'interagir et de modifier des choses. Dans cet article, nous allons le faire, en explorant les évènements et les états en cours de route.</dd>
+ <dt><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_interactivity_filtering_conditional_rendering">5. Interactivité de React: modification, filtrage, rendu conditionné</a></dt>
+ <dd>Alors que nous approchons de la fin de notre voyage React (pour l'instant du moins), <span class="tlid-translation translation" lang="fr"><span title="">nous ajouterons la touche finale aux principaux domaines de fonctionnalités de notre application de liste de tâches</span></span>. Cela comprend la possibilité de modifier les tâches existantes et de filtrer la liste des tâches entre toutes les tâches, terminées et incomplètes. Nous examinerons le rendu conditionné de l'interface utilisateur en cours de route.</dd>
+ <dt><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_accessibility">6. Accessibilité dans React</a></dt>
+ <dd>Dans notre avant-dernier article du tutoriel, nous nous concentrerons sur l'accessibilité, y compris la gestion de la mise au point dans React, ce qui peut améliorer la convivialité et réduire la confusion pour les utilisateurs de clavier uniquement et de lecteur d'écran.</dd>
+ <dt><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_resources">7. Ressources sur React</a></dt>
+ <dd>Notre dernier article vous fournit une liste de ressources sur React que vous pouvez utiliser pour aller plus loin dans votre apprentissage.</dd>
+</dl>
+
+<h2 id="Tutoriels_sur_Ember">Tutoriels sur Ember</h2>
+
+<div class="blockIndicator note">
+<p><strong>Note</strong>: Les tutoriels Ember ont été essayés pour la dernière fois en Mai 2020, avec Ember/Ember CLI version 3.18.0.</p>
+
+<p>Si vous avez besoin de vérifier votre code par rapport à notre version, vous pouvez trouver une version finale de l'exemple de code d'application Ember dans le Ember app code in the <a href="https://github.com/NullVoxPopuli/ember-todomvc-tutorial/tree/master/steps/00-finished-todomvc/todomvc">ember-todomvc-tutorial repository</a>. Pour une version exécutable en direct, voir <a href="https://nullvoxpopuli.github.io/ember-todomvc-tutorial/">https://nullvoxpopuli.github.io/ember-todomvc-tutorial/</a> (cela inclut également quelques fonctionnalités supplémentaires non couvertes dans le tutoriel).</p>
+</div>
+
+<dl>
+ <dt><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_getting_started">1. Premiers pas avec Ember</a></dt>
+ <dd>Dans notre premier article sur Ember, nous verrons comment fonctionne Ember et ce à quoi il sert, installerons la chaine d'outils d'Ember localement, créerons un exemple d'application, puis effectuerons une configuration initiale pour la préparer au développement.</dd>
+ <dt><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_structure_componentization">2. Structure et composant de l'application Ember</a></dt>
+ <dd>Dans cet article, nous commencerons à planifier la structure de notre application TodoMVC Ember, à ajouter du code HTML correspondant, puis nous diviserons cette structure HTML en composants.</dd>
+ <dt><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_interactivity_events_state">3. Interactivité Ember : évènements, classes et états</a></dt>
+ <dd>À ce stade, nous allons commencer à ajouter de l'interactivité à notre application, offrant la possibilité d'ajouter et d'afficher de nouveaux éléments à notre liste. En cours de route, nous examinerons l'utilisation d'évènements dans Ember, la création de classes de composants pour contenir du code JavaScript pour contrôler les fonctionnalités interactives et la configuration d'un service pour suivre l'état des données de notre application.</dd>
+ <dt><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_conditional_footer">4. Interactivité Ember : fonctionnalité du Footer, rendu conditionné</a></dt>
+ <dd>Il est maintenant temps de commencer à aborder la fonctionnalité de footer dans notre application. Ici, nous allons mettre à jour le compteur de tâches pour afficher le nombre correct de tâches à compléter et appliquer correctement le style aux tâches terminées (c'est-à-dire là dont la case a été cochée). Nous allons également câbler notre bouton "Effacer terminé". En cours de route, nous découvrirons comment utiliser le rendu conditionné dans nos modèles.</dd>
+ <dt><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_routing">5. Routage dans Ember</a></dt>
+ <dd>Dans cet article, nous apprendrons les bases du routage avec Ember. Nous l'utiliserons pour fournir une URL unique pour chacune des trois vues à faire : "Tous", "Actif", et "Terminé".</dd>
+ <dt><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_resources">6. Ressources sur Ember et dépannage</a></dt>
+ <dd>Notre dernier article sur Ember vous fournit une liste de ressources que vous pouvez utiliser pour aller plus loin dans votre apprentissage, ainsi que des dépannages utiles et d'autres informations.</dd>
+</dl>
+
+<h2 id="Tutoriels_sur_Vue">Tutoriels sur Vue</h2>
+
+<div class="blockIndicator note">
+<p><strong>Note</strong>: Les tutoriels sur Vue ont été essayés pour la dernière fois en mai 2020, avec Vue 2.6.11.</p>
+
+<p>Si vous avez besoin de vérifier votre code par rapport à notre version, vous pouvez trouver une version terminée de l'exemple de code d'application Vue dans notre <a href="https://github.com/mdn/todo-vue">todo-vue repository</a>. Pour une version exécutable en direct, voir <a href="https://mdn.github.io/todo-vue/dist/">https://mdn.github.io/todo-vue/dist/</a>.</p>
+</div>
+
+<dl>
+ <dt><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_getting_started">1. Premiers pas avec Vue</a></dt>
+ <dd>Maintenant, introduisons Vue, le troisième de nos frameworks. Dans cet article, nous allons examiner un peu le contexte de Vue, apprendre à l'installer et créer un nouveau projet, étudier la structure de haut niveau de l'ensemble du projet et d'un composant individuel, voir comment exécuter le projet localement, et préparez-le à commencer à construire notre exemple.</dd>
+ <dt><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_first_component">2. Création de notre premier composant Vue</a></dt>
+ <dd>Il est maintenant temps de plonger plus profondément dans Vue et de créer notre propre composant personnalisé (nous commencerons par créer un composant pour représenter chaque élément de la liste de tâches). En cours de route, nous découvrirons quelques concepts importants tels que l'appel de composants à l'intérieur d'autres composants, leur transmission de données via des accessoires et l'enregistrement de l'état des données.</dd>
+ <dt><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_rendering_lists">3. Rendu d'une liste de composants Vue</a></dt>
+ <dd><span class="author-d-1gg9uz65z1iz85zgdz68zmqkz84zo2qoxwoxz78zz83zz84zz69z2z80zgwxsgnz83zfkt5e5tz70zz68zmsnjz122zz71z">À ce stade, nous avons un composant entièrement fonctionnel ; nous sommes maintenant prêts à ajouter plusieurs composants <code>ToDoItem</code> à notre application. Dans cet article, nous examinerons l'ajout d'un ensemble de données d'élément todo à notre composant <code>App.vue</code> que nous allons ensuite parcourir et afficher à l'intérieur des composants <code>ToDoItem</code> à l'aide de la directive <code>v-for</code>. </span></dd>
+ <dt><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_methods_events_models">4. Ajout d'un nouveau formulaire todo: évènements, méthodes, et modèles Vue</a></dt>
+ <dd>Nous avons maintenant des exemples de données en place et une boucle qui prend chaque bit de données et le rend dans un <code>ToDoItem</code> dans notre application. Ce dont nous avons vraiment besoin ensuite, c'est la possibilité de permettre à nos utilisateurs de saisir leurs propres éléments à faire dans l'application, et pour cela, nous aurons besoin d'un texte <code>&lt;input&gt;</code>, un évènement à déclencher lorsque les données sont soumises, une méthode de déclenchement lors de la soumission pour ajouter les données et relancer la liste, et un modèle pour contrôler les données. C'est ce que nous allons couvrir dans cet article.</dd>
+ <dt><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_styling">5. Styliser les composants Vue avec CSS</a></dt>
+ <dd>Le moment est enfin venu de rendre notre application un peu plus jolie. Dans cet article, nous explorerons les différentes façons de styliser les composants Vue avec CSS.</dd>
+ <dt><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_computed_properties">6. Utilisation des propriétés calculées de Vue</a></dt>
+ <dd>Dans cet article, nous allons ajouter un compteur qui affiche le nombre d'éléments à faire terminés, en utilisant une fonctionnalité de Vue appelée propriétés calculées. Celles-ci fonctionnent de la même manière que les méthodes, mais ne sont réexécutées que lorsque l'une de leurs dépendances change.</dd>
+ <dt><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_conditional_rendering">7. Rendu conditionnel Vue : éditer les todos existants</a></dt>
+ <dd>Il est maintenant temps d'ajouter l'un des éléments majeurs de la fonctionnalité qui nous manque toujours: la possibilité de modifier les éléments todos existants. Pour ce faire, nous profiterons des capacités de rendu conditionnel de Vue — à savoir <code>v-if</code> et <code>v-else</code> — pour nous permettre de basculer entre la vue d'élément todo existante et une vue d'édition où vous pouvez mettre à jour les étiquettes d'élément todo. Nous examinerons également l'ajout de fonctionnalités pour supprimer les éléments todo.</dd>
+ <dt><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_refs_focus_management">8. Gestion de la mise au poinr avec les références de Vue</a></dt>
+ <dd>Nous en avons presque terminé avec Vue. La dernière fonctionnalité à implanter est la gestion de la mise au point, ou en d'autres termes, la façon dont nous pouvons améliorer l'accessibilité du clavier de notre application. Nous allons examiner l'utilisation des références de Vue pour gérer cela, une fonctionnalité avancée qui vous permet d'avoir un accès direct aux nœuds DOM sous-jacents sous le DOM virtuel, ou un accès direct d'un composant à la structure DOM interne d'un composant enfant.</dd>
+ <dt><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_resources">9. Ressources Vue</a></dt>
+ <dd>Nous allons maintenant terminer notre étude de Vue en vous donnant une liste de ressources que vous pouvez utiliser pour aller plus loin dans votre apprentissage, ainsi que d'autres conseils utiles.</dd>
+</dl>
+
+<h2 id="Tutoriels_sur_Svelte">Tutoriels sur Svelte</h2>
+
+<div class="blockIndicator note">
+<p>Note : Les tutoriels sur Svelte ont été essayés pour la dernière fois en aout 2020, avec Svelte 3.24.1.</p>
+
+<p>Si vous avez besoin de vérifier votre code par rapport à notre version, vous pouvez trouver une version terminée de l'exemple eu code de l'application Svelte (tel qu'il est après chaque chapitre) dans le dépôt <a href="https://github.com/opensas/mdn-svelte-tutorial">mdn-svelte-tutorial</a>. Pour une version exécutable en direct, voir <a href="https://svelte.dev/repl/378dd79e0dfe4486a8f10823f3813190?version=3.23.2">https://svelte.dev/repl/378dd79e0dfe4486a8f10823f3813190?version=3.23.2</a>.</p>
+</div>
+
+<dl>
+ <dt><a href="https://wiki.developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_getting_started">1. Premiers pas avec Svelte</a></dt>
+ <dd>Dans cet articles, nous vous proposerons une brève introduction au framework Svelte. Nous verrons comment Svelte fonctionne et qu'est-ce qui le rend si différent des autrse frameworks et outils que nous avons vus jusqu'à présent. Ensuite, nous apprendronds à mettre en place notre environnement de développement, créerons une application démonstrative, appréhenderons la structure du projet et nous verrons comment la mettre en oeuvre localement puis la compiler pour la mettre en production.</dd>
+</dl>
+
+<dl>
+ <dt><a href="https://wiki.developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_Todo_list_beginning">2. Commencer notre application todolist avec Svelte</a></dt>
+ <dd>Maintenant que nous avons compris les bases du fonctionnement  de Svelte, nous pouvons commencer à construirer application démonstrative : une liste de tâches. Dans cet article, nous verrons d'abord les fonctionnalités attendues dans notre application, puis nous créerons un composant Todos.svelte et mettrons en place un HTML statique et du CSS, prêts pour commencer le développement des fonctionnalités de notre application de liste de tâches avec laquelle nous continuerons dans les articles suivants.</dd>
+ <dt><a href="https://wiki.developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_variables_props">3. Comportements dynamiques dans Svelte : travailler avec les variables et les propriétés</a></dt>
+ <dd>Maintenant que nous avons HTML et notre CSS, nous pouvons commencer le développement des fonctionnalités attendues pour notre application de liste de tâches Svelte. Dans cet article, nous utiliserons des variables et propriétés pour rendre notre application dynamique, nous permettant d'ajouter et de supprimer des tâches, de les marquer comme terminées et de les filter par état.</dd>
+ <dt><a href="https://wiki.developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_components">4. Diviser notre application Svelte en composants</a></dt>
+ <dd>L'objectif principal de cet article est de voir comment nous pouvons diviser notre application en composants gérables et partager l'information entre eux. Nous décomposerons notre application puis y ajouterons plus de fonctionnalités pour permettre aux utilisateurs de modifier des composants existants.</dd>
+ <dt><a href="https://wiki.developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_reactivity_lifecycle_accessibility">5. Svelte avancé : réactivité, cycle de vie et accessibilité</a></dt>
+ <dd>Dans cet articles, nous ajouterons les dernières fonctionnalités de l'application et nous pousserons la décomposition de notre application encore plus loin. Nous apprendrons comment résoudre des problèmes de réactivité liés à la mise à jour d'objets et de tableaux. Pour éviter les erreurs communes, nous devrons nous explorer plus profondément le système de réactivité de Svelte. nous verrons aussi comment résoudre certaines problèmes de mise au point pour l'accessibilité et plus encore.</dd>
+ <dt><a href="https://wiki.developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_stores">6. Travailler avec le stockage de Svelte</a></dt>
+ <dd>Dans cet article, nous vous montrerons une autre manière de gérer les états avec Svelte : les stockages Stores. Les Stores sont des répertoires de données globaux qui contiennent des valeurs. Les composants peuvent s'abonner aux stockages et recevoir des notifications que leurs valeurs changent.</dd>
+ <dt><a href="https://wiki.developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_TypeScript">7. Support de TypeScript avec Svelte</a></dt>
+ <dd>Nous allons maintenant apprendre à utiliser TypeScript dans nos applications Svelte. D'abord, nous apprendrons ce qu'est TypeScript et quels bénéfices il peut nous apporter, puis nous verrons ensemble comment configurer notre projet pour travailler avec des fichiers TypeScript. Enfin, nous parcourerons notre application pour voir ce que nous pouvons y changer pour tirer pleinement parti des fonctionnalités de TypeScript.</dd>
+ <dt><a href="https://wiki.developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_deployment_next">8. Déploiement et étapes suivantes</a></dt>
+ <dd>Dans ce dernier article, nous verrons comment déployer votre application et la mettre en ligne et nous vous partagerons quelques-unes des ressources auxquelles vous devriez jeter un oeil pour poursuivre votre apprentissage de Svelte.</dd>
+</dl>
+
+<h2 id="Quels_frameworks_avons-nous_choisis">Quels frameworks avons-nous choisis ?</h2>
+
+<p>Nous publions notre première série d'articles accompagné de guides axés sur quatre frameworks. Trois d'entre eux sont très populaires et bien établis (React/ReactDOM, Ember et Vue) tandis que Svelte est un nouveau prometteur et qui a déjà gagné beaucoup en popularité dernièrement.</p>
+
+<p>Il existe plusieurs raisons à ceci :</p>
+
+<ul>
+ <li>Ce sont des outils populaires qui dureront un certain temps – comme avec tout outil logiciel, il est bon de s'en tenir à des outils activement développés et qui ne seront probablement pas interrompus la semaine prochaine et qui constitueront des atouts considérables à vos compétences lorsque vous cherchez un emploi,</li>
+ <li>Ils ont des communautés solides et de bonnes documentations. C'est très important pour être en mesure de recevoir de l'aide lors de votre apprentissage d'un sujet complexe, surtout lorsque vous débutez.</li>
+ <li>Nous n'avons pas les ressources nécessaires pour couvrir <em>tous</em> les frameworks modernes. <span class="tlid-translation translation" lang="fr"><span title="">De toute façon, cette liste serait très difficile à tenir à jour car de nouveaux apparaissent tout le temps.</span></span></li>
+ <li>En tant que débutant, choisir sur quoi se pencher parmi le grand nombre de choix disponibles est un problème très réel. Faire en sorte que cette liste soit courte est donc utile.</li>
+</ul>
+
+<p>Disons-le franchement : nous n'avons <strong>pas</strong> choisi les frameworks sur lesquels nous nous concentrons parce que nous pensons qu'ils sont les meilleurs ou parce que nous les soutenons de quelque manière que ce soit. Nous pensons seulement qu'ils correspondent le mieux aux critères établis ci-avant.</p>
+
+<p>Notez que nous espérions avoir plus de frameworks inclus lors de la publication initiale, mais nous avons décidé de publier le contenu, puis d'ajouter plus de guides de framework plus tard plutôt que de le retarder l'édition. Si votre framework préféré n'est pas représenté dans ce contenu et que vous souhaitez faire changer cela, n'hésitez pas à en discuter avec nous ! Contactez-nous via <a href="https://wiki.mozilla.org/Matrix">Matrix</a>, ou <a href="https://discourse.mozilla.org/c/mdn">Discourse</a>, ou envoyez-nous un mail sur la <a href="mailto:mdn-admins@mozilla.org">liste mdn-admins</a>.</p>
diff --git a/files/fr/learn/tools_and_testing/client-side_javascript_frameworks/introduction/index.html b/files/fr/learn/tools_and_testing/client-side_javascript_frameworks/introduction/index.html
new file mode 100644
index 0000000000..6762cb5842
--- /dev/null
+++ b/files/fr/learn/tools_and_testing/client-side_javascript_frameworks/introduction/index.html
@@ -0,0 +1,405 @@
+---
+title: Introduction aux frameworks côté client
+slug: Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Introduction
+translation_of: Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Introduction
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{NextMenu("Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Main_features", "Learn/Tools_and_testing/Client-side_JavaScript_frameworks")}}</div>
+
+<p class="summary">We begin our look at frameworks with a general overview of the area, looking at a brief history of JavaScript and frameworks, why frameworks exist and what they give us, how to start thinking about choosing a framework to learn, and what alternatives there are to client-side frameworks.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Prerequisites:</th>
+ <td>Familiarity with the core <a href="/en-US/docs/Learn/HTML">HTML</a>, <a href="/en-US/docs/Learn/CSS">CSS</a>, and <a href="/en-US/docs/Learn/JavaScript">JavaScript</a> languages.</td>
+ </tr>
+ <tr>
+ <th scope="row">Objective:</th>
+ <td>To understand how client-side JavaScript frameworks came to exist, what problems they solve, what alternatives there are, and how to go about choosing one.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="A_brief_history">A brief history</h2>
+
+<p>When JavaScript debuted in 1996, it added occasional interactivity and excitement to a web that was, up until then, composed of static documents. The web became not just a place to <em>read things</em>, but to <em>do things</em>. JavaScript’s popularity steadily increased. Developers who worked with JavaScript wrote tools to solve the problems they faced, and packaged them into reusable packages called <strong>libraries</strong>, so they could share their solutions with others. This shared ecosystem of libraries helped shape the growth of the web.</p>
+
+<p>Now, JavaScript is an essential part of the web, <a href="https://w3techs.com/technologies/details/cp-javascript">used on 95% of all websites</a>, and the web is an essential part of modern life. Users write papers, manage their budgets, stream music, watch movies, and communicate with others over great distances instantaneously, with text, audio or video chat. The web allows us to do things that used to be possible only in native applications installed on our computers. These modern, complex, interactive websites are often referred to as <strong>web applications</strong>.</p>
+
+<p>The advent of modern JavaScript frameworks has made it much easier to build highly dynamic, interactive applications. A <strong>framework</strong> is a library that offers opinions about how software gets built. These opinions allow for predictability and homogeneity in an application; predictability allows software to scale to an enormous size and still be maintainable; predictability and maintainability are essential for the health and longevity of software.</p>
+
+<p>JavaScript frameworks power much of the impressive software on the modern web – including many of the websites you likely use every day. MDN Web Docs, which you are currently reading this on, uses the React/ReactDOM framework to power its front end.</p>
+
+<h2 id="What_frameworks_are_out_there">What frameworks are out there?</h2>
+
+<p>There are many frameworks out there, but currently the "big four" are considered to be the following.</p>
+
+<h3 id="Ember">Ember</h3>
+
+<p><a href="https://emberjs.com/">Ember</a> was initially released in December 2011 as a continuation of work that started in the <a href="https://en.wikipedia.org/wiki/SproutCore">SproutCore</a> project. It is an older framework that has less users than more modern alternatives  such as React and Vue, but it still enjoys a fair amount of popularity due to its stability, community support, and some clever coding principles.</p>
+
+<p><a href="https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_getting_started">Start learning Ember</a></p>
+
+<h3 id="Angular">Angular</h3>
+
+<p><a href="https://angular.io">Angular</a> is an open-source web application framework led by the Angular Team at Google and by a community of individuals and corporations. It is a complete rewrite from the same team that built <a href="https://angularjs.org/">AngularJS</a>. Angular was officially released on the 14th of September 2016.</p>
+
+<p>Angular is a component-based framework which uses declarative HTML templates. At build time, transparently to developers, the framework's compiler translates the templates to optimized JavaScript instructions. Angular uses <a href="https://www.typescriptlang.org/">TypeScript</a>, a superset of JavaScript that we’ll look at in a little more detail in the next chapter.</p>
+
+<h3 id="Vue">Vue</h3>
+
+<p>Evan You first released <a href="https://vuejs.org/">Vue</a> in 2014, after working on and learning from the original <a href="https://angularjs.org/">AngularJS</a> project. Vue is the youngest of the big four, but has enjoyed a recent uptick in popularity.</p>
+
+<p>Vue, like <a href="https://angularjs.org/">AngularJS</a>, extends HTML with some of its own code. Apart from that, it mainly relies on modern, standard JavaScript.</p>
+
+<p><a href="https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_getting_started">Start learning Vue</a></p>
+
+<h3 id="React">React</h3>
+
+<p>Facebook released <a href="https://reactjs.org/">React</a> in 2013. By this point, it had already been using React to solve many of its problems internally. React itself is <em>not</em> technically a framework; it's a library for rendering UI components. React is used in combination with <em>other</em> libraries to make applications — React and <a href="https://reactnative.dev/">React Native</a> enable developers to make mobile applications; React and <a href="https://reactjs.org/docs/react-dom.html">ReactDOM</a> enable them to make web applications, etc.</p>
+
+<p>Because React and ReactDOM are so often used together, React is colloquially understood as a JavaScript framework. As you read through this module, we will be working with that colloquial understanding.</p>
+
+<p>React extends JavaScript with HTML-like syntax, known as <a href="https://reactjs.org/docs/introducing-jsx.html">JSX</a>.</p>
+
+<p><a href="https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_getting_started">Start learning React</a></p>
+
+<h2 id="Why_do_frameworks_exist">Why do frameworks exist?</h2>
+
+<p>We've discussed the environment that inspired the creation of frameworks, but not really <em>why</em> developers felt the need to make them. Exploring the why requires first examining the challenges of software development.</p>
+
+<p>Consider a common kind of application: A to-do list creator, which we'll look at implementing using a variety of frameworks in future chapters. This application should allow users to do things like render a list of tasks, add a new task, and delete a task; and it must do this while reliably tracking and updating the data underlying the application. In software development, this underlying data is known as state.</p>
+
+<p>Each of our goals is theoretically simple in isolation. We can iterate over the data to render it; we can add to an object to make a new task; we can use an identifier to find, edit, or delete a task. When we remember that the application has to let the user to do <em>all</em> of these things through the browser, however, some cracks start to show. <strong>The real problem is this: every time we change our application’s state, we need to update the UI to match.</strong></p>
+
+<p>We can examine the difficulty of this problem by looking at just <em>one</em> feature of our todo list app: rendering a list of tasks.</p>
+
+<h2 id="The_verbosity_of_DOM_changes">The verbosity of DOM changes</h2>
+
+<p>Building HTML elements and rendering them in the browser at the appropriate time takes a surprising amount of code. Let's say that our state is an array of objects structured like this:</p>
+
+<pre class="brush: js notranslate">const state = [
+ {
+ id: 'todo-0',
+ name: 'Learn some frameworks!'
+ }
+]</pre>
+
+<p>How do we show one of those tasks to our user? We want to represent each task as a list item – an HTML <code><a href="/en-US/docs/Web/HTML/Element/li">&lt;li&gt;</a></code> element inside of an unordered list element (a <code><a href="/en-US/docs/Web/HTML/Element/ul">&lt;ul&gt;</a></code>). How do we make it? That could look something like this:</p>
+
+<pre class="brush: js notranslate">function buildTodoItemEl(id, name) {
+ const item = document.createElement('li');
+ const span = document.createElement('span');
+ const textContent = document.createTextNode(name);
+
+ span.appendChild(textContent);
+
+ item.id = id;
+ item.appendChild(span);
+ item.appendChild(buildDeleteButtonEl(id));
+
+ return item;
+}</pre>
+
+<p>Here, we use the <code><a href="/en-US/docs/Web/API/Document/createElement">document.createElement()</a></code> method to make our <code>&lt;li&gt;</code>, and several more lines of code to create the properties and children it needs.</p>
+
+<p>The tenth line of this snippet references another build function: <code>buildDeleteButtonEl()</code>. It follows a similar pattern to the one we used to build a list item element:</p>
+
+<pre class="brush: js notranslate">function buildDeleteButtonEl(id) {
+ const button = document.createElement('button');
+ const textContent = document.createTextNode('Delete');
+
+ button.setAttribute('type', 'button');
+ button.appendChild(textContent);
+
+ return button;
+}</pre>
+
+<p>This button doesn't do anything yet, but it will later once we decide to implement our delete feature. The code that will render our items on the page might read something like this:</p>
+
+<pre class="brush: js notranslate">function renderTodoList() {
+ const frag = document.createDocumentFragment();
+ state.tasks.forEach(task =&gt; {
+ const item = buildTodoItemEl(task.id, task.name);
+ frag.appendChild(item);
+ });
+
+ while (todoListEl.firstChild) {
+ todoListEl.removeChild(todoListEl.firstChild);
+ }
+ todoListEl.appendChild(frag);
+}</pre>
+
+<p>We've now got well over thirty lines of code dedicated <em>just</em> to the UI – <em>just</em> to the step of rendering something in the DOM – and at no point do we add classes that we could use later to style our list-items!</p>
+
+<p>Working directly with the DOM, as in this example, requires understanding many things about how the DOM works: how to make elements; how to change their properties; how to put elements inside of each other; how to get them on the page. None of this code actually handles user interactions, or addresses adding or deleting a task. If we add those features, we have to remember to update our UI in the right time and in the right way.</p>
+
+<p>JavaScript frameworks were created to make this kind of work a little easier — they exist to provide a better <em>developer experience</em>. They don't bring brand-new powers to JavaScript; they give you easier access to JavaScript's powers so you can build for today's web.</p>
+
+<p>If you want to see code samples from this section in action, you can check out a <a href="https://codepen.io/dengeist/pen/XWbPNmw">working version of the app on CodePen</a>, which also allows users to add and delete new tasks.</p>
+
+<p>Read more about the JavaScript used in this section:</p>
+
+<ul>
+ <li><code><a href="/en-US/docs/Web/API/Document/createElement">document.createElement()</a></code></li>
+ <li><code><a href="/en-US/docs/Web/API/Document/createTextNode">document.createTextNode()</a></code></li>
+ <li><code><a href="/en-US/docs/Web/API/Document/createDocumentFragment">document.createDocumentFragment()</a></code></li>
+ <li><code><a href="/en-US/docs/Web/API/EventTarget/addEventListener">eventTarget.addEventListener()</a></code></li>
+ <li><code><a href="/en-US/docs/Web/API/Node/appendChild">node.appendChild()</a></code></li>
+ <li><code><a href="/en-US/docs/Web/API/Node/removeChild">node.removeChild()</a></code></li>
+</ul>
+
+<h2 id="Another_way_to_build_UIs">Another way to build UIs</h2>
+
+<p>Every JavaScript framework offers a way to write user interfaces more <em>declaratively</em>. That is, they allow you to write code that describes how your UI should look, and the framework makes it happen in the DOM behind the scenes.</p>
+
+<p>The vanilla JavaScript approach to building out new DOM elements in repetition was difficult to understand at a glance.  By contrast, the following block of code illustrates the way you might use Vue to describe our list of tasks:</p>
+
+<pre class="brush: html notranslate">&lt;ul&gt;
+ &lt;li v-for="task in tasks" v-bind:key="task.id"&gt;
+ &lt;span&gt;\{{task.name\}}&lt;/span&gt;
+ &lt;button type="button"&gt;Delete&lt;/button&gt;
+ &lt;/li&gt;
+&lt;/ul&gt;</pre>
+
+<p>That's it. This snippet reduces approximately thirty-two lines of code down to six lines. If the curly braces and <code>v-</code> attributes here are unfamiliar to you, that's okay; you’ll learn about Vue-specific syntax later on in the module. The thing to take away here is that this code looks like the UI it represents, whereas the vanilla JavaScript code does not.</p>
+
+<p>Thanks to Vue, we didn't have to write our own functions for building the UI; the framework will handle that for us in an optimized, efficient way. Our only role here was to describe to Vue what each item should look like. Developers who are familiar with Vue can join our project and quickly work out what is going on. Vue is not alone in this: using a framework improves team as well as individual efficiency.</p>
+
+<p>It's possible to do things <em>similar</em> to this in vanilla JavaScript. <a href="/en-US/docs/Web/JavaScript/Reference/Template_literals">Template literal strings</a> make it easy to write strings of HTML that represent what the final element would look like. That might be a useful idea for something as simple as our to-do list application, but it's not maintainable for large applications that manage thousands of records of data, and could render just as many unique elements in a user interface.</p>
+
+<h2 id="Other_things_frameworks_give_us">Other things frameworks give us</h2>
+
+<p>Let's look at some of the other advantages conferred upon us by frameworks. As we've alluded to before, the advantages of frameworks are achievable in vanilla JavaScript, but using a framework takes away all of the cognitive load of having to solve these problems yourself.</p>
+
+<h3 id="Tooling">Tooling</h3>
+
+<p>Because each of the frameworks in this module have a large, active community, each framework's ecosystem provides tooling that Improves the developer experience. These tools make it easy to add things like testing (to ensure that your application behaves as it should) or linting (to ensure that your code is error-free and stylistically consistent).</p>
+
+<div class="blockIndicator note">
+<p><strong>Note</strong>: If you want to find out more details about web tooling concepts, have a read of our <a href="/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Overview">Client-side tooling overview</a>.</p>
+</div>
+
+<h3 id="Compartmentalization">Compartmentalization</h3>
+
+<p>Most major frameworks encourage developers to abstract the different parts of their user interfaces into <em>components</em> — maintainable, reusable chunks of code that can communicate with one another. All the code related to a given component can live in one file (or a couple of specific files), so that you as a developer know exactly where to go to make changes to that component. In a vanilla JavaScript app, you'd have to create your own set of conventions to achieve this in an efficient, scalable way. Many JavaScript developers, if left to their own devices, could end up with all the code related to one part of the UI being spread out all over a file — or in another file altogether.</p>
+
+<h3 id="Routing">Routing</h3>
+
+<p>The most essential feature of the web is that it allows users to navigate from one page to another – it is, after all, a network of interlinked documents. When you follow a link on this very website, your browser communicates with a server and fetches new content to display for you. As it does so, the URL in your address bar changes. You can save this new URL and come back to the page later on, or share it with others so they can easily find the same page. Your browser remembers your navigation history and allows you to navigate back and forth, too. This is called <strong>server-side routing</strong>.</p>
+
+<p>Modern web applications typically do not fetch and render new HTML files — they load a single HTML shell, and continually update the DOM inside it (referred to as <strong>single page apps</strong>, or <strong>SPAs</strong>) without navigating users to new addresses on the web. Each new pseudo-webpage is usually called a <em>view</em>, and by default, no routing is done.</p>
+
+<p>When an SPA is complex enough, and renders enough unique views, it's important to bring routing functionality into your application. People are used to being able to link to specific pages in an application, travel forward and backward in their navigation history, etc., and their experience suffers when these standard web features are broken. When routing is handled by a client application in this fashion, it is aptly called <strong>client-side routing</strong>.</p>
+
+<p>It's <em>possible</em> to make a router using the native capabilities of JavaScript and the browser, but popular, actively developed frameworks have companion libraries that make routing a more intuitive part of the development process.</p>
+
+<h2 id="Things_to_consider_when_using_frameworks">Things to consider when using frameworks</h2>
+
+<p>Being an effective web developer means using the most appropriate tools for the job. JavaScript frameworks make front-end application development easy, but they are not a silver bullet that will solve all problems. This section talks about some of the things you should consider when using frameworks. Bear in mind that you might not need a framework at all — beware that you don't end up using a framework just for the sake of it.</p>
+
+<h3 id="Familiarity_with_the_tool">Familiarity with the tool</h3>
+
+<p>Just like vanilla JavaScript, frameworks take time to learn and have their quirks. Before you decide to use a framework for a project, be sure you have time to learn enough of its features for it to be useful to you rather than it working against you, and be sure that your teammates are comfortable with it as well.</p>
+
+<h3 id="Overengineering">Overengineering</h3>
+
+<p>If your web development project is a personal portfolio with a few pages, and those pages have little or no interactive capability, a framework (and all of its JavaScript) may not be necessary at all. That said, frameworks are not a monolith, and some of them are better-suited to small projects than others. In an article for Smashing Magazine, Sarah Drasner writes about how <a href="https://www.smashingmagazine.com/2018/02/jquery-vue-javascript/">Vue can replace jQuery</a> as a tool for making small portions of a webpage interactive.</p>
+
+<h3 id="Larger_code_base_and_abstraction">Larger code base and abstraction</h3>
+
+<p>Frameworks allow you to write more declarative code – and sometimes <em>less</em> code overall – by dealing with the DOM interactions for you, behind the scenes. This abstraction is great for your experience as a developer, but it isn't free. In order to translate what you write into DOM changes, frameworks have to run their own code, which in turn makes your final piece of software larger and more computationally expensive to operate.</p>
+
+<p>Some extra code is inevitable, and a framework that supports tree-shaking (removal of any code that isn't actually used in the app during the build process) will allow you to keep your applications small, but this is still a factor you need to keep in mind when considering your app's performance, especially on more network/storage-constrained devices, like mobile phones.</p>
+
+<p>The abstraction of frameworks affects not only your JavaScript, but your relationship with the very nature of the web. No matter how you build for the web, the end result, the layer that your users ultimately interact with, is HTML. Writing your whole application in JavaScript can make you lose sight of HTML and the purpose of its various tags, and lead you to produce an HTML document that is un-semantic and inaccessible. In fact, it's possible to write a fragile application that depends entirely on JavaScript and will not function without it.</p>
+
+<p>Frameworks are not the source of our problems. With the wrong priorities, it's possible for <em>any</em> application to be fragile, bloated, and inaccessible. Frameworks do, however, amplify our priorities as developers. If your priority is to make a complex web app, it's easy to do that. However, if your priorities don't carefully guard performance and accessibility, frameworks will amplify your fragility, your bloat, and your inaccessibility. Modern developer priorities, amplified by frameworks, have inverted the structure of the web in many places. Instead of a robust, content-first network of documents, the web now often puts JavaScript first and user experience last.</p>
+
+<h2 id="Accessibility_on_a_framework-driven_web">Accessibility on a framework-driven web</h2>
+
+<p>Let's build on what we said in the previous section, and talk a bit more about accessibility. Making user interfaces accessible always requires some thought and effort, and frameworks can complicate that process. You often have to employ advanced framework APIs to access native browser features like ARIA <a href="/en-US/docs/Web/Accessibility/ARIA/ARIA_Live_Regions">live regions</a> or focus management.</p>
+
+<p>In some cases, framework applications create accessibility barriers that do not exist for traditional websites. The biggest example of this is in client-side routing, as mentioned earlier.</p>
+
+<p>With traditional (server-side) routing, navigating the web has predictable results. The browser knows to set focus to the top of the page and assistive technologies will announce the title of the page. These things happen every time you navigate to a new page.</p>
+
+<p>With client-side routing, your browser is not loading new web pages, so it doesn't know that it should automatically adjust focus or announce a new page title. Framework authors have devoted immense time and labor to writing JavaScript that recreates these features, and even then, no framework has done so perfectly.</p>
+
+<p>The upshot is that you should consider accessibility from the very start of <em>every</em> web project, but bear in mind that abstracted codebases that use frameworks are more likely to suffer from major accessibility issues if you don't.</p>
+
+<h2 id="How_to_choose_a_framework">How to choose a framework</h2>
+
+<p>Each of the frameworks discussed in this module take different approaches to web application development. Each is regularly improving or changing, and each has its pros and cons. Choosing the right framework is a team- and project-dependent process, and you should do your own research to uncover what suits your needs. That said, we've identified a few questions you can ask in order to research your options more effectively:</p>
+
+<ol>
+ <li>What browsers does the framework support?</li>
+ <li>What domain-specific languages does the framework utilize?</li>
+ <li>Does the framework have a strong community and good docs (and other support) available?</li>
+</ol>
+
+<p>The table in this section provides a glanceable summary of the current <em>browser support</em> offered by each framework, as well as the <strong>domain-specific languages</strong> with which it can be used.</p>
+
+<p>Broadly, domain-specific languages (<strong>DSLs</strong>) are programming languages relevant in specific areas of software development. In the context of frameworks, DSLs are variations on JavaScript or HTML that make it easier to develop with that framework. Crucially, none of the frameworks <em>require</em> a developer to use a specific DSL, but they have almost all been designed with a specific DSL in mind. Choosing not to employ a framework’s preferred DSL will mean you miss out on features that would otherwise improve your developer experience.</p>
+
+<p>You should seriously consider the support matrix and DSLs of a framework when making a choice for any new project. Mismatched browser support can be a barrier to your users; mismatched DSL support can be a barrier to you and your teammates.</p>
+
+<table class="standard-table">
+ <thead>
+ <tr>
+ <th scope="col">Framework</th>
+ <th scope="col">Browser support</th>
+ <th scope="col">Preferred DSL</th>
+ <th scope="col">Supported DSLs</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>Angular</td>
+ <td>IE9+</td>
+ <td>TypeScript</td>
+ <td>HTML-based; TypeScript</td>
+ </tr>
+ <tr>
+ <td>React</td>
+ <td>Modern (IE9+ with Polyfills)</td>
+ <td>JSX</td>
+ <td>JSX; TypeScript</td>
+ </tr>
+ <tr>
+ <td>Vue</td>
+ <td>IE9+</td>
+ <td>HTML-based</td>
+ <td>HTML-based, JSX, Pug</td>
+ </tr>
+ <tr>
+ <td>Ember</td>
+ <td>Modern (IE9+ in Ember version 2.18)</td>
+ <td>Handlebars</td>
+ <td>Handlebars, TypeScript</td>
+ </tr>
+ </tbody>
+</table>
+
+<div class="blockIndicator note">
+<p><strong>Note</strong>: DSLs we've described as "HTML-based" do not have official names. They are not really true DSLs, but they are non-standard HTML, so we believe they are worth highlighting.</p>
+</div>
+
+<p>Citations for this table:</p>
+
+<ul>
+ <li><a href="https://reactjs.org/docs/react-dom.html#browser-support">React browser support: official docs</a></li>
+ <li><a href="https://blog.emberjs.com/2018/02/14/ember-3-0-released.html">Ember browser support: Ember 3.0 release announcement</a></li>
+ <li><a href="https://guides.emberjs.com/v3.3.0/templates/handlebars-basics/">Ember templating language (official docs)</a></li>
+</ul>
+
+<h3 id="Does_the_framework_have_a_strong_community">Does the framework have a strong community?</h3>
+
+<p>This is perhaps the hardest metric to measure, because community size does not correlate directly to easy-to-access numbers. You can check a project's number of GitHub stars or weekly npm downloads to get an idea of its popularity, but sometimes the best thing to do is search a few forums or talk to other developers. It is not just about the community's size, but also how welcoming and inclusive it is, and how good available documentation is.</p>
+
+<h3 id="Opinions_on_the_web">Opinions on the web</h3>
+
+<p>Don't just take our word on this matter — there are discussions all over the web. The Wikimedia Foundation recently chose to use Vue for its front-end, and posted a <a href="https://phabricator.wikimedia.org/T241180">request for comments (RFC) on framework adoption</a>. Eric Gardner, the author of the RFC, took time to outline the needs of the Wikimedia project and why certain frameworks were good choices for the team. This RFC serves as a great example of the kind of research you should do for yourself when planning to use a front-end framework.</p>
+
+<p>The <a href="https://stateofjs.com/">State of JavaScript survey</a> is a helpful collection of feedback from JavaScript developers. It covers many topics related to JavaScript, including data about both the use of frameworks and developer sentiment toward them. Currently, there are several years of data available, allowing you to get a sense of a framework's popularity.</p>
+
+<p>The Vue team has <a href="https://vuejs.org/v2/guide/comparison.html">exhaustively compared Vue to other popular frameworks</a>. There may be some bias in this comparison (which they note), but it's a valuable resource nonetheless.</p>
+
+<h2 id="Alternatives_to_client-side_frameworks">Alternatives to client-side frameworks</h2>
+
+<p>If you’re looking for tools to expedite the web development process, and you know your project isn’t going to require intensive client-side JavaScript, you could reach for one of a handful of other solutions for building the web:</p>
+
+<ul>
+ <li>A content management system</li>
+ <li>Server-side rendering</li>
+ <li>A static site generator</li>
+</ul>
+
+<h3 id="Content_management_systems">Content management systems</h3>
+
+<p><strong>Content-management systems</strong> (<strong>CMSes</strong>) are any tools that allow a user to create content for the web without directly writing code themselves. They're a good solution for large projects, especially projects that require input from content writers who have limited coding ability, or for programmers who want to save time. They do, however, require a significant amount of time to set up, and utilizing a CMS means that you surrender at least some measure of control over the final output of your website. For example: if your chosen CMS doesn't author accessible content by default, it's often difficult to improve this.</p>
+
+<p>Popular examples include <a href="https://wordpress.com/">Wordpress</a>, <a href="https://www.joomla.org/">Joomla</a>, and <a href="https://www.drupal.org/">Drupal</a>.</p>
+
+<h3 id="Server-side_rendering">Server-side rendering</h3>
+
+<p><strong>Server-side rendering</strong> (<strong>SSR</strong>) is an application architecture in which it is the <em>server'</em>s job to render a single-page application. This is the opposite of <em>client-side rendering</em>, which is the most common and most straightforward way to build a JavaScript application. Server-side rendering is easier on the client's device, because you're only sending a rendered HTML file to them, but it can be difficult to set up compared to a client-side-rendered application.</p>
+
+<p>All of the frameworks covered in this module support server-side rendering as well as client-side rendering. Check out <a href="https://nextjs.org/">Next.js</a> for React, <a href="https://nuxtjs.org/">Nuxt.js</a> for Vue (yes it is confusing, and no, these projects are not related!), <a href="https://github.com/ember-fastboot/ember-cli-fastboot">FastBoot</a> for Ember, and <a href="https://angular.io/guide/universal">Angular Universal</a> for Angular.</p>
+
+<div class="blockIndicator note">
+<p><strong>Note</strong>: Some SSR solutions are written and maintained by the community, whereas some are "official" solutions provided by the framework's maintainer.</p>
+</div>
+
+<h3 id="Static_site_generators">Static site generators</h3>
+
+<p>Static site generators are programs that dynamically generate all the webpages of a multi-page website — including any relevant CSS or JavaScript — so that they can be published in any number of places. The publishing host could be a GitHub pages branch, a Netlify instance, or any private server of your choosing, for example. There are a number of advantages of this approach, mostly around performance (your user's device isn’t building the page with JavaScript; it's already complete) and security (static pages have fewer attack vectors). These sites can still utilize JavaScript where they need to, but they are not <em>dependent</em> upon it. Static site generators take time to learn, just like any other tool, which can be a barrier to your development process.</p>
+
+<p>Static sites can have as few or as many unique pages as you want. Just as frameworks empower you to quickly write client-side JavaScript applications, static site generators allow you a way to quickly create HTML files you would otherwise have written individually. Like frameworks, static site generators allow developers to write components that define common pieces of your web pages, and to compose those components together to create a final page. In the context of static site generators, these components are called <strong>templates</strong>. Web pages built by static site generators can even be home to framework applications: if you want one specific page of your statically-generated website to boot up a React application when your user visits it for example, you can do that.</p>
+
+<p>Static site generators have been around for quite a long time, but they have seen a bit of a revival in the recent history of the web. A handful of powerful options are now available, such as <a href="https://gohugo.io/">Hugo</a>, <a href="https://jekyllrb.com/">Jekyll</a>, <a href="https://www.11ty.dev/">Eleventy</a>, and <a href="https://www.gatsbyjs.org/">Gatsby</a>.</p>
+
+<p>If you'd like to learn more about static site generators on the whole, check out Tatiana Mac's <a href="https://tatianamac.com/posts/beginner-eleventy-tutorial-parti/">Beginner's guide to Eleventy</a>. In the first article of the series, she explains what a static site generator is, and how it relates to other means of publishing web content.</p>
+
+<h2 id="Summary">Summary</h2>
+
+<p>And that brings us to the end of our introduction to frameworks — we’ve not taught you any code yet, but hopefully we've given you a useful background on why you'd use frameworks in the first place and how to go about choosing one, and made you excited to learn more and get stuck in!</p>
+
+<p>Our next article goes down to a lower level, looking at the specific kinds of features frameworks tend to offer, and why they work like they do.</p>
+
+<p>{{NextMenu("Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Main_features", "Learn/Tools_and_testing/Client-side_JavaScript_frameworks")}}</p>
+
+<h2 id="In_this_module">In this module</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Introduction">Introduction to client-side frameworks</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Main_features">Framework main features</a></li>
+ <li>React
+ <ul>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_getting_started">Getting started with React</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_todo_list_beginning">Beginning our React todo list</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_components">Componentizing our React app</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_interactivity_events_state">React interactivity: Events and state</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_interactivity_filtering_conditional_rendering">React interactivity: Editing, filtering, conditional rendering</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_accessibility">Accessibility in React</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_resources">React resources</a></li>
+ </ul>
+ </li>
+ <li>Ember
+ <ul>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_getting_started">Getting started with Ember</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_structure_componentization">Ember app structure and componentization</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_interactivity_events_state">Ember interactivity: Events, classes and state</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_conditional_footer">Ember Interactivity: Footer functionality, conditional rendering</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_routing">Routing in Ember</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_resources">Ember resources and troubleshooting</a></li>
+ </ul>
+ </li>
+ <li>Vue
+ <ul>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_getting_started">Getting started with Vue</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_first_component">Creating our first Vue component</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_rendering_lists">Rendering a list of Vue components</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_methods_events_models">Adding a new todo form: Vue events, methods, and models</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_styling">Styling Vue components with CSS</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_computed_properties">Using Vue computed properties</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_conditional_rendering">Vue conditional rendering: editing existing todos</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_refs_focus_management">Focus management with Vue refs</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_resources">Vue resources</a></li>
+ </ul>
+ </li>
+ <li>Svelte
+ <ul>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_getting_started">Getting started with Svelte</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_Todo_list_beginning">Starting our Svelte Todo list app</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_variables_props">Dynamic behavior in Svelte: working with variables and props</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_components">Componentizing our Svelte app</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_reactivity_lifecycle_accessibility">Advanced Svelte: Reactivity, lifecycle, accessibility</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_stores">Working with Svelte stores</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_TypeScript">TypeScript support in Svelte</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_deployment_next">Deployment and next steps</a></li>
+ </ul>
+ </li>
+</ul>
diff --git a/files/fr/learn/tools_and_testing/client-side_javascript_frameworks/main_features/index.html b/files/fr/learn/tools_and_testing/client-side_javascript_frameworks/main_features/index.html
new file mode 100644
index 0000000000..b9fe78c7d9
--- /dev/null
+++ b/files/fr/learn/tools_and_testing/client-side_javascript_frameworks/main_features/index.html
@@ -0,0 +1,354 @@
+---
+title: Fonctionnalités principales des framework
+slug: Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Main_features
+translation_of: Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Main_features
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Introduction","Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_getting_started", "Learn/Tools_and_testing/Client-side_JavaScript_frameworks")}}</div>
+
+<p class="summary">Each major JavaScript framework has a different approach to updating the DOM, handling browser events, and providing an enjoyable developer experience. This article will explore the main features of “the big 4” frameworks, looking at how frameworks tend to work from a high level, and the differences between them.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Prerequisites:</th>
+ <td>Familiarity with the core <a href="/en-US/docs/Learn/HTML">HTML</a>, <a href="/en-US/docs/Learn/CSS">CSS</a>, and <a href="/en-US/docs/Learn/JavaScript">JavaScript</a> languages.</td>
+ </tr>
+ <tr>
+ <th scope="row">Objective:</th>
+ <td>To understand the main code features of frameworks.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Domain-specific_languages">Domain-specific languages</h2>
+
+<p>All of the frameworks discussed in this module are powered by JavaScript, and all allow you to use domain-specific languages (DSLs) in order to build your applications. In particular, React has popularized the use of <strong>JSX</strong> for writing its components, while Ember utilizes <strong>Handlebars</strong>. Unlike HTML, these languages know how to read data variables, and this data can be used to streamline the process of writing your UI.</p>
+
+<p>Angular apps often make heavy use of <strong>TypeScript</strong>. TypeScript is not concerned with the writing of user interfaces, but it is a domain-specific language, and has significant differences to vanilla JavaScript.</p>
+
+<p>DSLs can't be read by the browser directly; they must be transformed into JavaScript or HTML first. <a href="/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Overview#Transformation">Transformation is an extra step in the development process</a>, but framework tooling generally includes the required tools to handle this step, or can be adjusted to include this step. While it is possible to build framework apps without using these domain-specific languages, embracing them will streamline your development process and make it easier to find help from the communities around those frameworks.</p>
+
+<h3 id="JSX">JSX</h3>
+
+<p><a href="https://reactjs.org/docs/introducing-jsx.html">JSX</a>, which stands for JavaScript and XML, is an extension of JavaScript that brings HTML-like syntax to a JavaScript environment. It was invented by the React team for use in React applications, but can be used to develop other applications — like Vue apps, for instance.</p>
+
+<p>The following shows a simple JSX example:</p>
+
+<pre class="brush: js notranslate">const subject = "World";
+const header = (
+ &lt;header&gt;
+ &lt;h1&gt;Hello, {subject}!&lt;/h1&gt;
+ &lt;/header&gt;
+);</pre>
+
+<p>This expression represents an HTML <code><a href="/en-US/docs/Web/HTML/Element/header">&lt;header&gt;</a></code> element with a <code><a href="/en-US/docs/Web/HTML/Element/Heading_Elements">&lt;h1&gt;</a></code> element inside. The curly braces around <code>subject</code> on line 4 tell the application to read the value of the <code>subject</code> constant and insert it into our <code>&lt;h1&gt;</code>.</p>
+
+<p>When used with React, the JSX from the previous snippet would be compiled into this:</p>
+
+<pre class="brush: js notranslate">var subject = "World";
+var header = React.createElement("header", null,
+ React.createElement("h1", null, "Hello, ", subject, "!")
+);</pre>
+
+<p>When ultimately rendered by the browser, the above snippet will produce HTML that looks like this:</p>
+
+<pre class="brush: html notranslate">&lt;header&gt;
+ &lt;h1&gt;Hello, World!&lt;/h1&gt;
+&lt;/header&gt;</pre>
+
+<h3 id="Handlebars">Handlebars</h3>
+
+<p>The <a href="https://handlebarsjs.com/">Handlebars</a> templating language is not specific to Ember applications, but it is heavily utilized in Ember apps. Handlebars code resembles HTML, but it has the option of pulling data in from elsewhere. This data can be used to influence the HTML that an application ultimately builds.</p>
+
+<p>Like JSX, Handlebars uses curly braces to inject the value of a variable. Handlebars uses a double-pair of curly braces, instead of a single pair.</p>
+
+<p>Given this Handlebars template:</p>
+
+<pre class="brush: html notranslate">&lt;header&gt;
+ &lt;h1&gt;Hello, \{{subject}}!&lt;/h1&gt;
+&lt;/header&gt;</pre>
+
+<p>And this data:</p>
+
+<pre class="brush: js notranslate">{
+ subject: "World"
+}</pre>
+
+<p>Handlebars will build HTML like this:</p>
+
+<pre class="brush: html notranslate">&lt;header&gt;
+ &lt;h1&gt;Hello, World!&lt;/h1&gt;
+&lt;/header&gt;</pre>
+
+<h3 id="TypeScript">TypeScript</h3>
+
+<p><a href="https://www.typescriptlang.org/">TypeScript</a> is a <em>superset</em> of JavaScript, meaning it extends JavaScript — all JavaScript code is valid TypeScript, but not the other way around. TypeScript is useful for the strictness it allows developers to enforce on their code. For instance, consider a function <code>add()</code>, which takes integers <code>a</code> and <code>b</code> and returns their sum.</p>
+
+<p>In JavaScript, that function could be written like this:</p>
+
+<pre class="brush: js notranslate">function add(a, b) {
+ return a + b;
+}</pre>
+
+<p>This code might be trivial for someone accustomed to JavaScript, but it could still be clearer. JavaScript lets us use the <code>+</code> operator to concatenate strings together, so this function would technically still work if <code>a</code> and <code>b</code> were strings — it just might not give you the result you'd expect. What if we wanted to only allow numbers to be passed into this function? TypeScript makes that possible:</p>
+
+<pre class="brush: js notranslate">function add(a: number, b: number) {
+ return a + b;
+}</pre>
+
+<p>The <code>: number</code> written after each parameter here tells TypeScript that both <code>a</code> and <code>b</code> must be numbers. If we were to use this function and pass <code>'2'</code> into it as an argument, TypeScript would raise an error during compilation, and we would be forced to fix our mistake. We could write our own JavaScript that raises these errors for us, but it would make our source code significantly more verbose. It probably makes more sense to let TypeScript handle such checks for us.</p>
+
+<h2 id="Writing_components">Writing components</h2>
+
+<p>As mentioned in the previous chapter, most frameworks have some kind of component model. React components can be written with JSX, Ember components with Handlebars, and Angular and Vue components with a templating syntax that lightly extends HTML.</p>
+
+<p>Regardless of their opinions on how components should be written, each framework's components offer a way to describe the external properties they may need, the internal state that the component should manage, and the events a user can trigger on the component's markup.</p>
+
+<p>The code snippets in the rest of this section will use React as an example, and are written with JSX.</p>
+
+<h3 id="Properties">Properties</h3>
+
+<p>Properties, or <strong>props</strong>, are external data that a component needs in order to render. Suppose you're building a website for an online magazine, and you need to be sure that each contributing writer gets credit for their work. You might create an <code>AuthorCredit</code> component to go with each article. This component needs to display a portrait of the author and a short byline about them. In order to know what image to render, and what byline to print, <code>AuthorCredit</code> needs to accept some props.</p>
+
+<p>A React representation of this <code>AuthorCredit</code> component might look something like this:</p>
+
+<pre class="brush: js notranslate">function AuthorCredit(props) {
+ return (
+ &lt;figure&gt;
+ &lt;img src={props.src} alt={props.alt} /&gt;
+ &lt;figcaption&gt;{props.byline}&lt;/figcaption&gt;
+ &lt;/figure&gt;
+ );
+}</pre>
+
+<p><code>{props.src}</code>, <code>{props.alt}</code>, and <code>{props.byline}</code> represent where our props will be inserted into the component. To render this component, we would write code like this in the place where we want it rendered (which will probably be inside another component):</p>
+
+<pre class="brush: js notranslate">&lt;AuthorCredit
+ src="./assets/zelda.png"
+ alt="Portrait of Zelda Schiff"
+ byline="Zelda Schiff is editor-in-chief of the Library Times."
+/&gt;</pre>
+
+<p>This will ultimately render the following <code><a href="/en-US/docs/Web/HTML/Element/figure">&lt;figure&gt;</a></code> element in the browser, with its structure as defined in the <code>AuthorCredit</code> component, and its content as defined in the props included on the <code>AuthorCredit</code> component call:</p>
+
+<pre class="brush: html notranslate">&lt;figure&gt;
+ &lt;img
+ src="assets/zelda.png"
+ alt="Portrait of Zelda Schiff"
+ &gt;
+ &lt;figcaption&gt;
+ Zelda Schiff is editor-in-chief of the Library Times.
+ &lt;/figcaption&gt;
+&lt;/figure&gt;</pre>
+
+<h3 id="State">State</h3>
+
+<p>We talked about the concept of <strong>state</strong> in the previous chapter — a robust state-handling mechanism is key to an effective framework, and each component may have data that needs its state controlled. This state will persist in some way as long as the component is in use. Like props, state can be used to affect how a component is rendered.</p>
+
+<p>As an example, consider a button that counts how many times it has been clicked. This component should be responsible for tracking its own <em>count</em> state, and could be written like this:</p>
+
+<pre class="brush: js notranslate">function CounterButton() {
+ const [count] = useState(0);
+ return (
+ &lt;button&gt;Clicked {count} times&lt;/button&gt;
+ );
+}</pre>
+
+<p><code><a href="https://reactjs.org/docs/hooks-reference.html#usestate">useState()</a></code> is a <strong><a href="https://reactjs.org/docs/hooks-intro.html">React hook</a></strong> which, given an initial data value, will keep track of that value as it is updated. The code will be initially rendered like so in the browser:</p>
+
+<pre class="brush: html notranslate">&lt;button&gt;Clicked 0 times&lt;/button&gt;</pre>
+
+<p>The <code>useState()</code> call keeps track of the <code>count</code> value in a robust way across the app, without you needing to write code to do that yourself.</p>
+
+<h3 id="Events">Events</h3>
+
+<p>In order to be interactive, components need ways to respond to browser events, so our applications can respond to our users. Frameworks each provide their own syntax for listening to browser events, which reference the names of the equivalent native browser events.</p>
+
+<p>In React, listening for the <code><a href="/en-US/docs/Web/API/Element/click_event">click</a></code> event requires a special property, <code>onClick</code>. Let’s update our <code>CounterButton</code> code from above to allow it to count clicks:</p>
+
+<pre class="brush: js notranslate">function CounterButton() {
+ const [count, setCount] = useState(0);
+ return (
+ &lt;button onClick={() =&gt; setCount(count + 1)}&gt;Clicked {count} times&lt;/button&gt;
+ );
+}</pre>
+
+<p>In this version we are using additional <code>useState()</code> functionality to create a special <code>setCount()</code> function, which we can invoke to update the value of <code>count</code>. We call this function on line 4, and set <code>count</code> to whatever its current value is, plus one.</p>
+
+<h2 id="Styling_components">Styling components</h2>
+
+<p>Each framework offers a way to define styles for your components — or for the application as a whole. Although each framework’s approach to defining the styles of a component is slightly different, all of them give you multiple ways to do so. With the addition of some helper modules, you can style your framework apps in <a href="https://sass-lang.com/">Sass</a> or <a href="http://lesscss.org/">Less</a>, or transpile your CSS stylesheets with <a href="https://postcss.org/">PostCSS</a>.</p>
+
+<h2 id="Handling_dependencies">Handling dependencies</h2>
+
+<p>All major frameworks provide mechanisms for handling dependencies — using components inside other components, sometimes with multiple hierarchy levels. As with other features, the exact mechanism will differ between frameworks, but the end result is the same. Components tend to import components into other components using the standard <a href="/en-US/docs/Web/JavaScript/Guide/Modules">JavaScript module syntax</a>, or at least something similar.</p>
+
+<h3 id="Components_in_components">Components in components</h3>
+
+<p>One key benefit of component-based UI architecture is that components can be composed together. Just like you can write HTML tags inside each other to build a website, you can use components inside other components to build a web application. Each framework allows you to write components that utilize (and thus depend on) other components.</p>
+
+<p>For example, our <code>AuthorCredit</code> React component might be utilized inside an <code>Article</code> component. That means that <code>Article</code> would need to import <code>AuthorCredit</code>.</p>
+
+<pre class="brush: js notranslate">import AuthorCredit from "./components/AuthorCredit";</pre>
+
+<p>Once that’s done, <code>AuthorCredit</code> could be used inside the <code>Article</code> component like this:</p>
+
+<pre class="brush: js notranslate"> ...
+
+&lt;AuthorCredit /&gt;
+
+ ...</pre>
+
+<h3 id="Dependency_injection">Dependency injection</h3>
+
+<p>Real-world applications can often involve component structures with multiple levels of nesting. An <code>AuthorCredit</code> component nested many levels deep might, for some reason, need data from the very root level of our application.</p>
+
+<p>Let's say that the magazine site we're building is structured like this:</p>
+
+<pre class="brush: js notranslate">&lt;App&gt;
+ &lt;Home&gt;
+ &lt;Article&gt;
+ &lt;AuthorCredit {/* props */} /&gt;
+ &lt;/Article&gt;
+ &lt;/Home&gt;
+&lt;/App&gt;</pre>
+
+<p>Our <code>App</code> component has data that our <code>AuthorCredit</code> component needs. We could rewrite <code>Home</code> and <code>Article</code> so that they know to pass props down, but this could get tedious if there are many, many levels between the origin and destination of our data. It's also excessive: <code>Home</code> and <code>Article</code> don’t actually make use of the author's portrait or byline, but if we want to get that information into the <code>AuthorCredit</code>, we will need to change <code>Home</code> and <code>Author</code> to accommodate it.</p>
+
+<p>The problem of passing data through many layers of components is called prop drilling, and it’s not ideal for large applications.</p>
+
+<p>To circumvent prop drilling, frameworks provide functionality known as dependency injection, which is a way to get certain data directly to the components that need it, without passing it through intervening levels. Each framework implements dependency injection under a different name, and in a different way, but the effect is ultimately the same.</p>
+
+<p>Angular calls this process <a href="https://angular.io/guide/dependency-injection">dependency injection</a>; Vue has <a href="https://vuejs.org/v2/api/#provide-inject"><code>provide()</code> and <code>inject()</code> component methods</a>; React has a <a href="https://reactjs.org/docs/context.html">Context API</a>; Ember shares state through <a href="https://guides.emberjs.com/release/services/">services</a>.</p>
+
+<h3 id="Lifecycle">Lifecycle</h3>
+
+<p>In the context of a framework, a component’s <strong>lifecycle</strong> is a collection of phases a component goes through from the time it is rendered by the browser (often called <em>mounting</em>) to the time that it is removed from the DOM (often called <em>unmounting</em>). Each framework names these lifecycle phases differently, and not all give developers access to the same phases. All of the frameworks follow the same general model: they allow developers to perform certain actions when the component <em>mounts</em>, when it <em>renders</em>, when it <em>unmounts</em>, and at many phases in between these.</p>
+
+<p>The <em>render</em> phase is the most crucial to understand, because it is repeated the most times as your user interacts with your application. It's run every time the browser needs to render something new, whether that new information is an addition to what's in the browser, a deletion, or an edit of what’s there.</p>
+
+<p>This <a href="http://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/">diagram of a React component's lifecycle</a> offers a general overview of the concept.</p>
+
+<h2 id="Rendering_elements">Rendering elements</h2>
+
+<p>Just as with lifecycles, frameworks take different-but-similar approaches to how they render your applications. All of them track the current rendered version of your browser's DOM, and each makes slightly different decisions about how the DOM should change as components in your application re-render. Because frameworks make these decisions for you, you typically don't interact with the DOM yourself. This abstraction away from the DOM is more complex and more memory-intensive than updating the DOM yourself, but without it, frameworks could not allow you to program in the declarative way they’re known for.</p>
+
+<p>The <strong>Virtual DOM</strong> is an approach whereby information about your browser's DOM is stored in JavaScript memory. Your application updates this copy of the DOM, then compares it to the "real" DOM — the DOM that is actually rendered for your users — in order to decide what to render. The application builds a "diff" to compare the differences between the updated virtual DOM and the currently rendered DOM, and uses that diff to apply updates to the real DOM. Both React and Vue utilize a virtual DOM model, but they do not apply the exact same logic when diffing or rendering.</p>
+
+<p>You can <a href="https://reactjs.org/docs/faq-internals.html#what-is-the-virtual-dom">read more about the Virtual DOM in the React docs</a>.</p>
+
+<p>The <strong>Incremental DOM</strong> is similar to the virtual DOM in that it builds a DOM diff to decide what to render, but different in that it doesn't create a complete copy of the DOM in JavaScript memory. It ignores the parts of the DOM that do not need to be changed. Angular is the only framework discussed so far in this module that uses an incremental DOM.</p>
+
+<p>You can <a href="https://auth0.com/blog/incremental-dom/">read more about the Incremental DOM on the Auth0 blog</a>.</p>
+
+<p>The <strong>Glimmer VM</strong> is unique to Ember. It is not a virtual DOM nor an incremental DOM; it is a separate process through which Ember's templates are transpiled into a kind of "byte code" that is easier and faster to read than JavaScript.</p>
+
+<h2 id="Routing">Routing</h2>
+
+<p>As <a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Introduction#Routing">mentioned in the previous chapter, routing</a> is an important part of the web experience. To avoid a broken experience in sufficiently complex apps with lots of views, each of the frameworks covered in this module provides a library (or more than one library) that helps developers implement client-side routing in their applications.</p>
+
+<h2 id="Testing">Testing</h2>
+
+<p>All applications benefit from test coverage that ensures your software continues to behave in the way that you'd expect, and web applications are no different. Each framework's ecosystem provides tooling that facilitates the writing of tests. Testing tools are not built into the frameworks themselves, but the command-line interface tools used to generate framework apps give you access to the appropriate testing tools.</p>
+
+<p>Each framework has extensive tools in its ecosystem, with capabilities for unit and integration testing alike.</p>
+
+<p><a href="https://testing-library.com/">Testing Library</a> is a suite of testing utilities that has tools for many JavaScript environments, including React, Vue, and Angular.  The Ember docs cover the <a href="https://guides.emberjs.com/release/testing/">testing of Ember apps</a>.</p>
+
+<p>Here’s a quick test for our <code>CounterButton</code> written with the help of React Testing Library — it tests a number of things, such as the button's existence, and whether the button is displaying the correct text after being clicked 0, 1, and 2 times:</p>
+
+<pre class="brush: js notranslate">import React from "react";
+import { render, fireEvent } from "@testing-library/react";
+import "@testing-library/jest-dom/extend-expect";
+
+import CounterButton from "./CounterButton";
+
+it("renders a semantic with an initial state of 0", () =&gt; {
+ const { getByRole } = render(&lt;CounterButton /&gt;);
+ const btn = getByRole("button");
+
+ expect(btn).toBeInTheDocument();
+ expect(btn).toHaveTextContent("Clicked 0 times");
+});
+
+it("Increments the count when clicked", () =&gt; {
+ const { getByRole } = render(&lt;CounterButton /&gt;);
+ const btn = getByRole("button");
+
+ fireEvent.click(btn);
+ expect(btn).toHaveTextContent("Clicked 1 times");
+
+ fireEvent.click(btn);
+ expect(btn).toHaveTextContent("Clicked 2 times");
+});</pre>
+
+<h2 id="Summary">Summary</h2>
+
+<p>At this point you should have more of an idea about the actual languages, features, and tools you'll be using as you create applications with frameworks. I'm sure you’re enthusiastic to get going and actually do some coding, and that's what you are going to do next! At this point you can choose which framework you'd like to start learning first:</p>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_getting_started">React</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_getting_started">Ember</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_getting_started">Vue</a></li>
+</ul>
+
+<div class="blockIndicator note">
+<p><strong>Note</strong>: We only have three framework tutorial series available now, but we hope to have more available in the future.</p>
+</div>
+
+<p>{{PreviousMenuNext("Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Introduction","Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_getting_started", "Learn/Tools_and_testing/Client-side_JavaScript_frameworks")}}</p>
+
+<h2 id="In_this_module">In this module</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Introduction">Introduction to client-side frameworks</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Main_features">Framework main features</a></li>
+ <li>React
+ <ul>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_getting_started">Getting started with React</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_todo_list_beginning">Beginning our React todo list</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_components">Componentizing our React app</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_interactivity_events_state">React interactivity: Events and state</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_interactivity_filtering_conditional_rendering">React interactivity: Editing, filtering, conditional rendering</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_accessibility">Accessibility in React</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_resources">React resources</a></li>
+ </ul>
+ </li>
+ <li>Ember
+ <ul>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_getting_started">Getting started with Ember</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_structure_componentization">Ember app structure and componentization</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_interactivity_events_state">Ember interactivity: Events, classes and state</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_conditional_footer">Ember Interactivity: Footer functionality, conditional rendering</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_routing">Routing in Ember</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_resources">Ember resources and troubleshooting</a></li>
+ </ul>
+ </li>
+ <li>Vue
+ <ul>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_getting_started">Getting started with Vue</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_first_component">Creating our first Vue component</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_rendering_lists">Rendering a list of Vue components</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_methods_events_models">Adding a new todo form: Vue events, methods, and models</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_styling">Styling Vue components with CSS</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_computed_properties">Using Vue computed properties</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_conditional_rendering">Vue conditional rendering: editing existing todos</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_refs_focus_management">Focus management with Vue refs</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_resources">Vue resources</a></li>
+ </ul>
+ </li>
+ <li>Svelte
+ <ul>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_getting_started">Getting started with Svelte</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_Todo_list_beginning">Starting our Svelte Todo list app</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_variables_props">Dynamic behavior in Svelte: working with variables and props</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_components">Componentizing our Svelte app</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_reactivity_lifecycle_accessibility">Advanced Svelte: Reactivity, lifecycle, accessibility</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_stores">Working with Svelte stores</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_TypeScript">TypeScript support in Svelte</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_deployment_next">Deployment and next steps</a></li>
+ </ul>
+ </li>
+</ul>
diff --git a/files/fr/learn/tools_and_testing/client-side_javascript_frameworks/react_getting_started/index.html b/files/fr/learn/tools_and_testing/client-side_javascript_frameworks/react_getting_started/index.html
new file mode 100644
index 0000000000..75316fd64e
--- /dev/null
+++ b/files/fr/learn/tools_and_testing/client-side_javascript_frameworks/react_getting_started/index.html
@@ -0,0 +1,468 @@
+---
+title: Démarrer avec React
+slug: >-
+ Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_getting_started
+tags:
+ - Apprendre
+ - Débutant
+ - Frameworks
+ - JavaScript
+ - React
+ - jsx
+ - props
+translation_of: >-
+ Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_getting_started
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Main_features","Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_todo_list_beginning", "Learn/Tools_and_testing/Client-side_JavaScript_frameworks")}}</div>
+
+<p class="summary">In this article we will say hello to React. We'll discover a little bit of detail about its background and use cases, set up a basic React toolchain on our local computer, and create and play with a simple starter app, learning a bit about how React works in the process.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Prerequisites:</th>
+ <td>
+ <p>Familiarity with the core <a href="/en-US/docs/Learn/HTML">HTML</a>, <a href="/en-US/docs/Learn/CSS">CSS</a>, and <a href="/en-US/docs/Learn/JavaScript">JavaScript</a> languages, knowledge of the <a href="/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Command_line">terminal/command line</a>.</p>
+
+ <p>React uses an HTML-in-JavaScript syntax called JSX (JavaScript and XML). Familiarity with both HTML and JavaScript will help you to learn JSX, and better identify whether bugs in your application are related to JavaScript or to the more specific domain of React.</p>
+ </td>
+ </tr>
+ <tr>
+ <th scope="row">Objective:</th>
+ <td>To setup a local React development environment, create a start app, and understand the basics of how it works</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Hello_React">Hello React</h2>
+
+<p>As its official tagline states, <a href="https://reactjs.org/">React</a> is a library for building user interfaces. React is not a framework – it's not even exclusive to the web. It's used with other libraries to render to certain environments. For instance, <a href="https://reactnative.dev/">React Native</a> can be used to build mobile applications; <a href="https://facebook.github.io/react-360/">React 360</a> can be used to build virtual reality applications; and there are other possibilities besides.</p>
+
+<p>To build for the web, developers use React in tandem with <a href="https://reactjs.org/docs/react-dom.html">ReactDOM</a>. React and ReactDOM are often discussed in the same spaces as, and utilized to solve the same problems as, other true web development frameworks. When we refer to React as a "framework", we’re working with that colloquial understanding.</p>
+
+<p>React's primary goal is to minimize the bugs that occur when developers are building UIs. It does this through the use of components — self-contained, logical pieces of code that describe a portion of the user interface. These components can be composed together to create a full UI, and React abstracts away much of the rendering work, leaving you to concentrate on the UI design.</p>
+
+<h2 id="Use_cases">Use cases</h2>
+
+<p>Unlike the other frameworks covered in this module, React does not enforce strict rules around code conventions or file organization. This allows teams to set conventions that work best for them, and to adopt React in any way they would like to. React can handle a single button, a few pieces of an interface, or an app's entire user interface.</p>
+
+<p>While React <em>can</em> be used for <a href="https://reactjs.org/docs/add-react-to-a-website.html">small pieces of an interface</a>, it's not as easy to "drop into" an application as a library like jQuery, or even a framework like Vue — it is more approachable when you build your entire app with React.</p>
+
+<p>In addition, many of the developer-experience benefits of a React app, such as writing interfaces with JSX, require a compilation process. Adding a compiler like Babel to a website makes the code on it run slowly, so developers often set up such tooling with a build step. React arguably has a heavy tooling requirement, but it can be learnt.</p>
+
+<p>This article is going to focus on the use case of using React to render the entire user interface of an application, using tooling provided by Facebook’s own <a href="https://create-react-app.dev/">create-react-app</a> tool.</p>
+
+<h2 id="How_does_React_use_JavaScript">How does React use JavaScript?</h2>
+
+<p>React utilizes features of modern JavaScript for many of its patterns. Its biggest departure from JavaScript comes with the use of <a href="https://reactjs.org/docs/introducing-jsx.html">JSX</a> syntax. JSX extends JavaScript's syntax so that HTML-like code can live alongside it. For example:</p>
+
+<pre class="brush: js notranslate">const heading = &lt;h1&gt;Mozilla Developer Network&lt;/h1&gt;;</pre>
+
+<p>This heading constant is known as a <strong>JSX expression</strong>. React can use it to render that <code><a href="/en-US/docs/Web/HTML/Element/Heading_Elements">&lt;h1&gt;</a></code> tag in our app.</p>
+
+<p>Suppose we wanted to wrap our heading in a <code><a href="/en-US/docs/Web/HTML/Element/header">&lt;header&gt;</a></code> tag, for semantic reasons? The JSX approach allows us to nest our elements within each other, just like we do with HTML:</p>
+
+<pre class="brush: js notranslate">const header = (
+ &lt;header&gt;
+ &lt;h1&gt;Mozilla Developer Network&lt;/h1&gt;
+ &lt;/header&gt;
+);</pre>
+
+<div class="blockIndicator note">
+<p><strong>Note</strong>: The parentheses in the previous snippet aren't unique to JSX, and don’t have any effect on your application. They're a signal to you (and your computer) that the multiple lines of code inside are part of the same expression. You could just as well write the header expression like this:</p>
+
+<pre class="brush: js notranslate">const header = &lt;header&gt;
+ &lt;h1&gt;Mozilla Developer Network&lt;/h1&gt;
+&lt;/header&gt;</pre>
+
+<p>However, this looks kind of awkward, because the <code><a href="/en-US/docs/Web/HTML/Element/header">&lt;header&gt;</a></code> tag that starts the expression is not indented to the same position as its corresponding closing tag.</p>
+</div>
+
+<p>Of course, your browser can't read JSX without help. When compiled (using a tool like <a href="https://babeljs.io/">Babel</a> or <a href="https://parceljs.org/">Parcel</a>), our header expression would look like this:</p>
+
+<pre class="brush: js notranslate">const header = React.createElement("header", null,
+ React.createElement("h1", null, "Mozilla Developer Network")
+);</pre>
+
+<p>It's <em>possible</em> to skip the compilation step and use <code><a href="https://reactjs.org/docs/react-api.html#createelement">React.createElement()</a></code> to write your UI yourself. In doing this, however, you lose the declarative benefit of JSX, and your code becomes harder to read. Compilation is an extra step in the development process, but many developers in the React community think that the readability of JSX is worthwhile. Plus, popular tooling makes JSX-to-JavaScript compilation part of its setup process. You don't have to configure compilation yourself unless you want to.</p>
+
+<p>Because JSX is a blend of HTML and JavaScript, some developers find it intuitive. Others say that its blended nature makes it confusing. Once you're comfortable with it, however, it will allow you build user interfaces more quickly and intuitively, and allow others to better understand your code base at a glance.</p>
+
+<p>To read more about JSX, check out the React team's <a href="https://reactjs.org/docs/jsx-in-depth.html">JSX In Depth</a> article.</p>
+
+<h2 id="Setting_up_your_first_React_app">Setting up your first React app</h2>
+
+<p>There are many ways to use React, but we're going to use the command-line interface (CLI) tool create-react-app, as mentioned earlier, which expedites the process of developing a React application by installing some packages and creating some files for you, handling the tooling described above.</p>
+
+<p>It's possible to <a href="https://reactjs.org/docs/add-react-to-a-website.html">add React to a website without create-react-app</a> by copying some <code><a href="/en-US/docs/Web/HTML/Element/script">&lt;script&gt;</a></code> elements into an HTML file, but the create-react-app CLI is a common starting point for React applications. Using it will allow you spend more time building your app, and less time fussing with setup.</p>
+
+<h3 id="Requirements">Requirements</h3>
+
+<p>In order to use create-react-app, you need to have <a href="https://nodejs.org/en/">Node.js</a> installed. It's recommended that you use the long-term support (LTS) version. Node includes npm (the node package manager), and npx (the node package runner).</p>
+
+<p>You may also use the Yarn package manager as an alternative, but we'll assume you are using npm in this set of tutorials. See <a href="/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Package_management">Package management basics</a> for more information on npm and yarn.</p>
+
+<p>If you're using Windows, you will need to install some software to give you parity with Unix/macOS terminal in order to use the terminal commands mentioned in this tutorial. <strong>Gitbash</strong> (which comes as part of the <a href="https://gitforwindows.org/">git for Windows toolset</a>) or <strong><a href="https://docs.microsoft.com/en-us/windows/wsl/about">Windows Subsystem for Linux</a></strong> (<strong>WSL</strong>) are both suitable. See <a href="/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Command_line">Command line crash course</a> for more information on these, and on terminal commands in general.</p>
+
+<p>Also bear in mind that React and ReactDOM produce apps that only work on a fairly modern set of browsers — IE9+ by way of some polyfills. It is recommended that you use a modern browser like Firefox, Safari, or Chrome when working through these tutorials.</p>
+
+<p>Also see the following for more information:</p>
+
+<ul>
+ <li><a href="https://nodejs.org/en/knowledge/getting-started/npm/what-is-npm/">"What is npm" on nodejs.org</a></li>
+ <li><a href="https://blog.npmjs.org/post/162869356040/introducing-npx-an-npm-package-runner">"Introducing npx" on the npm blog</a></li>
+ <li><a href="https://create-react-app.dev/">The create-react-app documentation</a></li>
+</ul>
+
+<h3 id="Initializing_your_app">Initializing your app</h3>
+
+<p>create-react-app takes one argument: the name you'd like to give your app. create-react-app uses this name to make a new directory, then creates the necessary files inside it. Make sure you <code>cd</code> to the place you'd like your app to live on your hard drive, then run the following in your terminal:</p>
+
+<pre class="brush: bash notranslate">npx create-react-app moz-todo-react</pre>
+
+<p>This creates a <code>moz-todo-react</code> directory, and does several things inside it:</p>
+
+<ul>
+ <li>Installs some npm packages essential to the functionality of the app.</li>
+ <li>Writes scripts for starting and serving the application.</li>
+ <li>Creates a structure of files and directories that define the basic app architecture.</li>
+ <li>Initializes the directory as a git repository, if you have git installed on your computer.</li>
+</ul>
+
+<div class="blockIndicator note">
+<p><strong>Note</strong>: if you have the yarn package manager installed, create-react-app will default to using it instead of npm. If you have both package managers installed and explicitly want to use NPM, you can add the flag <code>--use-npm</code> when you run create-react-app:</p>
+
+<pre class="brush: bash notranslate">npx create-react-app moz-todo-react --use-npm</pre>
+</div>
+
+<p>create-react-app will display a number of messages in your terminal while it works; this is normal! This might take a few minutes, so now might be a good time to go make a cup of tea.</p>
+
+<p>When the process is complete, <code>cd</code> into the <code>moz-todo-react</code> directory and run the command <code>npm start</code>. The scripts installed by create-react-app will start being served at a local server at localhost:3000, and open the app in a new browser tab. Your browser will display something like this:</p>
+
+<p><img alt="Screenshot of Firefox MacOS, open to localhost:3000, showing the default create-react-app application" src="https://mdn.mozillademos.org/files/17203/default-create-react-app.png" style="border-style: solid; border-width: 1px; height: 980px; width: 1600px;"></p>
+
+<h3 id="Application_structure">Application structure</h3>
+
+<p>create-react-app gives us everything we need to develop a React application. Its initial file structure looks like this:</p>
+
+<pre class="notranslate">moz-todo-react
+├── README.md
+├── node_modules
+├── package.json
+├── package-lock.json
+├── .gitignore
+├── public
+│ ├── favicon.ico
+│ ├── index.html
+│ └── manifest.json
+└── src
+ ├── App.css
+ ├── App.js
+ ├── App.test.js
+ ├── index.css
+ ├── index.js
+ ├── logo.svg
+ └── serviceWorker.js</pre>
+
+<p>The <strong><code>src</code></strong> directory is where we'll spend most of our time, as it's where the source code for our application lives.</p>
+
+<p>The <strong><code>public</code></strong> directory contains files that will be read by your browser while you're developing the app; the most important of these is <code>index.html</code>. React injects your code into this file so that your browser can run it. There's some other markup that helps create-react-app function, so take care not to edit it unless you know what you're doing. You very much should change the text inside the <code><a href="/en-US/docs/Web/HTML/Element/title">&lt;title&gt;</a></code> element in this file to reflect the title of your application. Accurate page titles are important for accessibility!</p>
+
+<p>The <code>public</code> directory will also be published when you build and deploy a production version of your app. We won’t cover deployment in this tutorial, but you should be able to use a similar solution to that described in our <a href="/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Deployment">Deploying our app</a> tutorial.</p>
+
+<p>The <code>package.json</code> file contains information about our project that Node.js/npm uses to keep it organized. This file is not unique to React applications; create-react-app merely populates it. You don't need to understand this file at all to complete this tutorial, however, if you'd like to learn more about it, you can read <a href="https://nodejs.org/en/knowledge/getting-started/npm/what-is-the-file-package-json/">What is the file `package.json`? on NodeJS.org</a>; we also talk about it in our <a href="/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Package_management">Package management basics</a> tutorial.</p>
+
+<h2 id="Exploring_our_first_React_component_—_&lt;App>">Exploring our first React component — <code>&lt;App/&gt;</code></h2>
+
+<p>In React, a <strong>component</strong> is a reusable module that renders a part of our app. These parts can be big or small, but they are usually clearly defined: they serve a single, obvious purpose.</p>
+
+<p>Let's open <code>src/App.js</code>, since our browser is prompting us to edit it. This file contains our first component, <code>App</code>, and a few other lines of code:</p>
+
+<pre class="brush: js notranslate">import React from 'react';
+import logo from './logo.svg';
+import './App.css';
+
+function App() {
+ return (
+ &lt;div className="App"&gt;
+ &lt;header className="App-header"&gt;
+ &lt;img src={logo} className="App-logo" alt="logo" /&gt;
+ &lt;p&gt;
+ Edit &lt;code&gt;src/App.js&lt;/code&gt; and save to reload.
+ &lt;/p&gt;
+ &lt;a
+ className="App-link"
+ href="https://reactjs.org"
+ target="_blank"
+ rel="noopener noreferrer"
+ &gt;
+ Learn React
+ &lt;/a&gt;
+ &lt;/header&gt;
+ &lt;/div&gt;
+ );
+}
+export default App;</pre>
+
+<p>The <code>App.js</code> file consists of three main parts: some <code><a href="/en-US/docs/Web/JavaScript/Reference/Statements/import">import</a></code> statements at the top, the <code>App</code> component in the middle, and an <code><a href="/en-US/docs/Web/JavaScript/Reference/Statements/export">export</a></code> statement at the bottom. Most React components follow this pattern.</p>
+
+<h3 id="Import_statements">Import statements</h3>
+
+<p>The <code>import</code> statements at the top of the file allow <code>App.js</code> to use code that has been defined elsewhere. Let's look at these statements more closely.</p>
+
+<pre class="brush: js notranslate">import React from 'react';
+import logo from './logo.svg';
+import './App.css';</pre>
+
+<p>The first statement imports the React library itself. Because React turns the JSX we write into <code>React.createElement()</code>, all React components must import the <code>React</code> module. If you skip this step, your application will produce an error.</p>
+
+<p>The second statement imports a logo from <code>'./logo.svg'</code>. Note the <code>./</code> at the beginning of the path, and the <code>.svg</code> extension at the end — these tell us that the file is local and that it is not a JavaScript file. Indeed, the <code>logo.svg</code> file lives in our source directory.</p>
+
+<p>We don't write a path or extension when importing the <code>React</code> module — this is not a local file; instead, it is listed as a dependency in our <code>package.json</code> file. Be careful of this distinction as you work through this lesson!</p>
+
+<p>The third statement imports the CSS related to our App component. Note that there is no variable name and no <code>from</code> directive. This particular import syntax is not native to JavaScript module syntax – it comes from Webpack, the tool create-react-app uses to bundle all our JavaScript files together and serve them to the browser.</p>
+
+<h3 id="The_App_component">The <code>App</code> component</h3>
+
+<p>After the imports, we have a function named <code>App</code>. Whereas most of the JavaScript community prefers camel-case names like <code>helloWorld</code>, React components use pascal-case variable names, like <code>HelloWorld</code>, to make it clear that a given JSX element is a React component, and not a regular HTML tag. If you were to rename the <code>App</code> function to <code>app</code>, your browser would show you an error.</p>
+
+<p>Let's look at App more closely.</p>
+
+<pre class="brush: js notranslate">function App() {
+ return (
+ &lt;div className="App"&gt;
+ &lt;header className="App-header"&gt;
+ &lt;img src={logo} className="App-logo" alt="logo" /&gt;
+ &lt;p&gt;
+ Edit &lt;code&gt;src/App.js&lt;/code&gt; and save to reload.
+ &lt;/p&gt;
+ &lt;a
+ className="App-link"
+ href="https://reactjs.org"
+ target="_blank"
+ rel="noopener noreferrer"
+ &gt;
+ Learn React
+ &lt;/a&gt;
+ &lt;/header&gt;
+ &lt;/div&gt;
+ );
+}</pre>
+
+<p>The <code>App</code> function returns a JSX expression. This expression defines what your browser ultimately renders to the DOM.</p>
+
+<p>Some elements in the expression have attributes, which are written just like in HTML, following a pattern of <code>attribute="value"</code>. On line 3, the opening <code><a href="/en-US/docs/Web/HTML/Element/div">&lt;div&gt;</a></code> tag has a <code>className</code> attribute. This is the same as the <code><a href="/en-US/docs/Web/HTML/Global_attributes/class">class</a></code> attribute in HTML, but because JSX is JavaScript, we can't use the word <code>class</code> – it's reserved, meaning JavaScript already uses it for a specific purpose and it would cause problems here in our code. A few other HTML attributes are written differently in JSX than they are in HTML too, for the same kind of reason. We'll cover them as we encounter them.</p>
+
+<p>Take a moment to change the <code><a href="/en-US/docs/Web/HTML/Element/p">&lt;p&gt;</a></code> tag on line 6 so that it reads "Hello, world!", then save your file. You'll notice that this change is immediately rendered in the development server running at <code>http://localhost:3000</code> in your browser. Now delete the <code><a href="/en-US/docs/Web/HTML/Element/a">&lt;a&gt;</a></code> tag and save; the "Learn React" link will be gone.</p>
+
+<p>Your <code>App</code> component should now look like this:</p>
+
+<pre class="brush: js notranslate">function App() {
+ return (
+ &lt;div className="App"&gt;
+ &lt;header className="App-header"&gt;
+ &lt;img src={logo} className="App-logo" alt="logo" /&gt;
+ &lt;p&gt;
+ Hello, World!
+ &lt;/p&gt;
+ &lt;/header&gt;
+ &lt;/div&gt;
+ );
+}</pre>
+
+<h3 id="Export_statements">Export statements</h3>
+
+<p>At the very bottom of the <code>App.js</code> file, the statement <code>export default App</code> makes our <code>App</code> component available to other modules.</p>
+
+<h2 id="Interrogating_the_index">Interrogating the index</h2>
+
+<p>Let’s open <code>src/index.js</code>, because that's where the <code>App</code> component is being used. This file is the entry point for our app, and it initially looks like this:</p>
+
+<pre class="brush: js notranslate">import React from 'react';
+import ReactDOM from 'react-dom';
+import './index.css';
+import App from './App';
+import * as serviceWorker from './serviceWorker';
+
+ReactDOM.render(&lt;App /&gt;, document.getElementById('root'));
+
+// If you want your app to work offline and load faster, you can change
+// unregister() to register() below. Note this comes with some pitfalls.
+// Learn more about service workers: https://bit.ly/CRA-PWA
+serviceWorker.unregister();</pre>
+
+<p>As with <code>App.js</code>, the file starts by importing all the JS modules and other assets it needs to run. <code>src/index.css</code> holds global styles that are applied to our whole app. We can also see our <code>App</code> component imported here; it is made available for import thanks to the <code>export</code> statement at the bottom of <code>App.js</code>.</p>
+
+<p>Line 7 calls React’s <code>ReactDOM.render()</code> function with two arguments:</p>
+
+<ul>
+ <li>The component we want to render, <code>&lt;App /&gt;</code> in this case.</li>
+ <li>The DOM element inside which we want the component to be rendered, in this case the element with an ID of <code>root</code>. If you look inside <code>public/index.html</code>, you'll see that this is a <code>&lt;div&gt;</code> element just inside the <code>&lt;body&gt;</code>.</li>
+</ul>
+
+<p>All of this tells React that we want to render our React application with the <code>App</code> component as the root, or first component.</p>
+
+<div class="blockIndicator note">
+<p><strong>Note</strong>: In JSX, React components and HTML elements must have closing slashes. Writing just <code>&lt;App&gt;</code> or just <code>&lt;img&gt;</code> will cause an error.</p>
+</div>
+
+<p><a href="/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers">Service workers</a> are interesting pieces of code that help application performance and allow features of your web applications to work offline, but they’re not in scope for this article. You can delete line 5, as well as lines 9 through 12.</p>
+
+<p>Your final <code>index.js</code> file should look like this:</p>
+
+<pre class="brush: js notranslate">import React from 'react';
+import ReactDOM from 'react-dom';
+import './index.css';
+import App from './App';
+
+ReactDOM.render(&lt;App /&gt;, document.getElementById('root'));</pre>
+
+<h2 id="Variables_and_props">Variables and props</h2>
+
+<p>Next, we'll use a few of our JavaScript skills to get a bit more comfortable editing components and working with data in React. We'll talk about how variables are used inside JSX, and introduce props, which are a way of passing data into a component (which can then be accessed using variables).</p>
+
+<h3 id="Variables_in_JSX">Variables in JSX</h3>
+
+<p>Back in <code>App.js</code>, let’s focus on line 9:</p>
+
+<pre class="brush: js notranslate">&lt;img src={logo} className="App-logo" alt="logo" /&gt;</pre>
+
+<p>Here, the <code>&lt;img /&gt;</code> tag's <code>src</code> attribute value is in curly braces. This is how JSX recognizes variables. React will see <code>{logo}</code>, know you are referring to the logo import on line 2 of our app, then retrieve the logo file and render it.</p>
+
+<p>Let's try making a variable of our own. Before the return statement of <code>App</code>, add <code>const subject = 'React';</code>. Your <code>App</code> component should now look like this:</p>
+
+<pre class="brush: js notranslate">function App() {
+ const subject = "React";
+ return (
+ &lt;div className="App"&gt;
+ &lt;header className="App-header"&gt;
+ &lt;img src={logo} className="App-logo" alt="logo" /&gt;
+ &lt;p&gt;
+ Hello, World!
+ &lt;/p&gt;
+ &lt;/header&gt;
+ &lt;/div&gt;
+ );
+}</pre>
+
+<p>Change line 8 to use our <code>subject</code> variable instead of the word "world", like this:</p>
+
+<pre class="brush: js notranslate">function App() {
+ const subject = "React";
+ return (
+ &lt;div className="App"&gt;
+ &lt;header className="App-header"&gt;
+ &lt;img src={logo} className="App-logo" alt="logo" /&gt;
+ &lt;p&gt;
+ Hello, {subject}!
+ &lt;/p&gt;
+ &lt;/header&gt;
+ &lt;/div&gt;
+ );
+}</pre>
+
+<p>When you save, your browser should display "Hello, React!" instead of "Hello, world!"</p>
+
+<p>Variables are convenient, but the one we've just set doesn’t make great use of React's features. That's where props come in.</p>
+
+<h3 id="Component_props">Component props</h3>
+
+<p>A <strong>prop</strong> is any data passed into a React component. Props are written inside component calls, and use the same syntax as HTML attributes — <code>prop="value"</code>. Let’s open <code>index.js</code> and give our <code>&lt;App/&gt;</code> call its first prop.</p>
+
+<p>Add a prop of <code>subject</code> to the <code>&lt;App/&gt;</code> component call, with a value of <code>Clarice</code>. When you are done, your code should look something like this:</p>
+
+<pre class="brush: js notranslate">ReactDOM.render(&lt;App subject="Clarice" /&gt;, document.getElementById('root'));</pre>
+
+<p>Back in <code>App.js</code>, let's revisit the App function itself, which reads like this (with the <code>return</code> statement shortened for brevity):</p>
+
+<pre class="brush: js notranslate">function App() {
+ const subject = "React";
+ return (
+ // return statement
+ );
+}</pre>
+
+<p>Change the signature of the <code>App</code> function so that it accepts <code>props</code> as a parameter, and delete the <code>subject</code> const. Just like any other function parameter, you can put <code>props</code> in a <code>console.log()</code> to print it to your browser's console. Go ahead and do that before the <code>return</code> statement, like so:</p>
+
+<pre class="brush: js notranslate">function App(props) {
+ console.log(props);
+ return (
+ // return statement
+ );
+}</pre>
+
+<p>Save your file and check your browser's JavaScript console. You should see something like this logged:</p>
+
+<pre class="brush: js notranslate">Object { subject: "Clarice" }</pre>
+
+<p>The object property <code>subject</code> corresponds to the <code>subject</code> prop we added to our <code>&lt;App /&gt;</code> component call, and the string <code>Clarice</code> corresponds to its value. Component props in React are always collected into objects in this fashion.</p>
+
+<p>Now that <code>subject</code> is one of our props, let's utilize it in <code>App.js</code>. Change the <code>subject</code> constant so that, instead of defining it as the string <code>React</code>, you are reading the value of <code>props.subject</code>. You can also delete your <code>console.log()</code> if you want.</p>
+
+<pre class="brush: js notranslate">function App(props) {
+ const subject = props.subject;
+ return (
+ // return statement
+ );
+}</pre>
+
+<p>When you save, the the app should now greet you with "Hello, Clarice!". If you return to <code>index.js</code>, edit the value of <code>subject</code>, and save, your text will change.</p>
+
+<h2 id="Summary">Summary</h2>
+
+<p>This brings us to the end of our initial look at React, including how to install it locally, creating a starter app, and how the basics work. In the next article we'll start building our first proper application — a todo list. Before we do that, however, let's recap some of the things we’ve learned.</p>
+
+<p>In React:</p>
+
+<ul>
+ <li>Components can import modules they need, and must export themselves at the bottom of their files.</li>
+ <li>Component functions are named with <code>PascalCase</code>.</li>
+ <li>You can read JSX variables by putting them between curly braces, like <code>{so}</code>.</li>
+ <li>Some JSX attributes are different to HTML attributes, so that they don't conflict with JavaScript reserved words. For example, <code>class</code> in HTML translates to <code>className</code> in JSX. Note that multi-word attributes are camel-cased.</li>
+ <li>Props are written just like attributes inside component calls, and are passed into components.</li>
+</ul>
+
+<p>{{PreviousMenuNext("Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Main_features","Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_todo_list_beginning", "Learn/Tools_and_testing/Client-side_JavaScript_frameworks")}}</p>
+
+<h2 id="In_this_module">In this module</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Introduction">Introduction to client-side frameworks</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Main_features">Framework main features</a></li>
+ <li>React
+ <ul>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_getting_started">Getting started with React</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_todo_list_beginning">Beginning our React todo list</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_components">Componentizing our React app</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_interactivity_events_state">React interactivity: Events and state</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_interactivity_filtering_conditional_rendering">React interactivity: Editing, filtering, conditional rendering</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_accessibility">Accessibility in React</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_resources">React resources</a></li>
+ </ul>
+ </li>
+ <li>Ember
+ <ul>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_getting_started">Getting started with Ember</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_structure_componentization">Ember app structure and componentization</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_interactivity_events_state">Ember interactivity: Events, classes and state</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_conditional_footer">Ember Interactivity: Footer functionality, conditional rendering</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_routing">Routing in Ember</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_resources">Ember resources and troubleshooting</a></li>
+ </ul>
+ </li>
+ <li>Vue
+ <ul>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_getting_started">Getting started with Vue</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_first_component">Creating our first Vue component</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_rendering_lists">Rendering a list of Vue components</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_methods_events_models">Adding a new todo form: Vue events, methods, and models</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_styling">Styling Vue components with CSS</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_computed_properties">Using Vue computed properties</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_conditional_rendering">Vue conditional rendering: editing existing todos</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_refs_focus_management">Focus management with Vue refs</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_resources">Vue resources</a></li>
+ </ul>
+ </li>
+</ul>
diff --git a/files/fr/learn/tools_and_testing/client-side_javascript_frameworks/react_todo_list_beginning/index.html b/files/fr/learn/tools_and_testing/client-side_javascript_frameworks/react_todo_list_beginning/index.html
new file mode 100644
index 0000000000..a93b2a044c
--- /dev/null
+++ b/files/fr/learn/tools_and_testing/client-side_javascript_frameworks/react_todo_list_beginning/index.html
@@ -0,0 +1,603 @@
+---
+title: Débuter notre React todo list
+slug: >-
+ Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_todo_list_beginning
+tags:
+ - React
+translation_of: >-
+ Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_todo_list_beginning
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_getting_started","Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_components", "Learn/Tools_and_testing/Client-side_JavaScript_frameworks")}}</div>
+
+<p class="summary">Let's say that we’ve been tasked with creating a proof-of-concept in React – an app that allows users to add, edit, and delete tasks they want to work on, and also mark tasks as complete without deleting them. This article will walk you through putting the basic <code>App</code> component structure and styling in place, ready for individual component definition and interactivity, which we'll add later.</p>
+
+<div class="blockIndicator note">
+<p class="summary"><strong>Note</strong>: If you need to check your code against our version, you can find a finished version of the sample React app code in our <a href="https://github.com/mdn/todo-react">todo-react repository</a>. For a running live version, see <a href="https://mdn.github.io/todo-react-build/">https://mdn.github.io/todo-react-build/</a>.</p>
+</div>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Prerequisites:</th>
+ <td>
+ <p>Familiarity with the core <a href="/en-US/docs/Learn/HTML">HTML</a>, <a href="/en-US/docs/Learn/CSS">CSS</a>, and <a href="/en-US/docs/Learn/JavaScript">JavaScript</a> languages, knowledge of the <a href="/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Command_line">terminal/command line</a>.</p>
+ </td>
+ </tr>
+ <tr>
+ <th scope="row">Objective:</th>
+ <td>To introduce our todo list case study, and get the basic <code>App</code> structure and styling in place.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Our_apps_user_stories">Our app's user stories</h2>
+
+<p>In software development, a user story is an actionable goal from the perspective of the user. Defining user stories before we begin our work will help us focus our work. Our app should fulfill the following stories:</p>
+
+<p>As a user, I can</p>
+
+<ul>
+ <li>read a list of tasks.</li>
+ <li>add a task using the mouse or keyboard.</li>
+ <li>mark any task as completed, using the mouse or keyboard.</li>
+ <li>delete any task, using the mouse or keyboard.</li>
+ <li>edit any task, using the mouse or keyboard.</li>
+ <li>view a specific subset of tasks: All tasks, only the active task, or only the completed tasks.</li>
+</ul>
+
+<p>We'll tackle these stories one-by-one.</p>
+
+<h2 id="Pre-project_housekeeping">Pre-project housekeeping</h2>
+
+<p>create-react-app has made a few files we won't be using at all for our project.</p>
+
+<ul>
+ <li>We're not going to write per-component stylesheets, so first delete the <code>App.css</code> import from the top of <code>App.js</code>.</li>
+ <li>We are also not going to be using the <code>logo.svg</code> file, so remove that import too.</li>
+</ul>
+
+<p>Then, copy and paste the following commands into your terminal to delete some unneeded files. Make sure you’re starting in the app's root directory!</p>
+
+<pre class="brush: bash notranslate"># Move into the src directory of your project
+cd src
+# Delete a few files
+rm -- App.test.js App.css logo.svg serviceWorker.js setupTests.js
+# Move back up to the root of the project
+cd ..</pre>
+
+<p>Notes:</p>
+
+<ul>
+ <li>Two of the files we’re deleting are for testing the application. We will not cover testing here.</li>
+ <li>If you stopped your server to do the terminal tasks mentioned above, you’ll have to start it again using <code>npm start</code>.</li>
+</ul>
+
+<h2 id="Project_starter_code">Project starter code</h2>
+
+<p>As a starting point for this project, we're going to provide two things: An <code>App()</code> function to replace the one you have now, and some CSS to style your app.</p>
+
+<h3 id="The_JSX">The JSX</h3>
+
+<p>Copy the following snippet to your clipboard, then paste it into <code>App.js</code> so that it replaces the existing <code>App()</code> function:</p>
+
+<pre class="brush: js notranslate">function App(props) {
+ return (
+ &lt;div className="todoapp stack-large"&gt;
+ &lt;h1&gt;TodoMatic&lt;/h1&gt;
+ &lt;form&gt;
+ &lt;h2 className="label-wrapper"&gt;
+ &lt;label htmlFor="new-todo-input" className="label__lg"&gt;
+ What needs to be done?
+ &lt;/label&gt;
+ &lt;/h2&gt;
+ &lt;input
+ type="text"
+ id="new-todo-input"
+ className="input input__lg"
+ name="text"
+ autoComplete="off"
+ /&gt;
+ &lt;button type="submit" className="btn btn__primary btn__lg"&gt;
+ Add
+ &lt;/button&gt;
+ &lt;/form&gt;
+ &lt;div className="filters btn-group stack-exception"&gt;
+ &lt;button type="button" className="btn toggle-btn" aria-pressed="true"&gt;
+ &lt;span className="visually-hidden"&gt;Show &lt;/span&gt;
+ &lt;span&gt;all&lt;/span&gt;
+ &lt;span className="visually-hidden"&gt; tasks&lt;/span&gt;
+ &lt;/button&gt;
+ &lt;button type="button" className="btn toggle-btn" aria-pressed="false"&gt;
+ &lt;span className="visually-hidden"&gt;Show &lt;/span&gt;
+ &lt;span&gt;Active&lt;/span&gt;
+ &lt;span className="visually-hidden"&gt; tasks&lt;/span&gt;
+ &lt;/button&gt;
+ &lt;button type="button" className="btn toggle-btn" aria-pressed="false"&gt;
+ &lt;span className="visually-hidden"&gt;Show &lt;/span&gt;
+ &lt;span&gt;Completed&lt;/span&gt;
+ &lt;span className="visually-hidden"&gt; tasks&lt;/span&gt;
+ &lt;/button&gt;
+ &lt;/div&gt;
+ &lt;h2 id="list-heading"&gt;
+ 3 tasks remaining
+ &lt;/h2&gt;
+ &lt;ul
+ role="list"
+ className="todo-list stack-large stack-exception"
+ aria-labelledby="list-heading"
+ &gt;
+ &lt;li className="todo stack-small"&gt;
+ &lt;div className="c-cb"&gt;
+ &lt;input id="todo-0" type="checkbox" defaultChecked={true} /&gt;
+ &lt;label className="todo-label" htmlFor="todo-0"&gt;
+ Eat
+ &lt;/label&gt;
+ &lt;/div&gt;
+ &lt;div className="btn-group"&gt;
+ &lt;button type="button" className="btn"&gt;
+ Edit &lt;span className="visually-hidden"&gt;Eat&lt;/span&gt;
+ &lt;/button&gt;
+ &lt;button type="button" className="btn btn__danger"&gt;
+ Delete &lt;span className="visually-hidden"&gt;Eat&lt;/span&gt;
+ &lt;/button&gt;
+ &lt;/div&gt;
+ &lt;/li&gt;
+ &lt;li className="todo stack-small"&gt;
+ &lt;div className="c-cb"&gt;
+ &lt;input id="todo-1" type="checkbox" /&gt;
+ &lt;label className="todo-label" htmlFor="todo-1"&gt;
+ Sleep
+ &lt;/label&gt;
+ &lt;/div&gt;
+ &lt;div className="btn-group"&gt;
+ &lt;button type="button" className="btn"&gt;
+ Edit &lt;span className="visually-hidden"&gt;Sleep&lt;/span&gt;
+ &lt;/button&gt;
+ &lt;button type="button" className="btn btn__danger"&gt;
+ Delete &lt;span className="visually-hidden"&gt;Sleep&lt;/span&gt;
+ &lt;/button&gt;
+ &lt;/div&gt;
+ &lt;/li&gt;
+ &lt;li className="todo stack-small"&gt;
+ &lt;div className="c-cb"&gt;
+ &lt;input id="todo-2" type="checkbox" /&gt;
+ &lt;label className="todo-label" htmlFor="todo-2"&gt;
+ Repeat
+ &lt;/label&gt;
+ &lt;/div&gt;
+ &lt;div className="btn-group"&gt;
+ &lt;button type="button" className="btn"&gt;
+ Edit &lt;span className="visually-hidden"&gt;Repeat&lt;/span&gt;
+ &lt;/button&gt;
+ &lt;button type="button" className="btn btn__danger"&gt;
+ Delete &lt;span className="visually-hidden"&gt;Repeat&lt;/span&gt;
+ &lt;/button&gt;
+ &lt;/div&gt;
+ &lt;/li&gt;
+ &lt;/ul&gt;
+ &lt;/div&gt;
+ );
+}</pre>
+
+<p>Now open <code>public/index.html</code> and change the <code><a href="/en-US/docs/Web/HTML/Element/title">&lt;title&gt;</a></code> element’s text to <code>TodoMatic</code>. This way, it will match the <code><a href="/en-US/docs/Web/HTML/Element/Heading_Elements">&lt;h1&gt;</a></code> at the top of our app.</p>
+
+<pre class="brush: html notranslate">&lt;title&gt;TodoMatic&lt;/title&gt;</pre>
+
+<p>When your browser refreshes, you should see something like this:</p>
+
+<p><img alt="todo-matic app, unstyled, showing a jumbled mess of labels, inputs, and buttons" src="https://mdn.mozillademos.org/files/17253/unstyled-app.png" style="border-style: solid; border-width: 1px; height: 743px; width: 838px;"></p>
+
+<p>It's ugly, and doesn’t function yet, but that's okay — we'll style it in a moment. First, consider the JSX we have, and how it corresponds to our user stories:</p>
+
+<ul>
+ <li>We have a <code><a href="/en-US/docs/Web/HTML/Element/form">&lt;form&gt;</a></code> element, with an <code><a href="/en-US/docs/Web/HTML/Element/input/text">&lt;input type="text"&gt;</a></code> for writing out a new task, and a button to submit the form.</li>
+ <li>We have an array of buttons that will be used to filter our tasks.</li>
+ <li>We have a heading that tells us how many tasks remain.</li>
+ <li>We have our 3 tasks, arranged in an un-ordered list. Each task is a list item (<code><a href="/en-US/docs/Web/HTML/Element/li">&lt;li&gt;</a></code>), and has buttons to edit and delete it and a checkbox to check it off as done.</li>
+</ul>
+
+<p>The form will allow us to <em>make</em> tasks; the buttons will let us <em>filter</em> them; the heading and list are our way to <em>read</em> them. The UI for <em>editing</em> a task is conspicuously absent for now. That's okay – we'll write that later.</p>
+
+<h3 id="Accessibility_features">Accessibility features</h3>
+
+<p>You may notice some unusual attributes here. For example:</p>
+
+<pre class="brush: html notranslate">&lt;button type="button" className="btn toggle-btn" aria-pressed="true"&gt;
+ &lt;span className="visually-hidden"&gt;Show &lt;/span&gt;
+ &lt;span&gt;all&lt;/span&gt;
+ &lt;span className="visually-hidden"&gt; tasks&lt;/span&gt;
+&lt;/button&gt;</pre>
+
+<p>Here, <code>aria-pressed</code> tells assistive technology (like screen readers) that the button can be in one of two states: <code>pressed</code> or <code>unpressed</code>. Think of these as analogs for <code>on</code> and <code>off</code>. Setting a value of <code>true</code> means that the button is pressed by default.</p>
+
+<p>The class <code>visually-hidden</code> has no effect yet, because we have not included any CSS. Once we have put our styles in place, though, any element with this class will be hidden from sighted users and still available to screen reader users — this is because these words are not needed by sighted users; they are there to provide more information about what the button does for screenreader users that do not have the extra visual context to help them.</p>
+
+<p>Further down, you can find our <code><a href="/en-US/docs/Web/HTML/Element/ul">&lt;ul&gt;</a></code> element:</p>
+
+<pre class="brush: html notranslate">&lt;ul
+ role="list"
+ className="todo-list stack-large stack-exception"
+ aria-labelledby="list-heading"
+&gt;</pre>
+
+<p>The <code>role</code> attribute helps assistive technology explain what kind of element a tag represents. A <code>&lt;ul&gt;</code> is treated like a list by default, but the styles we're about to add will break that functionality. This role will restore the "list" meaning to the <code>&lt;ul&gt;</code>  element. If you want to learn more about why this is necessary, you can check out <a href="https://www.scottohara.me/blog/2019/01/12/lists-and-safari.html">Scott O'Hara’s article, “Fixing Lists”</a>.</p>
+
+<p>The <code>aria-labelledby</code> attribute tells assistive technologies that we're treating our list heading as the label that describes the purpose of the list beneath it. Making this association gives the list a more informative context, which could help screen reader users better understand the purpose of it.</p>
+
+<p>Finally, the labels and inputs in our list items have some attributes unique to JSX:</p>
+
+<pre class="brush: html notranslate">&lt;input id="todo-0" type="checkbox" defaultChecked={true} /&gt;
+&lt;label className="todo-label" htmlFor="todo-0"&gt;
+ Eat
+&lt;/label&gt;</pre>
+
+<p>The <code>defaultChecked</code> attribute in the <code>&lt;input/ &gt;</code>  tag tells React to check this checkbox initially. If we were to use <code>checked</code>, as we would in regular HTML, React would log some warnings into our browser console relating to handling events on the checkbox, which we want to avoid. Don't worry too much about this for now — we will cover this later on when we get to using events.</p>
+
+<p>The <code>htmlFor</code> attribute corresponds to the <code>for</code> attribute used in HTML. We cannot use <code>for</code> as an attribute in JSX because <code>for</code> is a reserved word, so  React uses <code>htmlFor</code> instead.</p>
+
+<p>Notes:</p>
+
+<ul>
+ <li>To use boolean values (<code>true</code> and <code>false</code>) in JSX attributes, you must enclose them in curly braces. If you write <code>defaultChecked="true"</code>, the value of <code>defaultChecked</code> will be <code>"true"</code> — a string literal. Remember — this is actually JavaScript, not HTML!</li>
+ <li>The <code>aria-pressed</code> attribute used in our earlier code snippet has a value of <code>"true"</code> because <code>aria-pressed</code> is not a true boolean attribute in the way <code>checked</code> is.</li>
+</ul>
+
+<h3 id="Implementing_our_styles">Implementing our styles</h3>
+
+<p>Paste the following CSS code into <code>src/index.css</code> so that it replaces what's currently there:</p>
+
+<pre class="brush: css notranslate">/* RESETS */
+*,
+*::before,
+*::after {
+ box-sizing: border-box;
+}
+*:focus {
+ outline: 3px dashed #228bec;
+ outline-offset: 0;
+}
+html {
+ font: 62.5% / 1.15 sans-serif;
+}
+h1,
+h2 {
+ margin-bottom: 0;
+}
+ul {
+ list-style: none;
+ padding: 0;
+}
+button {
+ border: none;
+ margin: 0;
+ padding: 0;
+ width: auto;
+ overflow: visible;
+ background: transparent;
+ color: inherit;
+ font: inherit;
+ line-height: normal;
+ -webkit-font-smoothing: inherit;
+ -moz-osx-font-smoothing: inherit;
+ -webkit-appearance: none;
+}
+button::-moz-focus-inner {
+ border: 0;
+}
+button,
+input,
+optgroup,
+select,
+textarea {
+ font-family: inherit;
+ font-size: 100%;
+ line-height: 1.15;
+ margin: 0;
+}
+button,
+input {
+ overflow: visible;
+}
+input[type="text"] {
+ border-radius: 0;
+}
+body {
+ width: 100%;
+ max-width: 68rem;
+ margin: 0 auto;
+ font: 1.6rem/1.25 Arial, sans-serif;
+ background-color: #f5f5f5;
+ color: #4d4d4d;
+}
+@media screen and (min-width: 620px) {
+ body {
+ font-size: 1.9rem;
+ line-height: 1.31579;
+ }
+}
+/*END RESETS*/
+/* GLOBAL STYLES */
+.form-group &gt; input[type="text"] {
+ display: inline-block;
+ margin-top: 0.4rem;
+}
+.btn {
+ padding: 0.8rem 1rem 0.7rem;
+ border: 0.2rem solid #4d4d4d;
+ cursor: pointer;
+ text-transform: capitalize;
+}
+.btn.toggle-btn {
+ border-width: 1px;
+ border-color: #d3d3d3;
+}
+.btn.toggle-btn[aria-pressed="true"] {
+ text-decoration: underline;
+ border-color: #4d4d4d;
+}
+.btn__danger {
+ color: #fff;
+ background-color: #ca3c3c;
+ border-color: #bd2130;
+}
+.btn__filter {
+ border-color: lightgrey;
+}
+.btn__primary {
+ color: #fff;
+ background-color: #000;
+}
+.btn-group {
+ display: flex;
+ justify-content: space-between;
+}
+.btn-group &gt; * {
+ flex: 1 1 49%;
+}
+.btn-group &gt; * + * {
+ margin-left: 0.8rem;
+}
+.label-wrapper {
+ margin: 0;
+ flex: 0 0 100%;
+ text-align: center;
+}
+.visually-hidden {
+ position: absolute !important;
+ height: 1px;
+ width: 1px;
+ overflow: hidden;
+ clip: rect(1px 1px 1px 1px);
+ clip: rect(1px, 1px, 1px, 1px);
+ white-space: nowrap;
+}
+[class*="stack"] &gt; * {
+ margin-top: 0;
+ margin-bottom: 0;
+}
+.stack-small &gt; * + * {
+ margin-top: 1.25rem;
+}
+.stack-large &gt; * + * {
+ margin-top: 2.5rem;
+}
+@media screen and (min-width: 550px) {
+ .stack-small &gt; * + * {
+ margin-top: 1.4rem;
+ }
+ .stack-large &gt; * + * {
+ margin-top: 2.8rem;
+ }
+}
+.stack-exception {
+ margin-top: 1.2rem;
+}
+/* END GLOBAL STYLES */
+.todoapp {
+ background: #fff;
+ margin: 2rem 0 4rem 0;
+ padding: 1rem;
+ position: relative;
+ box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 0 2.5rem 5rem 0 rgba(0, 0, 0, 0.1);
+}
+@media screen and (min-width: 550px) {
+ .todoapp {
+ padding: 4rem;
+ }
+}
+.todoapp &gt; * {
+ max-width: 50rem;
+ margin-left: auto;
+ margin-right: auto;
+}
+.todoapp &gt; form {
+ max-width: 100%;
+}
+.todoapp &gt; h1 {
+ display: block;
+ max-width: 100%;
+ text-align: center;
+ margin: 0;
+ margin-bottom: 1rem;
+}
+.label__lg {
+ line-height: 1.01567;
+ font-weight: 300;
+ padding: 0.8rem;
+ margin-bottom: 1rem;
+ text-align: center;
+}
+.input__lg {
+ padding: 2rem;
+ border: 2px solid #000;
+}
+.input__lg:focus {
+ border-color: #4d4d4d;
+ box-shadow: inset 0 0 0 2px;
+}
+[class*="__lg"] {
+ display: inline-block;
+ width: 100%;
+ font-size: 1.9rem;
+}
+[class*="__lg"]:not(:last-child) {
+ margin-bottom: 1rem;
+}
+@media screen and (min-width: 620px) {
+ [class*="__lg"] {
+ font-size: 2.4rem;
+ }
+}
+.filters {
+ width: 100%;
+ margin: unset auto;
+}
+/* Todo item styles */
+.todo {
+ display: flex;
+ flex-direction: row;
+ flex-wrap: wrap;
+}
+.todo &gt; * {
+ flex: 0 0 100%;
+}
+.todo-text {
+ width: 100%;
+ min-height: 4.4rem;
+ padding: 0.4rem 0.8rem;
+ border: 2px solid #565656;
+}
+.todo-text:focus {
+ box-shadow: inset 0 0 0 2px;
+}
+/* CHECKBOX STYLES */
+.c-cb {
+ box-sizing: border-box;
+ font-family: Arial, sans-serif;
+ -webkit-font-smoothing: antialiased;
+ font-weight: 400;
+ font-size: 1.6rem;
+ line-height: 1.25;
+ display: block;
+ position: relative;
+ min-height: 44px;
+ padding-left: 40px;
+ clear: left;
+}
+.c-cb &gt; label::before,
+.c-cb &gt; input[type="checkbox"] {
+ box-sizing: border-box;
+ top: -2px;
+ left: -2px;
+ width: 44px;
+ height: 44px;
+}
+.c-cb &gt; input[type="checkbox"] {
+ -webkit-font-smoothing: antialiased;
+ cursor: pointer;
+ position: absolute;
+ z-index: 1;
+ margin: 0;
+ opacity: 0;
+}
+.c-cb &gt; label {
+ font-size: inherit;
+ font-family: inherit;
+ line-height: inherit;
+ display: inline-block;
+ margin-bottom: 0;
+ padding: 8px 15px 5px;
+ cursor: pointer;
+ touch-action: manipulation;
+}
+.c-cb &gt; label::before {
+ content: "";
+ position: absolute;
+ border: 2px solid currentColor;
+ background: transparent;
+}
+.c-cb &gt; input[type="checkbox"]:focus + label::before {
+ border-width: 4px;
+ outline: 3px dashed #228bec;
+}
+.c-cb &gt; label::after {
+ box-sizing: content-box;
+ content: "";
+ position: absolute;
+ top: 11px;
+ left: 9px;
+ width: 18px;
+ height: 7px;
+ transform: rotate(-45deg);
+ border: solid;
+ border-width: 0 0 5px 5px;
+ border-top-color: transparent;
+ opacity: 0;
+ background: transparent;
+}
+.c-cb &gt; input[type="checkbox"]:checked + label::after {
+ opacity: 1;
+}</pre>
+
+<p>Save and look back at your browser, and your app should now have reasonable styling.</p>
+
+<h2 id="Summary">Summary</h2>
+
+<p>Now our todo list app actually looks a bit more like a real app! The problem is: it doesn’t actually do anything. We’ll start fixing that in the next chapter!</p>
+
+<p>{{PreviousMenuNext("Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_getting_started","Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_components", "Learn/Tools_and_testing/Client-side_JavaScript_frameworks")}}</p>
+
+<h2 id="In_this_module">In this module</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Introduction">Introduction to client-side frameworks</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Main_features">Framework main features</a></li>
+ <li>React
+ <ul>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_getting_started">Getting started with React</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_todo_list_beginning">Beginning our React todo list</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_components">Componentizing our React app</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_interactivity_events_state">React interactivity: Events and state</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_interactivity_filtering_conditional_rendering">React interactivity: Editing, filtering, conditional rendering</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_accessibility">Accessibility in React</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_resources">React resources</a></li>
+ </ul>
+ </li>
+ <li>Ember
+ <ul>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_getting_started">Getting started with Ember</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_structure_componentization">Ember app structure and componentization</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_interactivity_events_state">Ember interactivity: Events, classes and state</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_conditional_footer">Ember Interactivity: Footer functionality, conditional rendering</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_routing">Routing in Ember</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_resources">Ember resources and troubleshooting</a></li>
+ </ul>
+ </li>
+ <li>Vue
+ <ul>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_getting_started">Getting started with Vue</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_first_component">Creating our first Vue component</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_rendering_lists">Rendering a list of Vue components</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_methods_events_models">Adding a new todo form: Vue events, methods, and models</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_styling">Styling Vue components with CSS</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_computed_properties">Using Vue computed properties</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_conditional_rendering">Vue conditional rendering: editing existing todos</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_refs_focus_management">Focus management with Vue refs</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_resources">Vue resources</a></li>
+ </ul>
+ </li>
+ <li>Svelte
+ <ul>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_getting_started">Getting started with Svelte</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_Todo_list_beginning">Starting our Svelte Todo list app</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_variables_props">Dynamic behavior in Svelte: working with variables and props</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_components">Componentizing our Svelte app</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_reactivity_lifecycle_accessibility">Advanced Svelte: Reactivity, lifecycle, accessibility</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_stores">Working with Svelte stores</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_TypeScript">TypeScript support in Svelte</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_deployment_next">Deployment and next steps</a></li>
+ </ul>
+ </li>
+</ul>
diff --git a/files/fr/learn/tools_and_testing/client-side_javascript_frameworks/vue_getting_started/index.html b/files/fr/learn/tools_and_testing/client-side_javascript_frameworks/vue_getting_started/index.html
new file mode 100644
index 0000000000..71718ed008
--- /dev/null
+++ b/files/fr/learn/tools_and_testing/client-side_javascript_frameworks/vue_getting_started/index.html
@@ -0,0 +1,295 @@
+---
+title: Prise en main de Vue
+slug: Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_getting_started
+translation_of: Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_getting_started
+---
+<div>{{LearnSidebar}}</div>
+
+<div>
+<p>{{PreviousMenuNext("Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_resources","Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_first_component", "Learn/Tools_and_testing/Client-side_JavaScript_frameworks")}}</p>
+</div>
+
+<p class="summary">Présentons Maintenant Vue, le troisième de nos cadres. Dans cet article, nous allons examiner un peu de fond Vue, apprendre à l’installer et créer un nouveau projet, étudier la structure de haut niveau de l’ensemble du projet et un composant individuel, voir comment exécuter le projet localement, et le préparer à commencer à construire notre exemple.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Conditions préalables:</th>
+ <td>
+ <p>Familiarité avec les langages <a href="/en-US/docs/Learn/HTML">HTML</a>, <a href="/en-US/docs/Learn/CSS">CSS</a>et <a href="/en-US/docs/Learn/JavaScript">JavaScript,</a> connaissance de la <a href="/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Command_line">ligne terminal/commande</a>.</p>
+
+ <p>Les composants Vue sont écrits sous la forme d’une combinaison d’objets JavaScript qui gèrent les données de l’application et d’une syntaxe de modèle html qui cartographie la structure DOM sous-jacente. Pour l’installation et pour utiliser certaines des fonctionnalités les plus avancées de Vue (comme les composants de fichier unique ou les fonctions de rendu), vous aurez besoin d’un terminal avec nœud + npm installé.</p>
+ </td>
+ </tr>
+ <tr>
+ <th scope="row">Objectif:</th>
+ <td>Pour configurer un environnement de développement Vue local, créez une application de démarrage et comprenez les bases de son fonctionnement.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Une_Vue_plus_claire">Une Vue plus claire</h2>
+
+<p>Vue est un cadre JavaScript moderne qui fournit des installations utiles pour une amélioration progressive - contrairement à beaucoup d’autres cadres, vous pouvez utiliser Vue pour améliorer html existant. Cela vous permet d’utiliser Vue comme un remplacement de drop-in pour une bibliothèque comme <a href="/en-US/docs/Glossary/jQuery">JQuery</a>.</p>
+
+<p>Cela étant dit, vous pouvez également utiliser Vue pour écrire des applications à page unique entières (SPA). Cela vous permet de créer un balisage géré entièrement par Vue, ce qui peut améliorer l’expérience et les performances des développeurs lors de la gestion d’applications complexes. Il vous permet également de profiter des bibliothèques pour le routage côté client et la gestion de l’État lorsque vous en avez besoin. En outre, Vue adopte une approche « intermédiaire » pour l’outillage comme le routage côté client et la gestion de l’État. Bien que l’équipe de base de Vue gère des bibliothèques suggérées pour ces fonctions, elles ne sont pas directement regroupées dans Vue. Cela vous permet de sélectionner une bibliothèque de routage/gestion d’état différente si elle correspond mieux à votre application.</p>
+
+<p>En plus de vous permettre d’intégrer progressivement Vue dans vos applications, Vue propose également une approche progressive du balisage de l’écriture. Comme la plupart des cadres, Vue vous permet de créer des blocs réutilisables de balisage via des composants. La plupart du temps, les composants Vue sont écrits à l’aide d’une syntaxe de modèle HTML spéciale. Lorsque vous avez besoin de plus de contrôle que ne le permet la syntaxe HTML, vous pouvez écrire des fonctions JSX ou JavaScript simples pour définir vos composants.</p>
+
+<p>Au fur et à mesure que vous travaillez sur ce didacticiel, vous pouvez garder le <a href="https://vuejs.org/v2/guide/">guide Vue</a> et la <a href="https://vuejs.org/v2/api/">documentation API</a> ouverts dans d’autres onglets, de sorte que vous pouvez vous référer à eux si vous voulez plus d’informations sur n’importe quel sous-sujet.<br>
+ Pour une bonne comparaison (mais potentiellement biaisée) entre Vue et plusieurs des autres cadres, voir <a href="https://vuejs.org/v2/guide/comparison.html">Vue Docs: Comparison with Other Frameworks</a>.</p>
+
+<h2 id="Installation">Installation</h2>
+
+<p><font>Pour utiliser Vue dans un site existant, vous pouvez déposer l’un des éléments suivants sur une page. Cela vous permet de commencer à utiliser Vue sur les sites existants, c’est pourquoi Vue se targue d’être un cadre progressif. Il s’agit d’une excellente option lors de la migration d’un projet existant à l’aide d’une bibliothèque comme JQuery à Vue. Avec cette méthode, vous pouvez utiliser un grand nombre des fonctionnalités de base de Vue, telles que les attributs, les composants personnalisés et la gestion des données.</font><code><a href="/en-US/docs/Web/HTML/Element/script">&lt;script&gt;</a></code></p>
+
+<ul>
+ <li>
+ <p>Script de développement (Non optimisé, mais inclut les avertissements de console. Idéal pour le développement</p>
+
+ <pre class="brush: html notranslate">&lt;script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"&gt;&lt;/script&gt;</pre>
+ </li>
+ <li>
+ <p>Production Script (Optimized version, minimal console warnings. It is recommended that you specify a version number when including Vue on your site so that any framework updates do not break your live site without you knowing.)</p>
+
+ <pre class="brush: html notranslate">&lt;script src="https://cdn.jsdelivr.net/npm/vue@2"&gt;&lt;/script&gt;</pre>
+ </li>
+</ul>
+
+<p>However, this approach has some limitations. To build more complex apps, you’ll want to use the <a href="https://www.npmjs.com/package/vue">Vue NPM package</a>. This will let you use advanced features of Vue and take advantage of bundlers like WebPack. To make building apps with Vue easier, there is a CLI to streamline the development process. To use the npm package &amp; the CLI you will need:</p>
+
+<ol>
+ <li>Node.js 8.11+ installed.</li>
+ <li>npm or yarn.</li>
+</ol>
+
+<div class="blockIndicator note">
+<p><strong>Note</strong>: If you don't have the above installed, find out <a href="/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Command_line#Adding_powerups">more about installing npm and Node.js</a> here.</p>
+</div>
+
+<p>To install the CLI, run the following command in your terminal:</p>
+
+<pre class="brush: bash notranslate">npm install --global @vue/cli</pre>
+
+<p>Or if you'd prefer to use yarn:</p>
+
+<pre class="brush: bash notranslate">yarn global add @vue/cli</pre>
+
+<p><font>Once installed, to initialize a new project you can then open a terminal in the directory you want to create the project in, and run . The CLI will then give you a list of project configurations you can use. There are a few preset ones, and you can make your own. These options let you configure things like TypeScript, linting, vue-router, testing, and more.</font><code>vue create &lt;project-name&gt;</code></p>
+
+<p>We’ll look at using this below.</p>
+
+<h2 id="Initializing_a_new_project">Initializing a new project</h2>
+
+<p>To explore various features of Vue, we will be building up a sample todo list app. We'll begin by using the Vue CLI to create a new app framework to build our app into. Follow the steps below:</p>
+
+<ol>
+ <li><font>In terminal, to where you'd like to create your sample app, then run .</font><code>cd</code><code>vue create moz-todo-vue</code></li>
+ <li><font>Use the arrow keys and to select the "Manually select features" option.</font><kbd>Enter</kbd></li>
+ <li><font>The first menu you’ll be presented with allows you to choose which features you want to include in your project. Make sure that "Babel" and "Linter / Formatter" are selected. If they are not, use the arrow keys and the space bar to toggle them on. Once they are selected, press to proceed.</font><kbd>Enter</kbd></li>
+ <li><font>Next you’ll select a config for the linter / formatter. Navigate to "Eslint with error prevention only" and hit again. This will help us catch common errors, but not be overly opinionated.</font><kbd>Enter</kbd></li>
+ <li><font>Next you are asked to configure what kind of automated linting we want. Select "Lint on save". This will check for errors when we save a file inside the project. Hit to continue.</font><kbd>Enter</kbd></li>
+ <li><font>Now, you will select how we want your config files to be managed. "In dedicated config files" will put your config settings for things like ESLint into their own, dedicated files. The other option, "In package.json", will put all of your config settings into the app's file. Select "In dedicated config files" and push .</font><code>package.json</code><kbd>Enter</kbd></li>
+ <li><font>Finally, you are asked if you want to save this as a preset for future options. This is entirely up to you. If you like these settings over the existing presets and want to use them again, type , otherwise type .</font><kbd>y</kbd><kbd>n</kbd></li>
+</ol>
+
+<p>The CLI will now begin scaffolding out your project, and installing all of your dependencies.</p>
+
+<p><font>If you've never run the Vue CLI before, you'll get one more question — you'll be asked to choose a package manager. You can use the arrow keys to select which one you prefer. The Vue CLI will default to this package manager from now on. If you need to use a different package manager after this, you can pass in a flag , when you run .  So if you wanted to create the project with npm and you'd previously chosen yarn, you’d run .</font><code>--packageManager=&lt;package-manager&gt;</code><code>vue create</code><code>moz-todo-vue</code><code>vue create moz-todo-vue --packageManager=npm</code></p>
+
+<div class="blockIndicator note">
+<p><strong>Note</strong>: We've not gone over all of the options here, but you can <a href="https://cli.vuejs.org">find more information on the CLI</a> in the Vue docs.</p>
+</div>
+
+<h2 id="Project_structure">Project structure</h2>
+
+<p>If everything went successfully, the CLI should have created a series of files and directories for your project. The most significant ones are as follows:</p>
+
+<ul>
+ <li><code>.eslintrc.js</code><font>: This is a config file for <a href="https://eslint.org/">eslint</a>. You can use this to manage your linting rules.</font></li>
+ <li><code>babel.config.js</code><font>: This is the config file for <a href="https://babeljs.io/">Babel</a>, which transforms modern JavaScript features being used in development code into older syntax that is more cross-browser compatible in production code. You can register additional babel plugins in this file.</font></li>
+ <li><code>.browserslistrc</code><font>: This is a config for <a href="https://github.com/browserslist/browserslist">Browserslist</a>. You can use this to control which browsers your tooling optimizes for.</font></li>
+ <li><code>public</code><font>: This directory contains static assets that are published, but not processed by <a href="https://webpack.js.org/">Webpack</a> during build (with one exception; gets some processing).</font><code>index.html</code>
+ <ul>
+ <li><code>favicon.ico</code><font>: This is the favicon for your app. Currently, it's the Vue logo.</font></li>
+ <li><code>index.html</code><font>: This is the template for your app. Your Vue app is run from this HTML page, and you can use lodash template syntax to interpolate values into it.</font>
+ <div class="note"><strong>Note</strong>: this is not the template for managing the layout of your application — this template is for managing static HTML that sits outside of your Vue app. Editing this file typically only occurs in advanced use cases.</div>
+ </li>
+ </ul>
+ </li>
+ <li><code>src</code><font>: This directory contains the core of your Vue app.</font>
+ <ul>
+ <li><code>main.js</code><font>: this is the entry point to your application. Currently, this file initializes your Vue application and signifies which HTML element in the file your app should be attached to. This file is often where you register global components or additional Vue libraries.</font><code>index.html</code></li>
+ <li><code>App.vue</code><font>: this is the top-level component in your Vue app. See below for more explanation of Vue components.</font></li>
+ <li><code>components</code><font>: this directory is where you keep your components. Currently it just has one example component.</font></li>
+ <li><code>assets</code><font>: This directory is for storing static assets like CSS and images. Because these files are in the source directory, they can be processed by Webpack. This means you can use pre-processors like <a href="https://sass-lang.com/">Sass/SCSS</a> or <a href="https://stylus-lang.com/">Stylus</a>.</font></li>
+ </ul>
+ </li>
+</ul>
+
+<div class="blockIndicator note">
+<p><font><strong>Note</strong>: Depending on the options you select when creating a new project, there might be other directories present (for example, if you choose a router, you will also have a directory).</font><code>views</code></p>
+</div>
+
+<h2 id=".vue_files_single_file_components">.vue files (single file components)</h2>
+
+<p>Like in many front-end frameworks, components are a central part of building apps in Vue. These components let you break a large application into discrete building blocks that can be created and managed separately, and transfer data between each other as required. These small blocks can help you reason about and test your code.</p>
+
+<p><font>While some frameworks encourage you to separate your template, logic, and styling code into separate files, Vue takes the opposite approach. Using <a href="https://vuejs.org/v2/guide/single-file-components.html">Single File Components</a>, Vue lets you group your templates, corresponding script, and CSS all together in a single file ending in . These files are processed by a JS build tool (such as Webpack), which means you can take advantage of build-time tooling in your project. This allows you to use tools like Babel, TypeScript, SCSS and more to create more sophisticated components.</font><code>.vue</code></p>
+
+<p><font>As a bonus, projects created with the Vue CLI are configured to use files with Webpack out of the box. In fact, if you look inside the folder in the project we created with the CLI, you'll see your first file: .</font><code>.vue</code><code>src</code><code>.vue</code><code>App.vue</code></p>
+
+<p>Let's explore this now.</p>
+
+<h3 id="App.vue">App.vue</h3>
+
+<p><font>Open your file — you’ll see that it has three parts: , , and , which contain the component’s template, scripting, and styling information. All Single File Components share this same basic structure.</font><code>App.vue</code><code>&lt;template&gt;</code><code>&lt;script&gt;</code><code>&lt;style&gt;</code></p>
+
+<p><code>&lt;template&gt;</code><font> contains all the markup structure and display logic of your component. Your template can contain any valid HTML, as well as some Vue-specific syntax that we'll cover later.</font></p>
+
+<div class="blockIndicator note">
+<p><font><strong>Note</strong>: By setting the attribute on the tag, you can use Pug template syntax instead of standard HTML — . We'll stick to standard HTML through this tutorial, but it is worth knowing that this is possible.</font><code>lang</code><code>&lt;template&gt;</code><code>&lt;template lang="pug"&gt;</code></p>
+</div>
+
+<p><code>&lt;script&gt;</code><font> contains all of the non-display logic of your component. Most importantly, your tag needs to have a default exported JS object. This object is where you locally register components, define component inputs (props), handle local state, define methods, and more. Your build step will process this object and transform it (with your template) into a Vue component with a function.</font><code>&lt;script&gt;</code><code>render()</code></p>
+
+<p><font>In the case of , our default export sets the name of the component to and registers the component by adding it into the property. When you register a component in this way, you're registering it locally. Locally registered components can only be used inside the components that register them, so you need to import and register them in every component file that uses them. This can be useful for bundle splitting/tree shaking since not every page in your app necessarily needs every component.</font><code>App.vue</code><code>app</code><code>HelloWorld</code><code>components</code></p>
+
+<pre class="brush: js notranslate">import HelloWorld from './components/HelloWorld.vue';
+
+export default {
+ name: 'app',
+ components: {
+ //You can register components locally here.
+ HelloWorld
+ }
+};</pre>
+
+<div class="blockIndicator note">
+<p><font><strong>Note</strong>: If you want to use <a href="https://www.typescriptlang.org/">TypeScript</a> syntax, you need to set the attribute on the tag to signify to the compiler that you're using TypeScript — .</font><code>lang</code><code>&lt;script&gt;</code><code>&lt;script lang="ts"&gt;</code></p>
+</div>
+
+<p><code>&lt;style&gt;</code><font> is where you write your CSS for the component. If you add a attribute — — Vue will scope the styles to the contents of your SFC. This works similar to CSS-in-JS solutions, but allows you to just write plain CSS.</font><code>scoped</code><code>&lt;style scoped&gt;</code></p>
+
+<div class="blockIndicator note">
+<p><font><strong>Note</strong>: If you select a CSS pre-processor when creating the project via the CLI, you can add a attribute to the tag so that the contents can be processed by Webpack at build time. For example, will allow you to use SCSS syntax in your styling information.</font><code>lang</code><code>&lt;style&gt;</code><code>&lt;style lang="scss"&gt;</code></p>
+</div>
+
+<h2 id="Running_the_app_locally">Running the app locally</h2>
+
+<p><font>The Vue CLI comes with a built-in development server. This allows you to run your app locally so you can test it easily without needing to configure a server yourself. The CLI adds a command to the project’s file as an npm script, so you can easily run it.</font><code>serve</code><code>package.json</code></p>
+
+<p><font>In your terminal, try running (or if you prefer yarn). Your terminal should output something like the following:</font><code>npm run serve</code><code>yarn serve</code></p>
+
+<pre class="notranslate">INFO Starting development server...
+98% after emitting CopyPlugin
+
+ DONE Compiled successfully in 18121ms
+
+ App running at:
+ - Local: &lt;http://localhost:8080/&gt;
+ - Network: &lt;http://192.168.1.9:8080/&gt;
+
+ Note that the development build is not optimized.
+ To create a production build, run npm run build.</pre>
+
+<p><font>If you navigate to the “local” address in a new browser tab (this should be something like as stated above, but may vary based on your setup), you should see your app. Right now, it should contain a welcome message, a link to the Vue documentation, links to the plugins you added when you initialized the app with your CLI, and some other useful links to the Vue community and ecosystem.</font><code>http://localhost:8080</code></p>
+
+<p><img alt="default vue app render, with vue logo, welcome message, and some documentation links" src="https://mdn.mozillademos.org/files/17240/vue-default-app.png" style="border-style: solid; border-width: 1px; height: 779px; width: 1600px;"></p>
+
+<h2 id="Making_a_couple_of_changes">Making a couple of changes</h2>
+
+<p><font>Let's make our first change to the app — we’ll delete the Vue logo. Open the file, and delete the element from the template section:</font><code>App.vue</code><code><a href="/en-US/docs/Web/HTML/Element/img">&lt;img&gt;</a></code></p>
+
+<pre class="brush: html notranslate"><span class="author-d-iz88z86z86za0dz67zz78zz78zz74zz68zjz80zz71z9iz90z8h7gz67ziz76zcz77zz80zz71zncfz69zz69ziaz82zz71zz72zhz77zz122zz90z14mcyd">&lt;img alt="Vue logo" src="./assets/logo.png"&gt;</span></pre>
+
+<p><font>If your server is still running, you should see the logo removed from the rendered site almost instantly. Let’s also remove the component from our template.</font><code>HelloWorld</code></p>
+
+<p>First of all delete this line:</p>
+
+<pre class="brush: html notranslate">&lt;HelloWorld msg="Welcome to Your Vue.js App"/&gt;</pre>
+
+<p><font>If you save your file now, the rendered app will throw an error because we’ve registered the component but are not using it. We also need to remove the lines from inside the element that import and register the component:</font><code>App.vue</code><code>&lt;script&gt;</code></p>
+
+<p>Delete these lines now:</p>
+
+<pre class="brush: js notranslate">import HelloWorld from './components/HelloWorld.vue'</pre>
+
+<pre class="brush: js notranslate">components: {
+ HelloWorld
+}</pre>
+
+<p><font>Your rendered app should no longer show an error, just a blank page, as we currently have no visible content inside .</font><code>&lt;template&gt;</code></p>
+
+<p><font>Let’s add a new inside . Since we’re going to be creating a todo list app below, let's set our header text to "To-Do List". Add it like so:</font><code>&lt;h1&gt;</code><code>&lt;div id="app"&gt;</code></p>
+
+<pre class="brush: html notranslate">&lt;template&gt;
+ &lt;div id="app"&gt;
+ &lt;h1&gt;To-Do List&lt;/h1&gt;
+ &lt;/div&gt;
+&lt;/template&gt;</pre>
+
+<p><code>App.vue</code><font> will now show our heading, as you'd expect.</font></p>
+
+<h2 id="Summary">Summary</h2>
+
+<p>Let's leave this here for now. We've learnt about some of the ideas behind Vue, created some scaffolding for our example app to live inside, inspected it, and made a few preliminary changes.</p>
+
+<p>With a basic introduction out of the way, we'll now go further and build up our sample app, a basic Todo list application that allows us to store a list of items, check them off when done, and filter the list by all, complete, and incomplete todos.</p>
+
+<p>In the next article we'll build our first custom component, and look at some important concepts such as passing props into it and saving its data state.</p>
+
+<p>{{PreviousMenuNext("Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_resources","Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_first_component", "Learn/Tools_and_testing/Client-side_JavaScript_frameworks")}}</p>
+
+<h2 id="In_this_module">In this module</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Introduction">Introduction to client-side frameworks</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Main_features">Framework main features</a></li>
+ <li><font>React</font>
+ <ul>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_getting_started">Getting started with React</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_todo_list_beginning">Beginning our React todo list</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_components">Componentizing our React app</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_interactivity_events_state">React interactivity: Events and state</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_interactivity_filtering_conditional_rendering">React interactivity: Editing, filtering, conditional rendering</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_accessibility">Accessibility in React</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_resources">React resources</a></li>
+ </ul>
+ </li>
+ <li><font>Ember</font>
+ <ul>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_getting_started">Getting started with Ember</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_structure_componentization">Ember app structure and componentization</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_interactivity_events_state">Ember interactivity: Events, classes and state</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_conditional_footer">Ember Interactivity: Footer functionality, conditional rendering</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_routing">Routing in Ember</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Ember_resources">Ember resources and troubleshooting</a></li>
+ </ul>
+ </li>
+ <li><font>Vue</font>
+ <ul>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_getting_started">Getting started with Vue</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_first_component">Creating our first Vue component</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_rendering_lists">Rendering a list of Vue components</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_methods_events_models">Adding a new todo form: Vue events, methods, and models</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_styling">Styling Vue components with CSS</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_computed_properties">Using Vue computed properties</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_conditional_rendering">Vue conditional rendering: editing existing todos</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_refs_focus_management">Focus management with Vue refs</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Vue_resources">Vue resources</a></li>
+ </ul>
+ </li>
+ <li><font>Svelte</font>
+ <ul>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_getting_started">Getting started with Svelte</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_Todo_list_beginning">Starting our Svelte Todo list app</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_variables_props">Dynamic behavior in Svelte: working with variables and props</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_components">Componentizing our Svelte app</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_reactivity_lifecycle_accessibility">Advanced Svelte: Reactivity, lifecycle, accessibility</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_stores">Working with Svelte stores</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_TypeScript">TypeScript support in Svelte</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Svelte_deployment_next">Deployment and next steps</a></li>
+ </ul>
+ </li>
+</ul>
diff --git a/files/fr/learn/tools_and_testing/cross_browser_testing/accessibilité/index.html b/files/fr/learn/tools_and_testing/cross_browser_testing/accessibilité/index.html
new file mode 100644
index 0000000000..0af81a09b0
--- /dev/null
+++ b/files/fr/learn/tools_and_testing/cross_browser_testing/accessibilité/index.html
@@ -0,0 +1,684 @@
+---
+title: Gérer les problèmes courants d'accessibilité
+slug: Learn/Tools_and_testing/Cross_browser_testing/Accessibilité
+tags:
+ - Accessibilité
+ - Apprentissage
+ - Article
+ - CSS
+ - Clavier
+ - Débutant
+ - HTML
+ - JavaScript
+ - Outils
+ - navigateur croisé
+ - test
+translation_of: Learn/Tools_and_testing/Cross_browser_testing/Accessibility
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/Tools_and_testing/Cross_browser_testing/JavaScript","Learn/Tools_and_testing/Cross_browser_testing/Feature_detection", "Learn/Tools_and_testing/Cross_browser_testing")}}</div>
+
+<p class="summary">Tournons maintenant notre attention vers l'accessibilité, les informations sur les problèmes communs, comment faire des tests simples, et comment faire pour utiliser les outils d'audit/automatisation pour trouver les problèmes d'accessibilités.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Prérequis :</th>
+ <td>
+ <p>Connaissances avec le noyau des langages <a href="https://developer.mozilla.org/fr/Apprendre/HTML">HTML</a>, <a href="https://developer.mozilla.org/fr/Apprendre/CSS">CSS</a> et <a href="https://developer.mozilla.org/fr/Apprendre/JavaScript">JavaScript</a> ; une idée du haut niveau des principes du <a href="https://developer.mozilla.org/fr/docs/Learn/Tools_and_testing/Cross_browser_testing/Introduction">test en navigateur croisé</a>.</p>
+ </td>
+ </tr>
+ <tr>
+ <th scope="row">Objectif :</th>
+ <td>
+ <p>Être capable de diagnostiquer les problèmes courants d'Accessibilité, et utiliser les outils et techniques appropriés pour les résoudre.</p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Qu'est-ce_que_l'accessibilité">Qu'est-ce que l'accessibilité ?</h2>
+
+<p>Quand on parle d'accessibilité dans le contexte de la technologie web, la plupart des gens pense directement au fait de s'assurer que les sites web/apps sont utilisables par les personnes avec des handicap, par exemple :</p>
+
+<ul>
+ <li>Les personnes malvoyantes utilisant des lecteurs d'écran ou l'élargissement/zoom pour accéder au texte.</li>
+ <li>Les personnes avec des troubles fonctionnels moteurs utilisant le clavier (ou d'autres fonctions sans souris) pour activer des fonctionnalités de site web.</li>
+ <li>Les personnes avec des troubles auditifs dépendant des légendes/sous-titres ou d'autres textes alternatifs pour du contenu audio/vidéo.</li>
+</ul>
+
+<p>Toutefois, ce serait faux de réduire l'accessibilité uniquement aux handicaps. Le vrai but de l'accessibilité est de faire en sorte que vos sites web/applis soient utilisables par le plus grand nombre de personnes dans le plus grand nombre de contextes possibles, pas uniquement ces utilisateurs qui utilisant des ordinateurs de bureau puissants. Les exemples extrêmes pourraient inclure :</p>
+
+<ul>
+ <li>Les utilisateurs sur des appareils mobiles.</li>
+ <li>Les utilisateurs sur des appareils de navigation alternatifs comme les TVs, les montres, etc.</li>
+ <li>Les utilisateurs de vieux appareils qui n'ont pas les derniers navigateurs.</li>
+ <li>Les utilisateurs avec des appareils aux caractéristiques basses qui peuvent avoir des processeurs lents.</li>
+</ul>
+
+<p>D'une certaine manière, la totalité de ce module concerne l'accessibilité — le test en navigateur croisé assure que vos sites peuvent être utilisé par le plus de personne possible. <a href="https://developer.mozilla.org/fr/Apprendre/a11y/What_is_accessibility">Qu'est-ce que l'accessibilité ?</a> décrit plus largement et précisément l'accessibilité que cet article ne le fait.</p>
+
+<p>Cela dit, cet article couvrira les problèmes en navigateur croisé et de test entourant les personnes avec des handicaps, et comment ils utilisent le Web. Nous avons déjà parlé des autres domaines comme le <a href="https://developer.mozilla.org/fr/docs/Learn/Tools_and_testing/Cross_browser_testing/HTML_et_CSS#Les_probl%C3%A8mes_de_responsive_design">responsive design</a> et la <a href="https://developer.mozilla.org/fr/docs/Learn/Tools_and_testing/Cross_browser_testing/JavaScript#Les_probl%C3%A8mes_de_performance">performance</a> à d'autres endroits dans ce module.</p>
+
+<div class="note">
+<p><strong>Note </strong>: Comme beaucoup de choses dans le développement web, l'accessibilité ne concerne pas la totale réussite ou échec ; l'accessibilité à 100% est quasiment impossible à atteindre pour tous les contenus, spécialement quand les sites deviennent plus complexes. Il s'agit plutôt de faire un effort pour rendre votre contenu accessible au plus grand nombre de personnes possible, avec du code de prévention, et se tenir aux meilleures pratiques.</p>
+</div>
+
+<h2 id="Problèmes_d'accessibilité_courants">Problèmes d'accessibilité courants</h2>
+
+<p>Dans cette section nous détaillerons certains des problèmes principaux qui se manifestent autour de l'accessibilité, liée à des technologies spécifiques, avec les bonnes pratiques à adopter, et quelques tests rapides que vous pouvez faire pour voir si vos sites vont dans le bon sens.</p>
+
+<div class="note">
+<p><strong>Note </strong>: L'accessibilité est moralement la bonne chose à faire, est bonne pour les affaires (nombre élevé d'utilisateurs handicapés, utilisateurs sur des appareils mobiles, etc. représentent un segment du marché signifiant), mais c'est aussi illégal dans de nombreuses régions de la planète de ne pas rendre les propriétés du web accessibles aux personnes avec des handicaps. Pour plus d'informations, lisez <a href="/en-US/docs/Learn/Accessibility/What_is_accessibility#Accessibility_guidelines_and_the_law">Accessibility guidlines and the law</a>.</p>
+</div>
+
+<h3 id="HTML">HTML</h3>
+
+<p>La sémantique HTML (où les éléments sont utilisés à leur fin prévues) est accessible sans aucune modification — les contenus sont lisibles par les spectateurs voyants (à condition que vous n'ayez rien fait d'absurde comme rendre le texte bien trop petit ou ne l'ayez caché en utilisant du CSS), mais il sera aussi utilisable par des technologies d'assistance comme les lecteurs d'écran (applis qui lisent littéralement une page à leurs utilisateurs), et apporte également d'autres avantages.</p>
+
+<h4 id="La_structure_sémantique">La structure sémantique</h4>
+
+<p>Le quick win le plus important en sémantique HTML et d'utiliser une structure de rubriques et de paragraphes pour votre contenu ; parce que les utilisateurs de lecteurs d'écran ont tendance à utiliser les rubriques d'un document comme indications pour trouver le contenu qu'il recherche plus rapidement. Si votre contenu n'a pas de rubriques, tout ce qu'ils auraient c'est un énorme mur de texte sans aucune indication pour trouver quelque chose. Exemples de bon et de mauvais HTML :</p>
+
+<pre class="brush: html example-bad">&lt;font size="7"&gt;My heading&lt;/font&gt;
+&lt;br&gt;&lt;br&gt;
+This is the first section of my document.
+&lt;br&gt;&lt;br&gt;
+I'll add another paragraph here too.
+&lt;br&gt;&lt;br&gt;
+&lt;font size="5"&gt;My subheading&lt;/font&gt;
+&lt;br&gt;&lt;br&gt;
+This is the first subsection of my document. I'd love people to be able to find this content!
+&lt;br&gt;&lt;br&gt;
+&lt;font size="5"&gt;My 2nd subheading&lt;/font&gt;
+&lt;br&gt;&lt;br&gt;
+This is the second subsection of my content. I think is more interesting than the last one.</pre>
+
+<pre class="brush: html example-good">&lt;h1&gt;My heading&lt;/h1&gt;
+
+&lt;p&gt;This is the first section of my document.&lt;/p&gt;
+
+&lt;p&gt;I'll add another paragraph here too.&lt;/p&gt;
+
+&lt;h2&gt;My subheading&lt;/h2&gt;
+
+&lt;p&gt;This is the first subsection of my document. I'd love people to be able to find this content!&lt;/p&gt;
+
+&lt;h2&gt;My 2nd subheading&lt;/h2&gt;
+
+&lt;p&gt;This is the second subsection of my content. I think is more interesting than the last one.&lt;/p&gt;</pre>
+
+<p>De plus, votre contenu doit avoir un sens logique dans son code source — vous pourrez toujours le placer où vous voulez en utilisant du CSS plus tard, mais vous devez avoir un bon code source avec lequel commencer.</p>
+
+<p>Comme test, vous pouvez désactiver le CSS d'un site et voir à quel point il est compréhensible sans ce dernier. Vous pouvez le faire manuellement juste en retirant le CSS de votre code, mais la façon la plus simple reste d'utiliser les fonctionnalités du navigateur, par exemple :</p>
+
+<ul>
+ <li>Firefox : Sélectionnez <em>Affichage &gt; Style de page &gt; Aucun style</em> depuis le menu principal.</li>
+ <li>Safari : Sélectionnez <em>Développement &gt; Désactiver les styles</em> depuis le menu principale (pour activer le menu <em>Développement</em>, choisissez <em>Safari </em>&gt; <em>Préférences </em>&gt; <em>Avancés </em>&gt; <em>Montrer le menu développement dans la barre de menu</em>).</li>
+ <li>Chrome : Installez l'extension Web Developer Toolbar, puis redémarrer le navigateur. Cliquez sur l'icône engrenage qui apparaîtra, puis sélectionnez <em>CSS</em> &gt; <em>Désactiver tous les styles.</em></li>
+ <li>Edge : Sélectionnez <em>Vue </em>&gt; <em>Style</em> &gt; <em>Aucun style</em> depuis le menu principal.</li>
+</ul>
+
+<h4 id="Utiliser_l'accessibilité_native_du_clavier">Utiliser l'accessibilité native du clavier</h4>
+
+<p>Certaines fonctionnalités HTML peuvent être sélectionnées en utilisant uniquement le clavier — c'est le comportement par défaut, disponible depuis les prémices du web. Les éléments qui ont cette capacité sont les plus communs qui permettent à l'utilisateur d'interagir avec les pages web, à savoir les liens, {{htmlelement("button")}}s, et les éléments des formulaire comme {{htmlelement("input")}}.</p>
+
+<p>Vous pouvez essayer ceci en utilisant notre exemple <a href="http://mdn.github.io/learning-area/tools-testing/cross-browser-testing/accessibility/native-keyboard-accessibility.html">native-keyboard-accessibility.html</a> (voir le <a href="https://github.com/mdn/learning-area/blob/master/tools-testing/cross-browser-testing/accessibility/native-keyboard-accessibility.html">code source</a>) — ouvrez le dans un nouvel onglet, et essayez de presser la touche tab ; après quelques pressions, vous devriez voir la focalisation du tab commencer à se déplacer entre les différents éléments focalisables ; les éléments focalisés ont un style de mise en avant par défaut dans tous les navigateurs (cela diffère peu entre les différents navigateurs) donc vous pouvez dire quel éléments est focalisé.</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/14215/button-focused-unfocused.png" style="border-style: solid; border-width: 1px; display: block; height: 39px; margin: 0px auto; width: 288px;"></p>
+
+<p>Vous pouvez ensuite presser Entrée/Retour pour accéder à un lien focalisé ou presser un bouton (nous avons inclus un peu de JavaScript pour que les boutons renvoies un message d'alerte), ou commencer à taper pour entrer du texte dans un des input texte (d'autres éléments de formulaire ont différents contrôles, par exemple l'élément {{htmlelement("select")}} peut avoir ses options affichées et navigable en utilisant les touches haut et bas).</p>
+
+<p>Notez que différents navigateurs peuvent avoir différentes options de contrôle par clavier disponibles. La plupart des navigateurs modernes respectent le modèle de tab écrit plus haut (vous pouvez aussi faire une Shift + Tab pour reculer entre les éléments focalisables), mais certains navigateurs ont leurs propres particularités :</p>
+
+<ul>
+ <li>Firefox pour Max ne tabule pas par défaut. Pour l'activer, vous devez aller dans <em>Préférences</em> &gt; <em>Avancées</em> &gt; <em>Général</em>, puis décochez "Toujours utiliser les curseurs pour naviguer dans une page". Ensuite, vous devez ouvrir les Préférences Système de votre Mac, puis sélectionnez le boutons radio <em>Tous les contrôles</em>.</li>
+ <li>Safari ne vous permet pas de naviguer avec tab par défaut ; pour l'activer, vous devez ouvrir les <em>Préférences</em> de Safari, allez dans Avancées, et cochez la case à cocher <em>Presser tab pour mettre en avant chaque item sur une page web</em>.</li>
+</ul>
+
+<div class="warning">
+<p><strong>Important </strong>: Vous devez jouer ce genre de test sur toutes les pages que vous écrivez — assurez-vous que la fonctionnalité peut être accessible par le clavier.</p>
+</div>
+
+<p>Cet exemple souligne l'importance de l'utilisation de la sémantique correcte d'élément pour le travail correct. C'est possible de styler <em>n'importe quel</em> élément pour qu'il ressemble à un lien ou un bouton avec le CSS, et de le faire se comporter comme un lien ou un bouton avec JavaScript, mais ils ne seront toujours pas des liens ou des boutons, et vous perdrez beaucoup de l'accessibilité que ces éléments vous fournissent pour rien. Donc ne le faîte pas si vous pouvez l'éviter.</p>
+
+<p>Un autre conseil — comme vu dans notre exemple, vous pouvez contrôler comment vos éléments focalisables paraissent quand ils sont focalisés, en utilisant la pseudo-class <a href="https://developer.mozilla.org/fr/docs/Web/CSS/:focus">:focus</a>. C'est une bonne idée de doubler les styles focus et hover, comme ça vos utilisateurs auront un indice visuel qu'un contrôle fera quelque chose lorsqu'il sera activé, qu'ils utilisent la souris ou le clavier :</p>
+
+<pre class="brush: css">a:hover, input:hover, button:hover, select:hover,
+a:focus, input:focus, button:focus, select:focus {
+ font-weight: bold;
+}</pre>
+
+<div class="note">
+<p><strong>Note </strong>: Si vous décidez de retirer le style focus par défaut en utilisant du CSS, assurez-vous de le remplacer par autre chose qui s'accorde au mieux avec votre design — c'est un outil d'accessibilité de grande valeur, qui ne doit pas être supprimé.</p>
+</div>
+
+<h4 id="Intégrer_l'accessibilité_clavier">Intégrer l'accessibilité clavier</h4>
+
+<p>Parfois ça n'est pas possible d'éviter la perte de l'accessibilité clavier. Vous pouvez avoir hérité d'un site où la sémantique n'est pas parfaite (peut-être que vous vous êtes retrouvé avec un CMS horrible qui génère des boutons créés avec des <code>&lt;div&gt;</code>s), ou que vous utilisez un contrôle complexe qui n'a pas d'accessibilité clavier intégré, comme l'élément {{htmlelement("video")}} (étonnamment, Opera est le seul navigateur qui vous permet de tabuler dans l'élément <code>&lt;video&gt;</code> avec les contrôles par défaut du navigateur). Vous avez quelques options ici :</p>
+
+<ol>
+ <li>Créer des contrôles personnalisés en utilisant les éléments <code>&lt;button&gt;</code> (sur lequel nous pouvons tabuler par défaut !) et JavaScript pour les relier à leur fonction. Pour des bons exemples voir <a href="/en-US/docs/Web/Apps/Fundamentals/Audio_and_video_delivery/cross_browser_video_player">Creating a cross-browser video player</a>.</li>
+ <li>Créer des raccourcis clavier en utilisant JavaScript, les fonctions sont activés quand vous appuyez sur une certaine touche du clavier. Voir <a href="/en-US/docs/Games/Techniques/Control_mechanisms/Desktop_with_mouse_and_keyboard">Desktop mouse and keyboard controls</a> pour des exemples en rapport avec le jeu qui peuvent être adaptés à d'autres fins.</li>
+ <li>Utilisez des approches intéressantes pour simuler le comportement d'un bouton. Prenez par exemple notre exemple <a href="http://mdn.github.io/learning-area/tools-testing/cross-browser-testing/accessibility/fake-div-buttons.html">fake-div-buttons.html</a> (voir le <a href="https://github.com/mdn/learning-area/blob/master/tools-testing/cross-browser-testing/accessibility/fake-div-buttons.html">code source</a>). Nous donnons à nos faux boutons <code>&lt;div&gt;</code> la capacité d'être focalisé (y compris avec la tabulation) en donnant à chacun d'entre eux l'attribut <code>tabindex="0"</code> (voir l'<a href="https://webaim.org/techniques/keyboard/tabindex">article tabindex</a> de WebAIM pour plus de détails utiles). Cela nous permet de tabuler sur les boutons, mais pas de les activer avec la toucher Entrée/Retour. Pour faire cela, nous devons ajouter ce petit bout de tromperie en JavaScript :</li>
+ <li>
+ <pre class="brush: js">document.onkeydown = function(e) {
+ if(e.keyCode === 13) { // The Enter/Return key
+ document.activeElement.onclick(e);
+ }
+};</pre>
+ Ici nous ajoutons un listener à l'objet <code>document</code> pour détecter quand une touche a été appuyée sur le clavier. Nous vérifions quelle touche a été pressée avec la propriété d'évènement d'objet <a href="/en-US/docs/Web/API/KeyboardEvent/keyCode">keyCode</a> ; si c'est le code de la touche qui retourne Entrée/Retour, on exécute la fonction stockée dans le <code>onclick</code> du bouton en utilisant <code>document.activeElement.onclick()</code>. <code><a href="/en-US/docs/Web/API/Document/activeElement">activeElement</a></code> nous donne l'élément courant qui est focalisé sur la page.</li>
+</ol>
+
+<div class="note">
+<p><strong>Note </strong>: Cette technique ne fonctionnera que si vous configurer vos propres gestionnaires d'évènement avec les propriétés de gestion d'évènement (par ex. <code>onclick</code>). <code>addEventListener</code> ne fonctionnera pas. C'est beaucoup de prises de tête pour construire la fonctionnalité de retour. Et il y a d'autres problèmes rattachés avec. Vaut mieux commencer par utiliser les bons éléments pour leurs buts initiaux.</p>
+</div>
+
+<h4 id="Les_textes_alternatifs">Les textes alternatifs</h4>
+
+<p>Les textes alternatifs sont très importants pour l'accessibilité — si une personne a un trouble visuel ou auditif qui l'empêche de voir ou d'entendre un contenu, alors c'est un problème. Le texte alternatif le plus simple disponible est le modeste attribut <code>alt</code>, que nous devrions inclure dans toutes les images qui contiennent un contenu pertinent. Il peut contenir une description de l'image qui transmet clairement son sens et son contenu sur la page, pour être récupéré par un lecteur d'écran et lu à l'utilisateur.</p>
+
+<div class="note">
+<p><strong>Note </strong>: Pour plus d'informations, lisez <a href="/en-US/docs/Learn/Accessibility/HTML#Text_alternatives">Text alternatives</a>.</p>
+</div>
+
+<p>L'oubli de texte alt peut être testé de bien des façons, par exemple en utilisant le {{anch("Auditing tools")}} d'accessibilité.</p>
+
+<p>Le texte alt est légèrement plus complexe pour du contenu vidéo ou audio. Il y a une manière de gérer l'affichage du texte (par ex. les sous-titres) et de les afficher quand la vidéo est jouée, sous le forme de l'élément {{htmlelement("track")}}, et du format <a href="/en-US/docs/Web/API/Web_Video_Text_Tracks_Format">WebVTT</a> (voir <a href="https://developer.mozilla.org/fr/Apps/Build/Audio_and_video_delivery/Adding_captions_and_subtitles_to_HTML5_video">Ajouter des légendes et des sous-titres à des vidéos HTML5</a> pour un tutoriel détaillé). <a href="https://developer.mozilla.org/fr/Apps/Build/Audio_and_video_delivery/Adding_captions_and_subtitles_to_HTML5_video#Compatibilit%C3%A9_entre_navigateurs">La compatibilité entre navigateur</a> pour cette fonction est assez bonne, mais si vous voulez fournir des textes alternatifs pour de l'audio ou supporter les vieux navigateurs, une simple transcription du texte présenté quelque part sur la page ou sur une page séparée peut être une bonne idée.</p>
+
+<h4 id="Relations_et_contexte_entre_élément">Relations et contexte entre élément</h4>
+
+<p>Il y a certaines caractéristiques et pratiques optimales en HTML conçues pour apporter du contexte et des relations entre des éléments lorsqu'aucune n'aurait autrement existé. Les trois exemples les plus courants sont les liens, les libellés de formulaire et les tableau de données.</p>
+
+<p>La solution pour les textes de type lien c'est que les personnes utilisant des lecteurs d'écran vont souvent utiliser une fonctionnalité commune avec laquelle ils vont récupérer une liste de tous les liens sur la page. Par exemple, une liste de lien libellés "cliquez ici", "cliquez ici", etc. est vraiment mauvaise pour l'accessibilité. Il est préférable pour les textes de type lien d'avoir du sens en contexte et hors contexte.</p>
+
+<p>Le suivant sur notre liste, l'élément de formulaire {{htmlelement("label")}} est une des fonctionnalités centrales qui nous permet de rendre les formulaires accessibles. Le problème avec les formulaires c'est que vous avez besoin de libellés pour dire quelle donnée doit être entrée dans chaque champs du formulaire. Chaque libellé doit être inclus dans un {{htmlelement("label")}} pour le relier clairement à son champs partenaire (chaque valeur de l'attribut <code>for</code> de <code>&lt;label&gt;</code> doit aller avec la valeur de l'<code>id</code> de l'élément du formulaire), et cela aura du sens même si le code source n'est pas totalement logique (ce qui pour être tout à fait juste devrait être fait).</p>
+
+<div class="note">
+<p><strong>Note </strong>: Lisez <a href="/en-US/docs/Learn/Accessibility/HTML#Meaningful_text_labels">Meaningful text labels</a>, pour plus d'information à propos des textes de type lien et les libellés des formulaires.</p>
+</div>
+
+<p>Pour terminer, un mot rapide sur les tableaux de données. Un tableau de données basique peut être écrit avec des indications très simples (voir <code>bad-table.html</code> <a href="http://mdn.github.io/learning-area/accessibility/html/bad-table.html">en direct</a>, et <a href="https://github.com/mdn/learning-area/blob/master/accessibility/html/bad-table.html">la source</a>), mais il y a des problèmes — il n'y a aucun moyen pour un utilisateur de lecteur d'écran d'associer des lignes ou des colonnes ensembles comme un groupe de données — pour faire cela vous devez connaître les lignes d'en-têtes, et si elles se dirigent en lignes, colonnes, etc. Cela ne peut être fait qu'en visuel pour un tel tableau.</p>
+
+<p>Si vous regardez plutôt notre exemple <code>punk-band-complete.html</code> (<a href="https://mdn.github.io/learning-area/css/styling-boxes/styling-tables/punk-bands-complete.html">direct</a>, <a href="https://github.com/mdn/learning-area/blob/master/css/styling-boxes/styling-tables/punk-bands-complete.html">source</a>), vous pouvez voir plusieurs aides à l'accessibilité en place, comme les entêtes de tableau ({{htmlelement("th")}} et les attributs <code>scope</code>), l'élément {{htmlelement("caption")}}, etc.</p>
+
+<div class="note">
+<p><strong>Note </strong>: Lisez <a href="/en-US/docs/Learn/Accessibility/HTML#Accessible_data_tables">Accessible data tables</a>, pour plus d'information à propos des tableaux accessibles.</p>
+</div>
+
+<h3 id="CSS">CSS</h3>
+
+<p>Le CSS tend à fournir beaucoup moins de caractéristiques fondamentales d'accessibilité que le HTML, mais il peut aussi faire beaucoup de dommage à l'accessibilité s'il est mal utilisé. Nous avons déjà mentionné quelques conseils sur l'accessibilité incluant le CSS :</p>
+
+<ul>
+ <li>Utilisez les éléments sémantiques correctes pour définir différent contenu en HTML ; si vous voulez créer un effet visuel différent, utilisez le CSS — n'abusez pas d'un élément HTML pour obtenir l'aspect que vous désirez. Par exemple si vous voulez un texte plus gros, utilisez {{cssxref("font-size")}}, par un élément {{htmlelement("h1")}}.</li>
+ <li>Assurez-vous que votre code source a du sens sans le CSS ; vous pouvez toujours utilisez le CSS pour styler autant que vous voudrez après.</li>
+ <li>Vous devez vous assurez que les éléments interactifs comme les boutons et les liens ont des états focus/hover/active appropriés configuré, pour donner à l'utilisateur un indice visuel de leur fonction. Si vous supprimez les styles par défaut pour des raisons stylistiques, assurez-vous de mettre en place des styles de remplacement.</li>
+</ul>
+
+<p>Il y a quelques autres considérations que vous devriez prendre en compte.</p>
+
+<h4 id="Couleur_et_contraste">Couleur et contraste</h4>
+
+<p>Lorsque vous choisissez une palette de couleurs pour votre site web, vous devez vous assurer que la couleur du texte (au premier plan) contraste bien avec la couleur d'arrière-plan. Votre design peut avoir l'air cool, mais ce n'est pas bon si les personnes avec un handicap visuel comme le daltonisme ne peuvent pas lire votre contenu. Utilisez un outil comme le <a href="http://webaim.org/resources/contrastchecker/">Color Contrast Checker</a> de WebAIM si votre palette contraste suffisamment.</p>
+
+<p>Une autre astuce est de ne pas compter sur une couleur seule pour les indications/informations, comme ça ne sera pas bon pour ceux qui ne peuvent pas voir la couleur. Plutôt que de marquer en rouge les champs requis d'un formulaire, par exemple, marquez-les avec un astérisque et en rouge.</p>
+
+<div class="note">
+<p><strong>Note </strong>: un contraste élevé permettra également à toute personnes utilisant un smartphone ou une tablette avec un écran brillant de mieux lire les pages dans un environnement lumineux, comme avec la lumière du soleil.</p>
+</div>
+
+<h4 id="Cacher_du_contenu">Cacher du contenu</h4>
+
+<p>Il y a plusieurs cas où un design visuel requerra que tout le contenu ne soit pas montré d'un seul coup. Par exemple, dans notre <a href="http://mdn.github.io/learning-area/css/css-layout/practical-positioning-examples/info-box.html">Exemple de boîte d'info avec onglets</a> (voir le <a href="https://github.com/mdn/learning-area/blob/master/css/css-layout/practical-positioning-examples/info-box.html">code source</a>) nous avons trois panneau d'information, mais nous les <a href="https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Positioning">positionnons</a> les uns sur les autres et fournissons des onglets qui peuvent être cliqués pour montrer chacun d'entre eux (c'est aussi accessible au clavier — vous pouvez utiliser alternativement Tab et Entrée/Retour pour les sélectionner).</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/13368/tabbed-info-box.png" style="display: block; height: 400px; margin: 0px auto; width: 450px;"></p>
+
+<p>Les utilisateurs de lecteur d'écran ne se soucient pas vraiment de cela — ils sont satisfaits tant que le contenu a du sens dans le code source, et qu'ils peuvent entièrement y accéder. Le positionnement absolute (comme utilisé dans cet exemple) est souvent vu comme l'un des meilleur mécanismes pour cacher du contenu pour des effets visuels, parce que ça n'empêche pas les lecteur d'écran d'y accéder.</p>
+
+<p>D'un autre côté, vous ne devriez pas utiliser {{cssxref("visibility")}}<code>:hidden</code> ou {{cssxref("display")}}<code>:none</code>, parce qu'il cache le contenu aux lecteurs d'écran. A moins que, bien entendu, il y est une bonne raison qui justifie que ce contenu soit caché aux lecteurs d'écran.</p>
+
+<div class="note">
+<p><strong>Note </strong>: <span class="subtitle"><a href="http://webaim.org/techniques/css/invisiblecontent/">Invisible Content Just for Screen Reader Users</a> vous décrira beaucoup de détails utilesà propos de ce sujet. </span></p>
+</div>
+
+<h3 id="JavaScript">JavaScript</h3>
+
+<p>Le JavaScript a le même type de problèmes que le CSS concernant l'accessibilité — cela peut être désastreux pour l'accessibilité si mal utilisé, ou trop utilisé. Nous avions déjà abordé quelques problèmes d'accessibilité en rapport avec le JavaScript, principalement dans le champ de la sémantique HTML — vous devez toujours utiliser une sémantique HTML appropriée pour implémenter une fonctionnalité qu'importe où elle est disponible, par exemple utiliser des liens et des boutons de façon appropriée. N'utilisez pas les éléments <code>&lt;div&gt;</code> avec du code JavaScript pour simuler une fonctionnalité si c'est possible — c'est une source d'erreur, et ça fonctionne mieux d'utiliser les fonctionnalités disponibles qu'HTML vous fournit.</p>
+
+<h4 id="Fonctionnalité_simple">Fonctionnalité simple</h4>
+
+<p>Normalement, une fonctionnalité simple doit marcher uniquement avec le HTML en place — le JavaScript ne doit pas être utilisé que pour améliorer la fonctionnalité, par pour la construire en entier. Les bons usages de JavaScript incluent :</p>
+
+<ul>
+ <li>Fournir une validation de formulaire côté client, qui informe rapidement les utilisateurs des problèmes avec leurs entrées dans le formulaire, sans qu'ils aient à attendre que le serveur vérifie les données. Si ça n'est pas disponible, le formulaire marchera toujours, mais la validation sera peut-être plus lente.</li>
+ <li>Fournir des contrôles personnalisés pour les <code>&lt;video&gt;</code>s HTML5 qui sont accessibles pour les utilisateurs uniquement au clavier (comme nous l'avons dit auparavant, les contrôles par défaut de navigateur ne sont pas accessibles au clavier dans la plupart des navigateurs).</li>
+</ul>
+
+<div class="note">
+<p><strong>Note </strong>: <a href="http://webaim.org/techniques/javascript/">Accessible JavaScript</a> de WebAIM fourni des renseignements approfondis à propos des considérations pour du JavaScript accessible.</p>
+</div>
+
+<p>Les implémentations JavaScript plus complexes peuvent mener à des problèmes avec l'accessibilité — vous devez faire ce que vous pouvez. par exemple, cela ne serait pas raisonnable d'attendre de vous que vous fassiez un jeu complexe 3D écrit avec <a href="https://developer.mozilla.org/fr/Apprendre/WebGL">WebGL</a> accessible à 100% pour une personne aveugle, mais vous pouvez implémenter des <a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/Control_mechanisms/Desktop_with_mouse_and_keyboard">contrôles clavier</a> pour qu'il soit utilisable pour un utilisateur sans souris, et réaliser une palette de couleurs suffisamment contrastée pour être utilisable par les personnes avec des lacunes pour percevoir les couleurs.</p>
+
+<h4 id="Fonctionnalité_complexe">Fonctionnalité complexe</h4>
+
+<p>L'un des domaines de problématique principal pour l'accessibilité c'est les applis complexes qui nécessitent des contrôles de formulaires compliqués (comme les sélecteurs de date) et le contenu dynamique qui se met souvent à jour et de façon incrémentale.</p>
+
+<p>Les contrôles de formulaire compliqués non natifs sont problématiques parce qu'ils ont tendance à nécessiter beaucoup de <code>&lt;div&gt;</code>s imbriquées, et le navigateur ne sait pas quoi faire par défaut avec elles. Si vous les inventer vous-même, vous devez vous assurer qu'ils sont accessibles par le clavier ; si vous utilisez des structures externes, revoyez en profondeur les options disponibles pour voir à quel point elles sont accessibles avant de vous plonger dedans. <a href="http://getbootstrap.com/">Bootstrap</a> à l'air d'être assez bon pour l'accessibilité, par exemple, bien que <span class="l-d-i l-pa2 t-bg-white"><a href="https://www.sitepoint.com/making-bootstrap-accessible/">Making Bootstrap a Little More Accessible</a> de Rhiana Heath aborde certain de ses problèmes (principalement en rapport avec le contraste des couleurs), et examine certaines solutions.</span></p>
+
+<p>Le contenu dynamique régulièrement mis à jour peut-être un problème parce que les utilisateurs de lecteur d'écran peuvent le manquer, spécialement si les mises à jour sont inattendues. Si vous avez une appli en single-page avec un contenu principal dans un panneau qui est régulièrement mis à jour en utilisant <a href="https://developer.mozilla.org/fr/docs/Web/API/XMLHttpRequest">XMLHttpRequest</a> ou <a href="https://developer.mozilla.org/fr/docs/Web/API/Fetch_API">Fetch</a>, un utilisateur utilisant un lecteur d'écran peut rater ces mises à jour.</p>
+
+<h4 id="WAI-ARIA">WAI-ARIA</h4>
+
+<p>Avez-vous besoin d'utiliser une fonctionnalité complexe, ou à la place vous le faîte avec une bonne vieille sémantique HTML ? Si vous avez besoin de complexité, vous devriez songer à utiliser <a href="https://www.w3.org/TR/wai-aria-1.1/">WAI-ARIA</a> (Accessible Rich Internet Applications), une spécification qui fournit une sémantique (sous la forme des nouveaux attributs HTML) pour les objets comme les contrôles complexes de formulaire et les panneaux mis à jour qui peuvent être compris par la plupart des navigateurs et les lecteurs d'écran.</p>
+
+<p>Pour traiter avec les widgets complexes de formulaire, vous devez utiliser les attributs ARIA comme <code>roles</code> pour déclarer quel rôle les différents éléments on dans un widget (par exemple, est-ce qu'ils sont un onglet, ou un panneau ?), <code>aria-disabled</code> pour dire si un contrôle est désactivé ou pas, etc.</p>
+
+<p>Pour traiter avec les zones de contenu qui sont régulièrement mises à jour, vous pouvez utiliser l'attribut <code>aria-live</code>, qui identifie une zone mise à jour. Sa valeur indique avec quelle urgence le lecteur d'écran doit faire la lecture :</p>
+
+<ul>
+ <li><code>off</code> : Par défaut. Les mises à jour ne seront pas annoncées.</li>
+ <li><code>polite</code> : Les mises à jour sont annoncées seulement si l'utilisateur est inactif.</li>
+ <li><code>assertive</code> : Les mises à jour sont annoncées à l'utilisateur aussi tôt que possible.</li>
+ <li><code>rude</code> : Les mises à jour sont annoncées immédiatement, même si cela interrompt l'utilisateur.</li>
+</ul>
+
+<p>Voici un exemple :</p>
+
+<pre class="brush: html">&lt;p&gt;&lt;span id="LiveRegion1" aria-live="polite" aria-atomic="false"&gt;&lt;/span&gt;&lt;/p&gt;</pre>
+
+<p>Vous pouvez voir un exemple en action sur l'exemple <a href="http://www.freedomscientific.com/Training/Surfs-up/AriaLiveRegions.htm">ARIA (Accessible Rich Internet Applications) Live Regions</a> de Freedom Scientific — le paragraphe surligné doit mettre à jour son contenu toutes les 10 secondes, et un lecteur d'écran doit le lire à l'utilisateur. <a href="http://www.freedomscientific.com/Training/Surfs-up/AriaLiveRegionsAtomic.htm">ARIA Live Regions - Atomic</a> apporte un autre exemple utile.</p>
+
+<p>Nous n'avons pas de place pour couvrir WAI-ARIA en détail ici, vous pouvez en apprendre beaucoup plus à ce propos sur <a href="/en-US/docs/Learn/Accessibility/WAI-ARIA_basics">WAI-ARIA basics</a>.</p>
+
+<h2 id="Les_outils_d'accessibilité">Les outils d'accessibilité</h2>
+
+<p>Maintenant que nous avons couvers les considérations de l'accessibilité pour les différentes technologies web, incluant quelques techniques de test (comme la navigation au clavier et le vérificateur de contraste de couleur), tournons-nous maintenant vers d'autres outils que vous pouvez utiliser pour faire des tests d'accessibilité.</p>
+
+<h3 id="Les_outils_d'audit">Les outils d'audit</h3>
+
+<p>Il y a plusieurs outils d'audit disponibles que vous pouvez placer sur vos pages web, lesquels les examinerons et retournerons une liste de problèmes d'accessibilité présents sur la page. A titre d'exemple :</p>
+
+<ul>
+ <li><a href="https://tenon.io">Tenon </a>: une assez bonne appli en ligne qui traverse le code à une URL fournie et qui retourne les résultats sur les erreurs d'acessibilité comprenant les indicateurs, ds erreurs spécifiques accompagnés des critères WCAG qu'elles affectent, et des suggestion de résolutions.</li>
+ <li><a href="http://khan.github.io/tota11y/">tota11y</a> : Un outil d'accessibilité de la Khan Academy qui prend la forme d'une librairie JavaScript que vous attachez à votre page pour apporter plusieurs outils d'accessibilité.</li>
+ <li><a href="http://wave.webaim.org/">Wave</a>: Un autre outil en ligne de test d'accessibilité qui accepte une adresse web et retourne une utile vue annotée de la page avec les problèmes d'accessibilité surlignés.</li>
+</ul>
+
+<p>Observons un exemple, en utilisant Tenon.</p>
+
+<ol>
+ <li>Aller sur la <a href="https://tenon.io">page d'accueil de Tenon</a>.</li>
+ <li>Entrez l'URL de notre exemple de <a href="http://mdn.github.io/learning-area/accessibility/html/bad-semantics.html">bad-semantics.html</a> dans l'entrée texte en haut de la page (ou l'URL d'une autre page que vous aimeriez analyser) et appuyez sur <em>Analyse your Webpage</em>.</li>
+ <li>Défilez vers le bas jusqu'à que vous trouviez la section d'erreur/signalement, comme montré ci-dessous.</li>
+</ol>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/14217/tenon-screenshot.png" style="border-style: solid; border-width: 1px; display: block; height: 593px; margin: 0px auto; width: 870px;"></p>
+
+<p>Il y a également des options que vous pouvez examiner (voir le lien <em>Show Options</em> vers le haut de la page), ainsi qu'une API pour utiliser Tenon comme un programme.</p>
+
+<div class="note">
+<p><strong>Note </strong>: De tels outils ne sont pas suffisant pour résoudre tous vos problèmes d'accessibilité en tant que tel. Vous devrez les combiner, savoir et expérience, test utilisateur, etc. pour vous faire une image exacte.</p>
+</div>
+
+<h3 id="Les_outils_d'automatisation">Les outils d'automatisation</h3>
+
+<p><a href="https://www.deque.com/products/axe/">Deque's aXe tool</a> va un peu plus loin que les outils d'audit que nous avons mentionné plus haut. Comme les autres, il vérifie les pages et retourne des erreurs d'accessibilité. Sa forme immédiate la plus utile est sûrement son extension navigateur :</p>
+
+<ul>
+ <li><a href="http://bitly.com/aXe-Chrome">aXe pour Chrome</a></li>
+ <li><a href="http://bit.ly/aXe-Firefox">aXe pour Firefox</a></li>
+</ul>
+
+<p>Cela ajoute un onglet accessibilité aux outils de développeur du navigateur, nous avons installé la version pour Firefox, puis nous l'avons utilisé pour auditer notre exemple <a href="http://mdn.github.io/learning-area/accessibility/html/bad-table.html">bad-table.html</a>. Nous obtenons les résultats suivants :</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/14213/aXe-screenshot.png" style="display: block; height: 580px; margin: 0px auto; width: 800px;"></p>
+
+<p>aXe est également installable en utilisant <code>npm</code>, et peut-être intégré avec des exécuteurs de tâche comme <a href="http://gruntjs.com/">Grunt</a> et <a href="http://gulpjs.com/">Gulp</a>, des frameworks d'automatisation comme <a href="http://www.seleniumhq.org/">Selenium</a> et <a href="https://cucumber.io/">Cucumber</a>, des framework de test unitaire comme <a href="http://jasmine.github.io/">Jasmin</a>, et d'autres encore (une fois encore, voir la <a href="https://www.deque.com/products/axe/">page principale d'aXe</a> pour plus de détails).</p>
+
+<h3 id="Les_lecteurs_d'écran"><a id="Screenreaders" name="Screenreaders"></a>Les lecteurs d'écran</h3>
+
+<p>Il faut définitivement tester avec un lecteur d'écran pour s'habituer à comment les personnes malvoyantes utilisent le Web. Il y a plusieurs lecteurs d'écran disponible : </p>
+
+<ul>
+ <li>Certain sont des produits commerciaux payants, comme <a href="http://www.freedomscientific.com/Products/Blindness/JAWS">JAWS</a> (Windows) et <a href="http://www.gwmicro.com/window-eyes/">Window Eyes</a> (Windows).</li>
+ <li>Certains sont des produits gratuits, comme <a href="http://www.nvaccess.org/">NVDA</a> (Windows), <a href="http://www.chromevox.com/">ChromeVox</a> (Chrome, Windows, et Mac OS X), et <a href="https://wiki.gnome.org/Projects/Orca">Orca</a> (Linux).</li>
+ <li>Certains sont compris dans le système d'exploitation, comme like <a href="http://www.apple.com/accessibility/osx/voiceover/">VoiceOver</a> (Mac OS X et iOS), <a href="http://www.chromevox.com/">ChromeVox</a> (sur les Chromebooks), et <a href="https://play.google.com/store/apps/details?id=com.google.android.marvin.talkback">TalkBack</a> (Android).</li>
+</ul>
+
+<p>La plupart du temps, les lecteurs d'écran sont des applis séparées, qui s'exécutent sur le système d'exploitation hôte et peuvent lire des pages web, mais aussi du texte dans d'autres appli. Ce n'est pas toujours le cas (ChromeVox est une extension navigateur), mais ça l'est souvent. Les lecteurs d'écran ont tendance à agir de manière légèrement différente et ont des contrôles différents, donc vous devrez consulter la documentation pour le lecteur d'écran que vous avez choisi pour obtenir tous les détails — cela dit, il fonctionne tous à peu près de la même manière.</p>
+
+<p>Commençons à effectuer quelques tests avec deux lecteurs d'écran différents pour vous donner une idée générale de comment ils fonctionnent et de comment tester avec eux.</p>
+
+<div class="note">
+<p><strong>Note </strong>: <a href="http://webaim.org/techniques/screenreader/">Designing for Screen Reader Compatibility</a> de WebAIM fournit des informations utiles à propos de l'utilisation des lecteurs d'écran et qu'est-ce qui est le plus efficace pour les lecteurs d'écran. Aller également voir <a href="http://webaim.org/projects/screenreadersurvey6/#used">Screen Reader User Survey #6 Results</a> pour des statistiques intéressantes concernant l'utilisation de lecteur d'écran.</p>
+</div>
+
+<h4 id="VoiceOver">VoiceOver</h4>
+
+<p>VoiceOver (VO) est gratuit avec votre Mac/iPhone/iPad, donc c'est utile pour tester sur votre ordinateur/mobile si vous utilisez des produits Apple. Nous le testerons sur Mac OS X sur un MacBook Pro.</p>
+
+<p>Pour le démarrer, pressez Cmd + Fn + F5. Si vous n'avez jamais utilisé VO auparavant, vous obtiendrez un écran de bienvenue où vous pouvez choisir de démarrer VO ou de ne pas le démarrer, et vous parcourrez un tutoriel utile pour apprendre à comment l'utiliser. Pour l'arrêter, pressez Cmd + Fn + F5 à nouveau.</p>
+
+<div class="note">
+<p><strong>Note </strong>: Vous devriez parcourir le tutoriel au moins une fois — il est vraiment très utile pour en apprendre à propos de VO.</p>
+</div>
+
+<p>Lorsque VO est démarré, l'affichage ressemblera à peu près à cela, mais vous verrez une boîte noire en bas à gauche de l'écran qui contient l'information sur quoi est-ce que VO est actuellement sélectionné. La sélection courante sera également mise en avant, avec une bordure noire — cette mise en avant est connue comme le <strong>curseur VO</strong>.</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/14219/voiceover.png" style="border-style: solid; border-width: 1px; display: block; height: 386px; margin: 0px auto; width: 800px;"></p>
+
+<p>Pour utiliser VO, vous aller beaucoup utiliser le "modificateur VO" — c'est une touche ou une combinaison de touches que vous devez presser en plus de l'actuel raccourci VO pour qu'elles fonctionnent. Utiliser un modificateur comme celui-ci est courant avec les lecteurs d'écran, pour leur permettre de garder leur propres commandes en évitant d'entrer en conflit avec d'autres commandes. Dans le cas de VO, le modificateur peut aussi être VerrMaj, ou Ctrl + Option.</p>
+
+<p>VO a beaucoup de commandes clavier, et nous n'allons pas toutes les lister ici. Les principales dont vous aurez besoin pour tester une page web sont dans le tableau suivant. Dans les raccourcis clavier, "VO" veut dire "le modificateur VoiceOver".</p>
+
+<table class="standard-table">
+ <caption>
+ <p>Les raccourcis clavier VoiceOver les plus communs</p>
+ </caption>
+ <thead>
+ <tr>
+ <th scope="col">Raccourci clavier</th>
+ <th scope="col">Description</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>VO + Touches du curseur</td>
+ <td>Déplace le curseur VO vers le haut, la droite, le bas, la gauche.</td>
+ </tr>
+ <tr>
+ <td>VO + Barre espace</td>
+ <td>
+ <p>Sélectionne/active les éléments mis en avant par le curseur VO. Cela inclut les items sélectionnés dans le Rotor (voir plus bas).</p>
+ </td>
+ </tr>
+ <tr>
+ <td>VO + Shift + curseur bas</td>
+ <td>
+ <p>Se déplacer dans un groupe d'éléments (comme un tableau HTML, ou un formulaire, etc.) Une fois dans un groupe vous pouvez vous déplacer et sélectionner les éléments à l'intérieur de ce groupe en utilisant les commandes ci-dessus normalement.</p>
+ </td>
+ </tr>
+ <tr>
+ <td>VO + Shift + curseur haut</td>
+ <td>Sortir d'un groupe.</td>
+ </tr>
+ <tr>
+ <td>VO + C</td>
+ <td>
+ <p>(à l'intérieur d'un tableau) lire l'entête de la colonne courante.</p>
+ </td>
+ </tr>
+ <tr>
+ <td>VO + R</td>
+ <td>(à l'intérieur d'un tableau) lire l'entête de la ligne courante.</td>
+ </tr>
+ <tr>
+ <td>VO + C + C (deux C d'affilé)</td>
+ <td>(à l'intérieur d'un tableau) lire toute la colonne courante, incluant l'entête.</td>
+ </tr>
+ <tr>
+ <td>VO + R + R (deux R d'affilé)</td>
+ <td>
+ <p>(à l'intérieur d'un tableau) lire toute la ligne courante, incluant les entêtes qui correspondent à chacune des cellules.</p>
+ </td>
+ </tr>
+ <tr>
+ <td>VO + curseur gauche, VO + curseur droit</td>
+ <td>(à l'intérieur d'options horizontales, comme un sélecteur de date ou de temps) Se déplacer entre les options</td>
+ </tr>
+ <tr>
+ <td>VO + curseur haut, VO + curseur bas</td>
+ <td>(à l'intérieur d'options horizontales, comme un sélecteur de date ou de temps) Modifier l'option courante.</td>
+ </tr>
+ <tr>
+ <td>VO + U</td>
+ <td>
+ <p>Utiliser le rotor, qui affiche des listes de rubriques, de liens, de contrôles de formulaires, etc. pour une navigation simplifiée.</p>
+ </td>
+ </tr>
+ <tr>
+ <td>VO + curseur gauche, VO + curseur droit</td>
+ <td>
+ <p>(à l'intérieur du Rotor) Se déplacer ente les différentes listes disponibles dans le Rotor.</p>
+ </td>
+ </tr>
+ <tr>
+ <td>VO + curseur haut, VO + curseur bas</td>
+ <td>
+ <p>(à l'intérieur du Rotor) Se déplacer entre les différents éléments dans la liste courante du Rotor.</p>
+ </td>
+ </tr>
+ <tr>
+ <td>Esc</td>
+ <td>(à l'intérieur du Rotor) Sortir du Rotor.</td>
+ </tr>
+ <tr>
+ <td>Ctrl</td>
+ <td>(Lorsque VO parle) Arrêter/Reprendre l'allocution.</td>
+ </tr>
+ <tr>
+ <td>VO + Z</td>
+ <td>Relance la dernière partie de l'allocution.</td>
+ </tr>
+ <tr>
+ <td>VO + D</td>
+ <td>
+ <p>Aller dans le Dock du Mac, pour que vous puissiez sélectionner des applis à exécuter.</p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+<p>Cela peut paraître comme beaucoup de commandes, mais pas tant que ça que vous vous y habituez, et VO vous rappelle régulièrement quels commandes utiliser dans quels cas. Essayer de tester VO maintenant ; vous pouvez dorénavant essayer de tester certains de nos exemples dans la section {{anch("Screenreader testing")}}.</p>
+
+<h4 id="NVDA">NVDA</h4>
+
+<p>NVDA est exclusif à Windows, et vous allez devoir l'installer.</p>
+
+<ol>
+ <li>Téléchargez-le depuis <a href="http://www.nvaccess.org/">nvaccess.org</a>. Vous pouvez choisir si vous voulez faire une donation ou le télécharger gratuitement ; vous devrez également leur donner votre adresse e-mail avant de pouvoir le télécharger.</li>
+ <li>Une fois téléchargé, installez-le — double cliquez sur l'installeur, acceptez la licence et suivez les instructions.</li>
+ <li>Pour lancer NVDA, double cliquez sur fichier/raccourci du programme, ou utilisez le raccourci clavier Ctrl + Alt + N. Vous verrez la boîte de dialogue de bienvenue de NVDA lorsque vous le démarrez. Vous pouvez choisir ici différentes options, puis appuyez sur <em>OK</em> pour continuer.</li>
+</ol>
+
+<p>NVDA sera maintenant actif sur votre ordinateur.</p>
+
+<p>Pour utiliser NVDA, vous aller beaucoup utiliser le "modificateur NVDA" — c'est une touche que vous devez presser en plus de l'actuel raccourci NVDA pour qu'elles fonctionnent. Utiliser un modificateur comme celui-ci est courant avec les lecteurs d'écran, pour leur permettre de garder leurs propres commandes en évitant d'entrer en conflit avec d'autres commandes. Dans le cas de NVDA, le modificateur peut aussi être Insert (par défaut), ou VerrMaj (peut être choisi en cochant la première case à cocher dans la boîte de dialogue de bienvenue avant d'appuyer sur <em>OK</em>).</p>
+
+<div class="note">
+<p><strong>Note </strong>: NVDA est plus subtile que VoiceOver en termes de comment il met en valeur là où il est et qu'est-ce qu'il fait. Lorsque vous défilez à travers des rubriques, listes, etc. les éléments que vous sélectionnez seront généralement mis à avant avec un contour subtile, mais ça n'est pas toujours le cas pour toutes les choses. Si vous vous retrouvez complètement perdu, vous pouvez appuyer sur Ctrl + F5 pour rafraîchir la page courante et recommencer en haut de la page.</p>
+</div>
+
+<p>NVDA a beaucoup de commandes clavier, et nous n'allons pas toutes les lister ici. Les principales dont vous aurez besoin pour tester une page web sont dans le tableau suivant. Dans les raccourcis clavier, "NVDA" veut dire "le modificateur NVDA".</p>
+
+<table class="standard-table">
+ <caption>Les raccourcis clavier NVDA les plus communs</caption>
+ <thead>
+ <tr>
+ <th scope="col">Raccourci clavier</th>
+ <th scope="col">Description</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>NVDA + Q</td>
+ <td>
+ <p>Arrête NVDA après que vous l'ayez démarré.</p>
+ </td>
+ </tr>
+ <tr>
+ <td>NVDA + curseur haut</td>
+ <td>Lit la ligne courante.</td>
+ </tr>
+ <tr>
+ <td>NVDA + curseur bas</td>
+ <td>Commence à lire à la position courante.</td>
+ </tr>
+ <tr>
+ <td>curseur haut ou curseur bas, ou Shift + Tab et Tab</td>
+ <td>
+ <p>Se déplace à l'élément suivant/précédent de la page et le lit.</p>
+ </td>
+ </tr>
+ <tr>
+ <td>curseur gauche et curseur droit</td>
+ <td>
+ <p>Se déplace au caractère suivant/précédent dans l'élément courant et le lit.</p>
+ </td>
+ </tr>
+ <tr>
+ <td>Shift + H et H</td>
+ <td>
+ <p>Se déplace au titre suivante/précédente et le lit.</p>
+ </td>
+ </tr>
+ <tr>
+ <td>Shift + K et K</td>
+ <td>
+ <p>Se déplace au lien suivant/précédent et le lit.</p>
+ </td>
+ </tr>
+ <tr>
+ <td>Shift + D et D</td>
+ <td>
+ <p>Se déplace au repère de document (par ex. <code>&lt;nav&gt;</code>) suivant/précédent et le lit.</p>
+ </td>
+ </tr>
+ <tr>
+ <td>Shift + 1–6 et 1–6</td>
+ <td>
+ <p>Se déplace au titre (niveau 1 à 6) suivant/précédent et le lit.</p>
+ </td>
+ </tr>
+ <tr>
+ <td>Shift + F et F</td>
+ <td>
+ <p>Se déplace à l'entrée de formulaire suivante/précédente et se focalise dessus.</p>
+ </td>
+ </tr>
+ <tr>
+ <td>Shift + T et T</td>
+ <td>
+ <p>Se déplace sur la donnée de tableau suivante/précédente et se focalise dessus.</p>
+ </td>
+ </tr>
+ <tr>
+ <td>Shift + B et B</td>
+ <td>
+ <p>Se déplace sur le bouton suivant/précédent et lit son libellé.</p>
+ </td>
+ </tr>
+ <tr>
+ <td>Shift + L et L</td>
+ <td>
+ <p>Se déplace à la liste suivante/précédente et lit son premier item de liste.</p>
+ </td>
+ </tr>
+ <tr>
+ <td>Shift + I et I</td>
+ <td>
+ <p>Se déplace à l'item de liste suivant/précédent et le lit.</p>
+ </td>
+ </tr>
+ <tr>
+ <td>Entrée/Retour</td>
+ <td>
+ <p>(quand un lien/bouton ou autre élément activable est sélectionné) Active l'élément.</p>
+ </td>
+ </tr>
+ <tr>
+ <td>NVDA + Barre espace</td>
+ <td>
+ <p>(quand un formulaire est sélectionné) Entre dans le formulaire pour que les éléments puissent être sélectionnés individuellement, ou quitter le formulaire si vous êtes déjà dedans.</p>
+ </td>
+ </tr>
+ <tr>
+ <td>Shift Tab et Tab</td>
+ <td>
+ <p>(à l'intérieur d'un formulaire) Se déplacer entre les entrées de formulaire.</p>
+ </td>
+ </tr>
+ <tr>
+ <td>Curseur haut et curseur bas</td>
+ <td>
+ <p>(à l'intérieur d'un formulaire) Modifier les valeurs d'une entrée de formulaire (dans les cas comme les listes déroulantes)</p>
+ </td>
+ </tr>
+ <tr>
+ <td>Barre espace</td>
+ <td>
+ <p>(à l'intérieur d'un formulaire) Sélectionner la valeur choisie.</p>
+ </td>
+ </tr>
+ <tr>
+ <td>Ctrl + Alt + touches fléchées</td>
+ <td>(à l'intérieur d'un tableau) Se déplacer entre les cellules du tableau.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h4 id="Test_avec_lecteur_d'écran">Test avec lecteur d'écran</h4>
+
+<p>Maintenant que vous vous êtes habitué à utiliser un lecteur d'écran, nous aimerions que vous vous habituiez à faire quelques tests d'accessibilité rapides, pour vous faire une idée de comment les lecteurs d'écran se débrouillent avec les bonnes et mauvaises caractéristiques d'une page web :</p>
+
+<ul>
+ <li>Regardez <a href="http://mdn.github.io/learning-area/accessibility/html/good-semantics.html">good-semantics.html</a>, et notez comment les titres sont trouvés pas le lecteur d'écran et rendus disponibles pour être utilisés en navigation. Regardez maintenant <a href="http://mdn.github.io/learning-area/accessibility/html/bad-semantics.html">bad-semantics.html</a>, et observez comme le lecteur d'écran n'obtient aucune de ces informations. Imaginez à quel point cela peut être pénible lorsque vous essayez de naviguer sur une page de texte vraiment longue.</li>
+ <li>Regardez <a href="http://mdn.github.io/learning-area/accessibility/html/good-links.html">good-links.html</a>, et notez comment est-ce qu'ils ont du sens vus hors contexte. Ce n'est pas le cas avec <a href="http://mdn.github.io/learning-area/accessibility/html/bad-links.html">bad-links.html</a> — ceux sont juste tous des "click here".</li>
+ <li>Regardez <a href="http://mdn.github.io/learning-area/accessibility/html/good-form.html">good-form.html</a>, et regardez comment les entrées du formulaire sont décrites en utilisant leurs libellés parce que nous avons utilisé l'élément <code>&lt;label&gt;</code> correctement. Dans <a href="http://mdn.github.io/learning-area/accessibility/html/bad-form.html">bad-form.html</a>, ils ne sont que des "blank" sur toute la ligne, totalement inutiles.</li>
+ <li>Regardez notre exemple <a href="http://mdn.github.io/learning-area/css/styling-boxes/styling-tables/punk-bands-complete.html">punk-bands-complete.html</a>, et observez comment le lecteur d'écran est capable d'associer les colonnes et les lignes de contenu et de les lires toutes ensembles, parce que nous avons défini les entêtes correctement. Dans <a href="http://mdn.github.io/learning-area/accessibility/html/bad-table.html">bad-table.html</a>, aucune des cellules ne peut être associée du tout. Notez que NVDA a étonnamment l'air d'assez bien se comporter lorsque vous n'avez qu'un seul tableau sur une page ; à la place vous pouvez essayer <a href="http://webaim.org/articles/nvda/tables.htm">WebAIM's table test page</a>.</li>
+ <li>Jetez un œil à <a href="http://www.freedomscientific.com/Training/Surfs-up/AriaLiveRegions.htm">WAI-ARIA live regions example</a> que nous avons vu plus tôt, et observez comment le lecteur d'écran va continuer de lire la section qui se met à constamment à jour dès qu'elle se met à jour.</li>
+</ul>
+
+<h3 id="Test_utilisateur">Test utilisateur</h3>
+
+<p>Comme mentionné plus haut, vous ne pouvez pas uniquement compter sur les outils automatisés pour déterminer les problèmes d'accessibilité sur votre site. Il est recommandé que lorsque vous établissez votre plan de test, vous devez inclure quelques groupes d'utilisateur d'accessibilité si c'est possible (voir notre section <a href="https://developer.mozilla.org/fr/docs/Learn/Tools_and_testing/Cross_browser_testing/Testing_strategies#Les_tests_utilisateurs">Test Utilisateur</a> plus tôt dans ce cours pour plus de contexte). Essayez d'inclure des utilisateurs de lecteur d'écran, des utilisateurs exclusifs au clavier, des utilisateurs malentendants, et peut-être d'autres groupes encore, selon vos besoins.</p>
+
+<h2 id="Checklist_de_tests_d'accessibilité">Checklist de tests d'accessibilité</h2>
+
+<p>La liste suivante vous fournit une checklist à suivre pour vous assurer de mener à bien les tests d'accessibilité recommandés pour votre projet :</p>
+
+<ol>
+ <li>Assurez-vous que votre HTML est sémantiquement correct au possible. <a href="https://developer.mozilla.org/fr/docs/Learn/Tools_and_testing/Cross_browser_testing/HTML_et_CSS#La_validation">Le valider</a> est un bon début, comme utiliser un <a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Accessibility#Auditing_tools">outil d'Audit</a>.</li>
+ <li>Vérifiez que votre contenu a du sens lorsque le CSS est désactivé.</li>
+ <li>Assurez-vous que votre fonctionnalité est <a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Accessibility#Using_native_keyboard_accessibility">accessible au clavier</a>. Testez en utilisant Tab, Retour/Entrée, etc.</li>
+ <li>Assurez-vous que votre contenu non-textuel a un <a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Accessibility#Text_alternatives">texte alternatif</a>. Un <a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Accessibility#Auditing_tools">Outil d'audit</a> est bien pour repérer ce type de problèmes.</li>
+ <li>Assurez-vous que votre <a href="https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Accessibility#Color_and_color_contrast">contraste de couleurs</a> est acceptable, en utilisant un outil de vérification approprié.</li>
+ <li>Assurez-vous que le <a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Accessibility#Hiding_content">contenu caché</a> est visible par les lecteurs d'écran.</li>
+ <li>Assurez-vous qu'une fonctionnalité est utilisable sans JavaScript autant que possible.</li>
+ <li>Utilisez ARIA pour améliorer l'accessibilité quand c'est approprié.</li>
+ <li>Exécutez votre site dans un <a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Accessibility#Auditing_tools">Outil d'audit</a>.</li>
+ <li>Testez avec un lecteur d'écran.</li>
+ <li>Incluez une politique/déclaration d'accessibilité à un endroit que l'on peut trouver sur votre site pour dire ce que vous avez fait.</li>
+</ol>
+
+<h2 id="Trouver_de_l'aide">Trouver de l'aide</h2>
+
+<p>Il y a bien d'autres problèmes que vous allez rencontrer avec l'accessibilité ; la chose la plus importante à vraiment savoir est comment trouver des réponses en ligne. Consultez l'article <a href="https://developer.mozilla.org/fr/docs/Learn/Tools_and_testing/Cross_browser_testing/HTML_et_CSS#Trouver_de_l'aide">la section Trouver de l'aide</a> de l'article sur le HTML et le CSS pour des bonnes directions.</p>
+
+<h2 id="Résumé">Résumé</h2>
+
+<p>Espérons que cet article vous aura donné des bonnes connaissances concernant les problèmes principaux d'accessibilité que vous pourrez rencontrer, et comment les tester et les surmonter.</p>
+
+<p>Dans le prochain article nous nous tournerons vers la fonctionnalité de détection dans plus de détail.</p>
+
+<p>{{PreviousMenuNext("Learn/Tools_and_testing/Cross_browser_testing/JavaScript","Learn/Tools_and_testing/Cross_browser_testing/Feature_detection", "Learn/Tools_and_testing/Cross_browser_testing")}}</p>
+
+<p> </p>
+
+<h2 id="Dans_ce_module">Dans ce module</h2>
+
+<ul>
+ <li><a href="/en-US/docs/">Introduction au test en navigateur croisé</a></li>
+ <li><a href="https://developer.mozilla.org/fr/docs/Learn/Tools_and_testing/Cross_browser_testing/Testing_strategies">Stratégies pour mener à bien vos tests</a></li>
+ <li><a href="https://developer.mozilla.org/fr/docs/Learn/Tools_and_testing/Cross_browser_testing/HTML_et_CSS">Gérer les problèmes courants en HTML et CSS</a></li>
+ <li><a href="https://developer.mozilla.org/fr/docs/Learn/Tools_and_testing/Cross_browser_testing/JavaScript">Gérer les problèmes courants en JavaScript</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Accessibility">Handling common accessibility problems</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Feature_detection">Implementing feature detection</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Automated_testing">Introduction to automated testing</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Your_own_automation_environment">Setting up your own test automation environment</a></li>
+</ul>
+
+<p> </p>
diff --git a/files/fr/learn/tools_and_testing/cross_browser_testing/html_et_css/index.html b/files/fr/learn/tools_and_testing/cross_browser_testing/html_et_css/index.html
new file mode 100644
index 0000000000..7b2a01fc95
--- /dev/null
+++ b/files/fr/learn/tools_and_testing/cross_browser_testing/html_et_css/index.html
@@ -0,0 +1,509 @@
+---
+title: Gérer les problèmes courants en HTML et CSS
+slug: Learn/Tools_and_testing/Cross_browser_testing/HTML_et_CSS
+tags:
+ - Apprentissage
+ - CSS
+ - Débutant
+ - HTML
+ - Sélecteurs
+ - linting
+ - navigateur croisé
+ - test
+translation_of: Learn/Tools_and_testing/Cross_browser_testing/HTML_and_CSS
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/Tools_and_testing/Cross_browser_testing/Testing_strategies","Learn/Tools_and_testing/Cross_browser_testing/JavaScript", "Learn/Tools_and_testing/Cross_browser_testing")}}</div>
+
+<p class="summary">Maintenant que les bases sont posées, nous allons nous concentrer sur les problèmes courants en navigateur croisé que vous allez rencontrer en code HTML et CSS, et quels outils peuvent être utilisés pour prévenir l'arrivée de ces problèmes, ou résoudre les problèmes qui surviennent. Cela inclut le <a href="https://stackoverflow.com/questions/8503559/what-is-linting">linting code</a>, la gestion des préfixes CSS, l'utilisation des outils de dev des navigateurs pour localiser les problèmes, utiliser des <a href="https://developer.mozilla.org/fr/docs/Glossaire/Polyfill">polyfills</a> pour apporter du support dans les navigateurs, se confronter aux problèmes de responsive design et plus encore.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Prérequis :</th>
+ <td>
+ <p>Connaissances avec le noyau des langages <a href="/en-US/docs/Learn/HTML">HTML</a>, <a href="/en-US/docs/Learn/CSS">CSS</a>, et <a href="/en-US/docs/Learn/JavaScript">JavaScript</a> ; une idée du haut niveau des <a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Introduction">principes du test en navigateur croisé</a>.</p>
+ </td>
+ </tr>
+ <tr>
+ <th scope="row">Objectif :</th>
+ <td>
+ <p>Etre capable de diagnostiquer des problèmes courants de CSS et de HTML en navigateur croisé, et utiliser les techniques et outils appropriés pour les réparer.</p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Les_difficultés_avec_HTML_et_CSS">Les difficultés avec HTML et CSS</h2>
+
+<p>Certains des problèmes avec le HTML et le CSS viennent du fait qu'ils sont tous les deux des langages qui sont assez simples, et souvent les développeurs ne les considèrent pas sérieusement, en termes de s'assurer que le code est bien conçu, efficace, et qu'il décrit sémantiquement les but de la fonctionnalité sur la page. Dans les pires des cas, Javascript est utilisé pour générer tout le contenu et le style d'une page web, ce qui rend vos pages inaccessibles, et moins performantes (générer des éléments de DOM est coûteux). Dans d'autres cas, des fonctionnalités naissantes ne sont pas supportées constamment par tous les navigateurs, ce qui peut empêcher certaines fonctionnalités et styles de fonctionner pour certains utilisateurs. Les problèmes de responsive design sont également courant — un site qui paraît bien sur le navigateur d'un ordinateur de bureau pourra fournir une expérience horrible sur un appareil mobile, à cause du contenu qui est trop petit pour être lu, ou peut-être que le site sera lent à cause de animations coûteuses.</p>
+
+<p>Commençons et regardons comment nous pouvons réduire les erreurs en navigateur croisé issues du HTML/CSS.</p>
+
+<h2 id="Commençons_par_le_commencement_résoudre_les_problèmes_généraux">Commençons par le commencement : résoudre les problèmes généraux</h2>
+
+<p>Nous disions dans le <a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Introduction#Testingdiscovery">premier article de cette série</a> que c'était une bonne stratégie de commencer à tester sur une paire de navigateurs modernes sur desktop/mobile, afin de vous assurer que votre site fonctionne pour l'essentiel, avant de commencer à se concentrer sur les problèmes en navigateur croisé.</p>
+
+<p>Dans nos articles <a href="/en-US/docs/Learn/HTML/Introduction_to_HTML/Debugging_HTML">Debugging HTML</a> et <a href="/en-US/docs/Learn/CSS/Introduction_to_CSS/Debugging_CSS">Debugging CSS</a>, nous avancions quelques conseils très basiques sur le débogage HTML/CSS — si vous ne maîtrisez pas ces bases, vous devriez sans aucun doute aller étudier ces articles avant de continuer.</p>
+
+<p>Il s'agit essentiellement de vérifier si votre code HTML et CSS est bien conçu et s'il ne contient aucune erreur de syntaxe.</p>
+
+<div class="note">
+<p><strong>Note </strong>: Un problème fréquent avec le HTML et le CSS arrive quand différentes règles CSS commencent à entrer en conflit avec une autre. Cela peut être particulièrement problématique lorsque vous utilisez un bout de code tierce. Par exemple, vous pouvez utiliser un modèle CSS et remarquer qu'un des noms de classe qui est utilisé entre en conflit avec un que vous utilisez déjà dans un but différent. Ou vous pouvez trouver que du HTML généré par une API tierce (générateur de bannières publicitaires, par exemple) inclut un nom de classe ou d'ID que vous utilisez déjà dans un but différent. Afin de garantir que cela ne se produira pas, vous devez rechercher les outils que vous allez utiliser en premier et construire votre code en conséquence. Il convient également de relever les "<a href="https://developer.mozilla.org/fr/docs/Glossaire/Namespace">espace de noms</a>" en CSS, par ex. si vous avez un widget, assurez-vous qu'il a des classes distinctes, et ensuite commencez les sélecteurs qui sélectionnent les éléments à l'intérieur du widget avec cette classe, les conflits risqueront moins d'arriver. Par exemple <code>.audio-player ul a</code>.</p>
+</div>
+
+<h3 id="La_validation">La validation</h3>
+
+<p>Pour le HTML, la validation implique de s'assurer que toutes vos balises sont correctement fermées et imbriquées, que vous utilisez un DOCTYPE, et que vous utilisez les balises à leur fin prévue. Une bonne stratégie est de valider régulièrement votre code. On service qui peut le faire est le W3C <a href="https://validator.w3.org/">Markup Validation Service</a>, qui vous permet de montrer votre code, et retourne une liste d'erreurs :</p>
+
+<p><img alt="The HTML validator homepage" src="https://mdn.mozillademos.org/files/12441/validator.png" style="display: block; margin: 0px auto;"></p>
+
+<p>Le CSS a une histoire semblable — vous devez vérifier que vos noms de propriétés sont correctement épelés, ques les valeurs des propriétés sont correctement épelées et qu'elles sont valides pour les propriétés auxquelles elles s'appliquent, que vous n'oubliez aucune accolades ouvrantes et fermantes. Les W3C a un <a class="external external-icon" href="http://jigsaw.w3.org/css-validator/">CSS Validator</a> également disponible à cet effet.</p>
+
+<h3 id="Les_linters">Les linters</h3>
+
+<p>Une autre bonne option à envisager est ce qu'on appelle les applications Linter, qui ne font pas que souligner les erreurs, mais peuvent aussi mettre en évidence des avertissements à propos des mauvaises pratiques dans votre CSS, et encore d'autres points. Les linters peuvent pour la plupart être configurés pour être plus strictes ou plus coulants dans leur rapport d'erreur/avertissement.</p>
+
+<p>Il y a beaucoup d'applications linter en ligne, les meilleures d'entre elles sont probablement <a href="https://www.dirtymarkup.com/">Dirty Markup</a> (HTML, CSS, JavaScript), et <a href="http://csslint.net/">CSS Lint</a> (seulement CSS). Elles vous permettent de coller votre code dans une fenêtre, et mettront en évidence toutes les erreurs avec des croix, qui peuvent être survolées pour obtenir un message d'erreur décrivant le problème. Dirty Markup vous permet également de faire des fixs dans votre code en utilisant le bouton <em>Clean</em>.</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/14113/dirty-markup.png" style="border-style: solid; border-width: 1px; display: block; height: 203px; margin: 0px auto; width: 1204px;"></p>
+
+<p>Néanmoins, ce n'est pas très pratique de devoir copier et coller votre code dans une page web pour vérifier sa validité plusieurs fois. Ce dont vous avez vraiment besoin c'est d'un linter qui s'installera dans votre espace de travail standard avec le minimum de prise de tête.</p>
+
+
+
+<p>La plupart des éditeurs de code ont leur plugins linter. Par exemple, l'éditeur de code <a href="https://atom.io/">Atom</a> de Github possède un riche écosystème de plugins disponibles, avec beaucoup d'options de linting. Voici un exemple pour vous montrer comment un plugin marche généralement :</p>
+
+<ol>
+ <li>Installer Atom (si vous n'avez pas déjà une version à jour installée) — télécharger-le depuis la page Atom indiquée plus haut.</li>
+ <li>Aller dans la boîte de dialogue <em>Préférences...</em> d'Atom (par ex. en sélectionnant <em>Atom </em>&gt; <em>Préférences...</em> sur Mac, ou <em>Fichier </em>&gt; <em>Préférences...</em> sur Windows/Linux) et choisissez l'option <em>Installer</em> dans le menu gauche.</li>
+ <li>Dans le champs texte <em>Rechercher des packages</em>, taper "lint" et presser Entrer/Envoyer pour rechercher des packages liés au linting.</li>
+ <li>Vous devriez voir un package appelé <strong>lint</strong> dans le haut de la liste. Installez celui-ci en premier (en utilisant le bouton <em>Installer</em>), comme les autres linters lui font appel pour fonctionner. Ensuite, installer le plugin <strong>linter-csslint </strong>pour le linting CSS, et le plugin <strong>linter-tidy</strong> pour le linting HTML.</li>
+ <li>Une fois que les packages ont fini de s'installer, essayer de charger un fichier HTML et un fichier CSS : vous verrez plusieurs zones soulignées en vert (pour les avertissements) et des cercles rouges (pour les erreurs) à côté des numéros de ligne, et un panneau séparé en bas qui affiche les numéros de ligne, les messages d'erreur, et parfois qui vous suggère des valeur par défaut ou d'autres solutions.</li>
+</ol>
+
+
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/14109/atom-htmltidy.png" style="display: block; margin: 0 auto;"><img alt="" src="https://mdn.mozillademos.org/files/14107/atom-csslint.png" style="display: block; height: 516px; margin: 0px auto; width: 700px;"></p>
+
+<p>D'autres éditeurs populaires ont des packages de linting similaires. Voir, par exemple :</p>
+
+<ul>
+ <li><a href="www.sublimelinter.com/">SublimeLinter</a> pour Sublime Text</li>
+ <li><a href="https://sourceforge.net/projects/notepad-linter/">Notepad++ linter</a></li>
+</ul>
+
+<h3 id="Les_outils_de_développement_des_navigateurs">Les outils de développement des navigateurs</h3>
+
+<p>Les outils de développement inclus dans la plupart des navigateurs fournissent également des outils pour traquer les erreurs, en particulier pour le CSS.</p>
+
+<div class="note">
+<p><strong>Note</strong> : Les erreurs HTML n'ont pas tendance à se montrer facilement avec les outils de dev, étant donné que le navigateur va essayer de corriger en fermant automatiquement mal les balises ; le validateur W3C est la meilleure façon d'obtenir des erreurs HTML — voir {{anch("Validation")}} plus haut.</p>
+</div>
+
+<p>As an example, in Firefox the CSS inspector will show CSS declarations that aren't applied crossed out, with a warning triangle. Hovering the warning triangle will provide a descriptive error message:</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/14111/css-message-devtools.png" style="display: block; height: 311px; margin: 0px auto; width: 451px;"></p>
+
+<p>Les outils de dev des autres navigateurs ont des fonctionnalités semblables.</p>
+
+<h2 id="Problèmes_fréquents_en_navigateur_croisé">Problèmes fréquents en navigateur croisé</h2>
+
+<p>Attaquons-nous maintenant à certains des problèmes HTML et CSS les plus courants en navigateur croisé. Les sujets principaux que nous allons aborder sont l'absence de support pour les fonctionnalités modernes, et les problèmes de mise en page.</p>
+
+<h3 id="Les_vieux_navigateurs_ne_supportant_pas_les_fonctionnalités_récentes">Les vieux navigateurs ne supportant pas les fonctionnalités récentes</h3>
+
+<p>C'est un problème courant, particulièrement lorsque vous devez supporter de vieux navigateurs (comme les anciennes versions d'IE) ou que vous utilisez des fonctionnalités qui sont implémentées en utilisant des préfixes CSS. En général, les fonctionnalités principales du HTML et du CSS (comme les éléments HTML basiques, les couleurs et styles de texte principaux de CSS) marchent sur la plupart des navigateurs que vous voulez supporter ; la majorité des problèmes sont découverts lorsque que vous commencez à vouloir utiliser des nouveautés comme <a href="https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox">Flexbox</a>, ou <a href="https://developer.mozilla.org/en-US/docs/Web/Apps/Fundamentals/Audio_and_video_delivery">HTML5 video/audio</a>, ou encore plus récent, <a href="https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Grids#Native_CSS_Grids_with_Grid_Layout">CSS Grids</a> ou <a href="https://developer.mozilla.org/en-US/docs/Learn/CSS/Styling_boxes/Advanced_box_effects#-webkit-background-clip_text">-webkit-background-clip: text</a>.</p>
+
+<p>Une fois que vous avez identifié une liste des potentielles technologies à problèmes que vous allez utiliser, c'est une bonne initiative des rechercher sur quels navigateurs elles sont supportées, et quelles techniques associées sont utiles. Voir {{anch("Finding help")}} plus bas.</p>
+
+<h4 id="Comportement_naturel_du_HTML">Comportement naturel du HTML</h4>
+
+<p>Certains problèmes peuvent être résolus, seulement en tirant parti des réactions naturelles du HTML/CSS.</p>
+
+<p>Les éléments HTML non reconnus sont traités par les navigateurs comme des éléments inline anonymes (véritablement des éléments inline avec aucune valeur sémantiques, similaires aux éléments {{htmlelement("span")}} ). Vous pouvez toujours vous référez à eux avec leurs noms, et les styler avec du CSS, par exemple — vous avez juste besoin de vous assurer qu'ils se comportent comme vous le voulez, par exemple configurer <code><span style="font-size: 10.0pt;">display: block;</span></code> sur tous les nouveaux éléments sémantiques (comme {{htmlelement("article")}}, {{htmlelement("aside")}}, etc.), mais seulement sur les vieilles versions d'IE qui ne les reconnaissent pas (donc, IE 8 et plus faible). De cette façon les nouveaux navigateurs peuvent juste utiliser le code normalement, mais les anciennes versions d'IE seront également capables de styler ces éléments.</p>
+
+<div class="note">
+<p><strong>Note </strong>: Voir {{anch("IE conditional comments")}} pour une application efficace.</p>
+</div>
+
+
+
+<p>Des éléments HTML plus complexes comme <a href="/en-US/docs/Web/HTML/Element/video"><span style='font-family: "Courier New"; font-size: 10.0pt;'>&lt;video&gt;</span></a>, <a href="/en-US/docs/Web/HTML/Element/audio"><span style='font-family: "Courier New"; font-size: 10.0pt;'>&lt;audio&gt;</span></a>, et <a href="/en-US/docs/Web/HTML/Element/canvas"><span style='font-family: "Courier New"; font-size: 10.0pt;'>&lt;canvas&gt;</span></a> (et encore d'autres) ont des mécanismes naturels pour que les recours soient ajoutés, qui se basent sur le même principe décrit plus haut. Vous pouvez ajouter un contenu de repli entre la balise ouvrante et fermante, et les navigateurs ne supportant pas la feature vont effectivement ignorer les éléments extérieurs et exécuter le contenu imbriqué.</p>
+
+<p>Par exemple :</p>
+
+<pre class="brush: html"><code class="language-html"><span class="tag token"><span class="tag token"><span class="punctuation token">&lt;</span>video</span> <span class="attr-name token">id</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>video<span class="punctuation token">"</span></span> <span class="attr-name token">controls</span> <span class="attr-name token">preload</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>metadata<span class="punctuation token">"</span></span> <span class="attr-name token">poster</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>img/poster.jpg<span class="punctuation token">"</span></span><span class="punctuation token">&gt;</span></span>
+ <span class="tag token"><span class="tag token"><span class="punctuation token">&lt;</span>source</span> <span class="attr-name token">src</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>video/tears-of-steel-battle-clip-medium.mp4<span class="punctuation token">"</span></span> <span class="attr-name token">type</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>video/mp4<span class="punctuation token">"</span></span><span class="punctuation token">&gt;</span></span>
+ <span class="tag token"><span class="tag token"><span class="punctuation token"> &lt;</span>source</span> <span class="attr-name token">src</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>video/tears-of-steel-battle-clip-medium.webm<span class="punctuation token">"</span></span> <span class="attr-name token">type</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>video/webm<span class="punctuation token">"</span></span><span class="punctuation token">&gt;</span></span>
+ <span class="tag token"><span class="tag token"><span class="punctuation token">&lt;</span>source</span> <span class="attr-name token">src</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>video/tears-of-steel-battle-clip-medium.ogg<span class="punctuation token">"</span></span> <span class="attr-name token">type</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>video/ogg<span class="punctuation token">"</span></span><span class="punctuation token">&gt;</span></span>
+ <span class="comment token">&lt;!-- Flash fallback --&gt;</span>
+ <span class="tag token"><span class="tag token"><span class="punctuation token">&lt;</span>object</span> <span class="attr-name token">type</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>application/x-shockwave-flash<span class="punctuation token">"</span></span> <span class="attr-name token">data</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>flash-player.swf?videoUrl<span class="punctuation token">=</span>video/tears-of-steel-battle-clip-medium.mp4<span class="punctuation token">"</span></span> <span class="attr-name token">width</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>1024<span class="punctuation token">"</span></span> <span class="attr-name token">height</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>576<span class="punctuation token">"</span></span><span class="punctuation token">&gt;</span></span>
+ <span class="tag token"><span class="tag token"><span class="punctuation token">&lt;</span>param</span> <span class="attr-name token">name</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>movie<span class="punctuation token">"</span></span> <span class="attr-name token">value</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>flash-player.swf?videoUrl<span class="punctuation token">=</span>video/tears-of-steel-battle-clip-medium.mp4<span class="punctuation token">"</span></span> <span class="punctuation token">/&gt;</span></span>
+ <span class="tag token"><span class="tag token"><span class="punctuation token">&lt;</span>param</span> <span class="attr-name token">name</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>allowfullscreen<span class="punctuation token">"</span></span> <span class="attr-name token">value</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>true<span class="punctuation token">"</span></span> <span class="punctuation token">/&gt;</span></span>
+ <span class="tag token"><span class="tag token"><span class="punctuation token">&lt;</span>param</span> <span class="attr-name token">name</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>wmode<span class="punctuation token">"</span></span> <span class="attr-name token">value</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>transparent<span class="punctuation token">"</span></span> <span class="punctuation token">/&gt;</span></span>
+ <span class="tag token"><span class="tag token"><span class="punctuation token">&lt;</span>param</span> <span class="attr-name token">name</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>flashvars<span class="punctuation token">"</span></span> <span class="attr-name token">value</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>controlbar<span class="punctuation token">=</span>over&amp;amp;image<span class="punctuation token">=</span>img/poster.jpg&amp;amp;file<span class="punctuation token">=</span>flash-player.swf?videoUrl<span class="punctuation token">=</span>video/tears-of-steel-battle-clip-medium.mp4<span class="punctuation token">"</span></span> <span class="punctuation token">/&gt;</span></span>
+ <span class="tag token"><span class="tag token"><span class="punctuation token">&lt;</span>img</span> <span class="attr-name token">alt</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>Tears of Steel poster image<span class="punctuation token">"</span></span> <span class="attr-name token">src</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>img/poster.jpg<span class="punctuation token">"</span></span> <span class="attr-name token">width</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>1024<span class="punctuation token">"</span></span> <span class="attr-name token">height</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>428<span class="punctuation token">"</span></span> <span class="attr-name token">title</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>No video playback possible, please download the video from the link below<span class="punctuation token">"</span></span> <span class="punctuation token">/&gt;</span></span>
+ <span class="tag token"><span class="tag token"><span class="punctuation token">&lt;/</span>object</span><span class="punctuation token">&gt;</span></span>
+ <span class="comment token">&lt;!-- Offer download --&gt;</span>
+ <span class="tag token"><span class="tag token"><span class="punctuation token">&lt;</span>a</span> <span class="attr-name token">href</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>video/tears-of-steel-battle-clip-medium.mp4<span class="punctuation token">"</span></span><span class="punctuation token">&gt;</span></span>Download MP4<span class="tag token"><span class="tag token"><span class="punctuation token">&lt;/</span>a</span><span class="punctuation token">&gt;</span></span>
+<span class="tag token"><span class="tag token"><span class="punctuation token">&lt;/</span>video</span><span class="punctuation token">&gt;</span></span></code></pre>
+
+<p>Cette exemple (issu de <a href="/en-US/docs/Web/Apps/Fundamentals/Audio_and_video_delivery/cross_browser_video_player">Creating a cross-browser video player</a>) n'inclut pas seulement un lecteur Flash de repli pour les anciennes versions d'IE, mais aussi un lien simple vous permettant de télécharger la vidéo si jamais le lecteur Flash ne fonctionne pas, finalement l'utilisateur peut toujours accéder à la vidéo.</p>
+
+<div class="note">
+<p><strong>Note</strong> : les librairies tierces comme <a href="http://videojs.com/">Video.js</a> et <a href="https://www.jwplayer.com/">JW Player</a> utilisent ce type de mécanismes de recours pour fournir un support en navigateur croisé.</p>
+</div>
+
+<p>Les éléments des formulaire HTML5 présentent également des recours de qualités — HTML5 a introduit des types d'<code><a href="/en-US/docs/Web/HTML/Element/input">&lt;input&gt;</a></code> spéciaux pour insérer des informations spécifiques dans les formulaires, en particulier sur les plateformes mobiles, où fournir une insertion de données sans difficultés est primordiale pour l'expérience utilisateur. Supporter les plateformes apporte des widgets UI spéciaux lorsque ces types d'input sont utilisés, comme le widget calendrier pour entrer des dates.</p>
+
+<p>L'exemple suivant montre des inputs date et time :</p>
+
+<pre class="brush: html">&lt;form&gt;
+ &lt;div&gt;
+ &lt;label for="date"&gt;Enter a date:&lt;/label&gt;
+ &lt;input id="date" type="date"&gt;
+ &lt;/div&gt;
+ &lt;div&gt;
+ &lt;label for="time"&gt;Enter a time:&lt;/label&gt;
+ &lt;input id="time" type="time"&gt;
+ &lt;/div&gt;
+&lt;/form&gt;</pre>
+
+<p>Le résultat de ce code est le suivant :</p>
+
+<div class="hidden">
+<h6 id="Hidden_example">Hidden example</h6>
+
+<pre class="brush: css">label {
+ float: left;
+ width: 30%;
+ text-align: right;
+ }
+
+ input {
+ float: right;
+ width: 65%;
+ }
+
+ label, input {
+ margin-bottom: 20px;
+ }
+
+ div {
+ clear: both;
+ margin: 10px;
+ }
+
+ body {
+ width: 400px;
+ margin: 0 auto;
+ }</pre>
+
+
+
+<pre class="brush: html">&lt;form&gt;
+ &lt;div&gt;
+ &lt;label for="date"&gt;Enter a date:&lt;/label&gt;
+ &lt;input id="date" type="date"&gt;
+ &lt;/div&gt;
+ &lt;div&gt;
+ &lt;label for="time"&gt;Enter a time:&lt;/label&gt;
+ &lt;input id="time" type="time"&gt;
+ &lt;/div&gt;
+ &lt;/form&gt;</pre>
+</div>
+
+<p>{{ EmbedLiveSample('Hidden_example', '100%', 150) }}</p>
+
+<div class="note">
+<p><strong>Note </strong>: Vous pouvez également le voir exécuté en direct depuis <a href="http://mdn.github.io/learning-area/tools-testing/cross-browser-testing/html-css/forms-test.html">forms-test.html</a> sur GitHub (voir aussi le <a href="https://github.com/mdn/learning-area/blob/master/tools-testing/cross-browser-testing/html-css/forms-test.html">code source</a>).</p>
+</div>
+
+<p>Si vous consultez l'exemple sur un navigateur qui supporte les technologies récentes comme Android Chrome ou iOS Safari, vous verrez le widget/fonctionnalité spécial en action quand vous essaierai de saisir des données. Sur des plateformes non compatibles comme Firefox ou Internet Explorer, les inputs vont juste recourir à un input texte normal, finalement l'utilisateur peut toujours entrer des informations.</p>
+
+<p>Note : Bien entendu, cela n'est pas une solution viable pour les besoins de votre projet — la différence dans une présentation visuelle n'est pas désirée, de plus c'est compliqué de garantir que la donnée qui a été inscrite est dans le format que vous voulez qu'elle soit. Pour les formulaires en navigateur croisé, il est préférable de se référer aux simples éléments de formulaire, ou utiliser les éléments avancés de formulaire de manière sélective uniquement sur les navigateurs qui les supportent, ou utiliser une librairie qui fournit des widget décents en navigateur croisé, comme <a href="http://jqueryui.com/">jQuery UI</a> ou <a href="https://bootstrap-datepicker.readthedocs.io/en/latest/">Bootstrap datepicker</a>.</p>
+
+<h4 id="Comportement_naturel_du_CSS">Comportement naturel du CSS</h4>
+
+
+
+<p>Le CSS est sans doute meilleur en solution de recours que le HTML. Si un navigateur rencontre une déclaration ou une règle qu'il ne comprend pas, il la passe complètement sans l'appliquer ou provoquer une erreur. Cela peut être frustrant pour vous et vos utilisateurs si de telles erreurs se glissent à travers le code en production, mais au moins cela veut dire que l'ensemble du site ne va pas crasher à cause d'une erreur, et si utilisé intelligemment vous pouvez vous en servir à votre avantage.</p>
+
+<p>Observons un exemple — une simple boîte stylée avec du CSS, qui a certains styles apportés par différentes caractéristiques CSS3 :</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/14141/blingy-button.png" style="display: block; margin: 0 auto;"></p>
+
+<div class="note">
+<p><strong>Note </strong>: Vous pouvez également voir cet exemple exécuté en direct sur GitHub comme <a href="https://github.com/mdn/learning-area/blob/master/tools-testing/cross-browser-testing/html-css/button-with-fallback.html">button-with-fallback.html</a> (voir aussi le <a href="http://mdn.github.io/learning-area/tools-testing/cross-browser-testing/html-css/button-with-fallback.html">code source</a>).</p>
+</div>
+
+<p>Le bouton a un nombre de déclarations qui le style, mais les deux qui nous intéressent le plus sont les suivantes :</p>
+
+<pre class="brush: css">button {
+ ...
+
+ background-color: #ff0000;
+ background-color: rgba(255,0,0,1);
+ box-shadow: inset 1px 1px 3px rgba(255,255,255,0.4),
+ inset -1px -1px 3px rgba(0,0,0,0.4);
+}
+
+button:hover {
+ background-color: rgba(255,0,0,0.5);
+}
+
+button:active {
+ box-shadow: inset 1px 1px 3px rgba(0,0,0,0.4),
+ inset -1px -1px 3px rgba(255,255,255,0.4);
+}</pre>
+
+<p>Ici on fournit un {{cssxref("background-color")}} <a href="/en-US/docs/Web/CSS/color_value#rgba()">RGBA</a> qui modifie l'opacité au survol afin de donner à l'utilisateur l'information que le bouton est interactif, et une ombre {{cssxref("box-shadow")}} interne semi-transparente pour donner au bouton un peu de texture et de profondeur. Le problème est que les couleurs RGBA et les box shadows ne fonctionnent pas sur les versions d'IE plus vieilles que la 9 — dans les versions plus anciennes le background ne sera juste pas visible du tout et le texte sera illisible, pas bon du tout !</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/14135/unreadable-button.png" style="display: block; margin: 0 auto;"></p>
+
+<p>Pour résoudre ce problème, nous avons ajouté une deuxième déclaration <code>background-color</code>, qui précise juste une couleur hex — c'est un recours supporté par les vieux navigateurs, et agit en tant que solution de repli si les fonctionnalités belles et brillantes ne fonctionnent pas. Ce qui se passe c'est que le navigateur parcourant cette page applique pour commencer la première valeur <code>background-color</code> ; lorsqu'il sélectionne la deuxième déclaration <code>background-color</code>, il remplace la valeur initiale avec cette valeur s'il supporte les couleurs RGBA. S'il ne supporte pas, il ignorera juste toute la déclaration et continuera à avancer.</p>
+
+<div class="note">
+<p><strong>Note </strong>: Il se produit la même chose pour les autres caractéristiques de CSS comme les blocs <a href="/en-US/docs/Web/CSS/Media_Queries/Using_media_queries">media queries</a>, <code><a href="/en-US/docs/Web/CSS/@font-face">@font-face</a></code> et <code><a href="/en-US/docs/Web/CSS/@supports">@supports</a></code> — s'ils ne sont pas supportés, le navigateur va juste les ignorer.</p>
+</div>
+
+<h4 id="Les_commentaires_conditionnels_dIE">Les commentaires conditionnels d'IE</h4>
+
+<p>Les commentaires conditionnels d'IE sont une propriété modifiée de la syntaxe des commentaires HTML, qui peuvent être utilisés pour appliquer du code HTML de manière sélective à différentes versions d'IE. Cela s'est avéré être un mécanisme très efficace pour résoudre les bugs en navigateur croisé. La syntaxe ressemble à ça :</p>
+
+<pre class="brush: html"><span class="c">&lt;!--[if lte IE 8]&gt;
+ &lt;script src="ie-fix.js"&gt;&lt;/script&gt;</span>
+ &lt;link href="ie-fix.css" rel="stylesheet" type="text/css"&gt;
+<span class="c">&lt;![endif]--&gt;</span></pre>
+
+<p>Ce block appliquera les CSS et Javascript spécifiques à IE uniquement si le navigateur qui affiche la page est IE 8 ou plus vieux. <code>lte</code> veux dire "moins que ou égal", mais vous pouvez aussi utiliser lt, gt, gte, <code>!</code> pour NOT, et d'autre syntaxe logique.</p>
+
+<div class="note">
+<p><strong>Note </strong>: L'article <span class="l-d-i l-pa2 t-bg-white"><a href="https://www.sitepoint.com/web-foundations/internet-explorer-conditional-comments/">Internet Explorer Conditional Comments</a> de </span>Sitepoint apporte un tutoriel/référence utile pour les débutants qui explique la syntaxe des commentaires conditionnels en détail.</p>
+</div>
+
+<p>Comme vous pouvez le voir, c'est particulièrement utile pour appliquer des fixes aux vieilles versions d'IE. Le cas d'usage que nous avons mentionné plus tôt (rendre les éléments sémantiques modernes stylables sur les vieilles versions d'IE) peut être atteint facilement en utilisant des commentaires conditionnels, par exemple vous pouvez mettre quelque chose comme ça dans votre feuille de style IE :</p>
+
+<pre class="brush: css">aside, main, article, section, nav, figure, figcaption {
+ display: block;
+}</pre>
+
+<p>Ce n'est cependant pas aussi simple — vous devez également créer une copie de chacun des éléments que vous voulez styler dans le DOM via Javascript, pour les rendre stylable ; c'est un peu bizarre, et nous ne vous ennuierons pas avec les détails ici. Par exemple :</p>
+
+<pre class="brush: js">var asideElem = document.createElement('aside');
+ ...</pre>
+
+<p>Cela paraît assez compliqué à gérer, mais heureusement il y a un {{glossary("polyfill")}} disponible qui fait les fixs nécessaires pour vous, et plus encore — voir <a href="https://github.com/aFarkas/html5shiv">HTML5Shiv</a> pour tous les détails (voir <a href="https://github.com/aFarkas/html5shiv#installation">manual installation</a> pour les usages les plus simples).</p>
+
+<h4 id="Support_de_sélecteur">Support de sélecteur</h4>
+
+<p>Naturellement, aucune caractéristiques CSS ne s'appliquera si vous n'utilisez pas les bons <a href="/en-US/docs/Learn/CSS/Introduction_to_CSS/Selectors">sélecteurs</a> pour sélectionner l'élément que vous voulez styler ! Si vous écrivez juste mal un sélecteur alors le style ne sera juste pas celui attendu sur aucun navigateur, vous devez juste résoudre le problème et trouver ce qui ne va pas avec votre sélecteur. Nous trouvons utile d'inspecter l'élément que vous essayez de styler en utilisant l'outil de dev de votre navigateur, ensuite regarder l'arborescence du fil d'Ariane du DOM que les inspecteurs du DOM fournissent en général afin de voir si votre sélecteur est pertinent par rapport à ce fil d'Ariane.</p>
+
+<p>Par exemple, dans l'outil de dev de Firefox, vous obtenez ce genre rendement en bas de l'inspecteur du DOM :</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/14139/dom-breadcrumb-trail.png" style="display: block; height: 24px; margin: 0px auto; width: 448px;"></p>
+
+<p>Si pour cet exemple vous essayez d'utiliser ce sélecteur, vous vous rendrez compte qu'il ne sélectionnera pas l'élément input comme désiré :</p>
+
+<pre class="brush: css">form &gt; #date</pre>
+
+<p>(L'input <code>date</code> du formulaire n'est pas directement dans le <code>&lt;form&gt;</code> ; vous feriez mieux d'utiliser un sélecteur descendant général plutôt qu'un sélecteur d'enfant).</p>
+
+<p>Il y a néanmoins un autre problème qui apparaît sur les versions d'IE plus anciennes que la 9 c'est qu'il n'y a aucun nouveau sélecteur (principalement les pseudo-classes et les pseudo-éléments comme <code><a href="/en-US/docs/Web/CSS/:nth-of-type">:nth-of-type</a></code>, <code><a href="/en-US/docs/Web/CSS/:not">:not</a></code>, <code><a href="/en-US/docs/Web/CSS/::selection">::selection</a></code>, etc.) qui marche. Si vous voulez les utiliser dans votre CSS et que vous devez supporter les anciennes versions d'IE, une bonne initiative et d'utiliser la librairie <a href="http://selectivizr.com/">Selectivizr</a> de Keith Clark — c'est une petite librairie Javascript qui s'exécute au-dessus d'une librairie Javascript existante comme  <a href="http://jquery.com/">jQuery</a> ou <a href="http://mootools.net/">MooTools</a>.</p>
+
+<ol>
+ <li>Afin de tester cet exemple, faites une copie locale de <a href="https://github.com/mdn/learning-area/blob/master/tools-testing/cross-browser-testing/html-css/selectivizr-example-start.html">selectivizr-example-start.html</a>. Si vous le regarder s'exécuter en direct, vous verrez qu'il contient deux paragraphes, dont l'un est stylé. Nous avons sélectionné le paragraphe avec <code>p:first-child</code>, qui ne fonctionne pas sur les anciennes versions d'IE.</li>
+ <li>Maintenant télécharger <a href="http://mootools.net/">MooTools </a>et <a href="http://selectivizr.com/">Selectivizr</a>, et placez-les dans le même répertoire que votre fichier HTML.</li>
+ <li>Placer le code suivant dans la têtière de votre document HTML, juste avant la balise ouvrante <code>&lt;style&gt;</code> :
+ <pre class="brush: html">&lt;script type="text/javascript" src="MooTools-Core-1.6.0.js"&gt;&lt;/script&gt;
+ &lt;!--[if (gte IE 6)&amp;(lte IE 8)]&gt;
+ &lt;script type="text/javascript" src="selectivizr-min.js"&gt;&lt;/script&gt;
+ &lt;![endif]--&gt;</pre>
+ </li>
+</ol>
+
+<p>Si vous essayer d'exécuter cette page sur une vieille version d'IE, cela devrait bien fonctionner.</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/14137/new-selector-ie7.png" style="border-style: solid; border-width: 1px; display: block; height: 516px; margin: 0px auto; width: 771px;"></p>
+
+<h4 id="Gestion_des_préfixes_CSS">Gestion des préfixes CSS</h4>
+
+<p>Une autre source de problèmes arrive avec les préfixes CSS — ceux sont des mécanismes utilisés à la base pour permettre au navigateur d'implémenter leur propre version d'une fonctionnalité CSS (ou Javascript) tant que la technologie est en stade expérimentale, donc ils peuvent jouer avec et la finaliser sans entrer en conflit avec les implémentations des autres navigateurs, ou la dernière implémentation non-préfixée. Voici par exemple :</p>
+
+<ul>
+ <li>Mozilla utilise <code>-moz-</code></li>
+ <li>Chrome/Opera/Safari utilise <code>-webkit-</code></li>
+ <li>Microsoft utilise <code>-ms-</code></li>
+</ul>
+
+<p>Voici quelques exemples :</p>
+
+<pre class="brush: css">-webkit-transform: rotate(90deg);
+
+background-image: -moz-linear-gradient(left,green,yellow);
+background-image: -webkit-gradient(linear,left center,right center,from(green),to(yellow));
+background-image: linear-gradient(to right,green,yellow);
+</pre>
+
+<p>La première ligne déclare une propriété {{cssxref("transform")}} avec un préfixe <code>-webkit-</code> — c'était nécessaire pour que la transformation fonctionne sur Chrome, etc jusqu'à ce que la fonctionnalité soit finalisée et beaucoup de navigateurs ont ajouté une version de la propriété sans préfixes (au moment de la rédaction, Chrome supportait les deux versions).</p>
+
+<p>Les trois dernières images montrent trois versions différentes de la fonction <code><a href="/en-US/docs/Web/CSS/linear-gradient">linear-gradient()</a></code>, qui est utilisée pour générer un dégradé linéaire dans la background d'un élément :</p>
+
+<ol>
+ <li>La première a un préfixe <code>-moz-</code>, et montre une version plutôt ancienne de la syntaxe (Firefox)</li>
+ <li>La seconde a un préfixe <code>-webkit-</code>, et montre encore une vieille version de la syntaxe de la propriété (également issue d'une vraiment vieille version du moteur Wekkit)</li>
+ <li>La troisième n'a pas de préfixe, et montre la version finale de la syntaxe (inclue dans  <a href="https://drafts.csswg.org/css-images-3/#linear-gradients">CSS Image Values and Replaced Content Module Level 3 spec</a>, qui définit cette fonctionnalité).</li>
+</ol>
+
+<p>Les fonctionnalités préfixées sont supposées ne jamais être utilisées dans des sites web en production — elles sont susceptibles de changer ou d'être supprimées sans avertissement, et causent des problèmes en navigateur croisé. C'est particulièrement un problème lorsque les développeurs décident de n'utiliser que la version <code>-webkit-</code> d'une propriété — ce qui veut dire que le site ne fonctionnera pas sur d'autres navigateurs. En fait, cela arrive tellement souvent que d'autres navigateurs ont commencé à implémenter les versions préfixées <code>-webkit-</code> de plusieurs propriétés CSS, ils marcheront donc avec un tel code. L'utilisation des préfixes fournit par chaque navigateur a récemment déclinée précisément à cause de ce type de problèmes, mais il en reste encore certain qui demandent de l'attention.</p>
+
+<p>Si vous persistez a utiliser des fonctionnalités préfixées, assurez-vous d'utiliser les bonnes. Vous pouvez vérifier quels navigateurs ont besoin de préfixes sur les pages de référence MDN, et des sites comme <a href="http://caniuse.com/">caniuse.com</a>. Si vous doutez, vous pouvez aussi vérifier en faisant des tests directement sur les navigateurs.</p>
+
+<p>Essayez cet exemple simple :</p>
+
+<ol>
+ <li>Ouvrez google.com, ou un autre site qui a un en-tête proéminent ou un niveau de bloc d'élément.</li>
+ <li>Clic droit sur l'élément en question et choisir Inspecter/Inspecter l'élément (ou qu'importe l'option de votre navigateur) — cela devrait ouvrir les outils de dev dans votre navigateur, avec l'élément mis en valeur dans l'inspecteur du DOM.</li>
+ <li>Chercher une fonctionnalité que vous pouvez utiliser pour sélectionner cet élément. Par exemple, au moment de la rédaction, le logo principal de Google a un ID <code>hplogo</code>.</li>
+ <li>Entreposer une référence à cet élément dans une variable, par exemple :
+ <pre class="brush: js">var test = document.getElementById('hplogo');</pre>
+ </li>
+ <li>Maintenant essayez d'appliquer une nouvelle valeur pour la propriété CSS qui vous intéresse sur cet élément ; vous pouvez le faire en utilisant la propriété <a href="/en-US/docs/Web/API/HTMLElement/style">style</a> de l'élément, par exemple essayez de taper ça dans votre console Javascript :</li>
+ <li>
+ <pre class="brush: js">test.style.transform = 'rotate(90deg)'
+test.style.webkitTransform = 'rotate(90deg)'</pre>
+ </li>
+</ol>
+
+<p>Quand vous commencez à taper la transcription du nom de la propriété après le deuxième point (notez qu'en Javascript, les noms des propriétés CSS sont écrites en lower camel case, sans trait d'union), la console Javascript devrait commencer à saisir automatiquement les noms des propriétés qui existent dans le navigateur et qui correspondent au mieux avec ce que vous écrivez. C'est utile pour trouver quelles versions de la propriété est implémentée dans ce navigateur.</p>
+
+<p>A l'heure où ces lignes sont écrites, Firefox et Chrome ont implémenté tous les deux les versions préfixées <code>-webkit-</code> et non préfixées de {{cssxref("transform")}} !</p>
+
+<p>Une fois que vous avez trouvé quels préfixes vous avez besoin de supporter, vous devriez tous les inscrire dans votre CSS, par exemple :</p>
+
+<pre class="brush: css">-ms-transform: rotate(90deg);
+-webkit-transform: rotate(90deg);
+transform: rotate(90deg);</pre>
+
+<p>Cela vous assurera que tous les navigateurs qui supportent n'importe laquelle des formes de la propriété ci-dessus pourront faire marcher la fonctionnalité. Il convient de placer la version non préfixée en dernier, parce qu'elle sera la version la plus récente, que vous voulez que les navigateurs utilisent si c'est possible. Si par exemple un navigateur implémente la version <code>-webkit-</code> et la version non préfixée, il va en premier temps appliquer la version <code>-webkit-</code>, puis la remplacer par la version non préfixée. Vous voulez que cela se produise dans ce sens, et non dans l'autre.</p>
+
+<p>Bien entendu, appliquer cela à de nombreuses différentes règles CSS peut devenir très fastidieux. Il est préférable d'utiliser des outils d'automatisation qui le font pour vous. Et de tels outils existent :</p>
+
+<p>La <a href="http://leaverou.github.io/prefixfree/">prefix-free JavaScript library</a> peut être jointe à une page, et détectera automatiquement quels sont les aptitudes détenues par navigateurs en analysant la page et en ajoutant les préfixes appropriés. C'est très facile et pratique à utiliser, bien qu'il ait quelques inconvénients (voir le lien au-dessus pour plus de détails), et on peut discuter du fait qu'analyser chaque feuille de style de votre site et ajouter des préfixes lors de l'exécution peut être un fardeau pour la puissance de traitement de l'ordinateur pour un grand site.</p>
+
+<p>Une autre solution est d'ajouter automatiquement les préfixes pendant le développement, et cela (et d'autres choses à venir) peut être fait en utilisant des outils comme <a href="https://github.com/postcss/autoprefixer">Autoprefixer</a> et <a href="http://postcss.org/">PostCSS</a>. Ces outils peuvent être utilisés de diverses manières, par exemple Autoprefixer a une <a href="http://autoprefixer.github.io/">version en ligne</a> qui vous permet d'entrer votre CSS non préfixé sur la gauche, et vous donne une version avec préfixes ajoutés sur la droite. Vous pouvez sélectionner quels navigateurs vous voulez afin de vous assurer de bien supporter en utilisant la notation définie dans <a href="https://github.com/postcss/autoprefixer#options">Autoprefixer options </a>; pour plus de détails, voir aussi <a href="https://github.com/ai/browserslist#queries">Browserslist queries</a>, qui est basé dessus. Comme exemple, la requête suivante sélectionnera les deux dernières versions de tous le navigateurs principaux et les versions d'IE  supérieure à la 9.</p>
+
+<pre>last 2 versions, ie &gt; 9</pre>
+
+
+
+<p>Autoprefixer peut aussi être utilisé dans d'autres cas, plus pratiques — voir <a href="https://github.com/postcss/autoprefixer#usage">Autoprefixer usage</a>. Par exemple vous pouvez l'utiliser avec un exécuteur de tâche/outil de build comme <a href="http://gulpjs.com/">Gulp </a>ou <a href="https://webpack.github.io/">Webpack </a>pour ajouter automatiquement les préfixes une fois que le développement a été fait. (Expliquer comment cela fonctionne est plutôt au-delà de la portée de cet article).</p>
+
+<p>Vous pouvez également utiliser un plugin pour éditeur de texte comme Atom ou Sublime text. Par exemple, dans Atom :</p>
+
+<ol>
+ <li>Vous pouvez l'installer en allant dans <em>Préférences</em> &gt; <em>Installer</em>, chercher <em>Autoprefixer</em>, puis cliquer sur installer.</li>
+ <li>Vous pouvez configurer une requête navigateur en appuyant sur le bouton <em>Settings</em> d'Autoprefixer et entrer la requête dans le champs texte de la section <em>Setting</em> de la page.</li>
+ <li>Dans votre code, vous pouvez sélectionner des sections de CSS auxquelles vous voulez ajouter des préfixes, ouvrez la palette de commande (<em>Cmd</em>/<em>Ctrl</em> + <em>Shift</em> + <em>P</em>), puis tapez Autoprefixer dedans et sélectionnez le résultat Autoprefixer qui auto complète.</li>
+</ol>
+
+<p>En tant qu'exemple, nous avons entré le code suivant :</p>
+
+<pre class="brush: css">body {
+ display: flex;
+}</pre>
+
+<p>Nous l'avons sélectionné et exécuté la commande Autoprefixer, et il l'a remplacé par ça :</p>
+
+<pre class="brush: css">body {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+}</pre>
+
+<h3 id="Les_problèmes_de_mise_en_page">Les problèmes de mise en page</h3>
+
+<p>Un autre problème qui peut survenir est la différence de mise en page entre les navigateurs. Historiquement c'était traité comme bien plus qu'un problème, mais ces derniers temps, avec les navigateurs modernes qui ont tendance à supporter le CSS plus systématiquement, les problèmes de mise en page ont plus tendance à être couramment associés avec :</p>
+
+<ul>
+ <li>Le manque (ou différences dans) de support pour les dispositions modernes.</li>
+ <li>Les dispositions qui ne paraissent pas bonnes sur les navigateurs mobiles (par ex. les problèmes en responsive design).</li>
+</ul>
+
+<div class="note">
+<p><strong>Note</strong> : Historiquement les développeurs web étaient habitués à utiliser des fichiers CSS appelés resets, qui supprimaient tous les styles par défaut des navigateurs qui s'appliquaient au HTML, et ensuite appliquaient leurs propres styles pour tout le reste — c'était fait pour rendre le style sur un projet plus cohérent, et réduire les possibles problèmes en navigateur croisé, spécialement pour les choses issues de la mise en page. Toutefois, cela a récemment été défini comme exagéré. Le meilleur équivalent que nous avons de nos jours c'est le <a href="https://necolas.github.io/normalize.css/">normalize.css</a>, un peu de CSS propre qui style discrètement par-dessus le style par défaut des navigateurs afin de rendre les éléments plus cohérents et fixe quelques problèmes de disposition. Nous vous recommandons d'appliquer normalize.css sur toutes vos pages HTML.</p>
+</div>
+
+<div class="note">
+<p><strong>Note </strong>:  Lorsque vous essayer de localiser un problème de disposition difficile, une bonne technique et d'ajouter une couleur éclatante {{cssxref("outline")}} sur l'élément dérangeant, ou sur tous les éléments à côté. Cela facilite la tâche pour voir où tous les éléments sont placés. Voir <a href="http://www.otsukare.info/2016/10/05/debugging-css" rel="bookmark" title="Permalink to Debug your CSS with outline visualizations.">Debug your CSS with outline visualizations</a> pour plus de détails...</p>
+</div>
+
+<h4 id="Support_pour_les_nouvelles_caractéristiques_de_disposition">Support pour les nouvelles caractéristiques de disposition</h4>
+
+<p>La plupart du travail de mise en page sur le web aujourd'hui et réalisé en utilisant les <a href="/en-US/docs/Learn/CSS/CSS_layout/Floats">floats</a> — c'est parce que les floats sont bien supportés (depuis IE 4, bien qu'il y ait un certain nombre de bugs qui auront besoin d'être examinés si vous essayez de supporter IE aussi loin). Il n'y a néanmoins pas de véritables explications sur la mise en page — utiliser les floats comme nous les utilisons est un vrai hack — et ils ont de sérieuses limites (par ex. voir <a href="https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox#Why_Flexbox">Why Flexbox?</a>)</p>
+
+<p>Plus récemment, des mécanismes dédiés à la disposition ont fait leur apparition, comme <a href="/en-US/docs/Learn/CSS/CSS_layout/Flexbox">Flexbox</a> et <a href="/en-US/docs/Learn/CSS/CSS_layout/Grids#Native_CSS_Grids_with_Grid_Layout">CSS Grids</a>, qui rendent les tâches ordinaires de disposition bien plus simples et enlèvent les défauts. Ils ne sont cependant pas bien supportés dans les navigateurs :</p>
+
+<ul>
+ <li>Les grilles CSS sont très récentes ; au moment de la rédaction, elles n'étaient <a href="http://gridbyexample.com/browsers/">supportées</a> que par les toutes nouvelles versions des navigateurs modernes.</li>
+ <li>Flexbox est <a href="/en-US/docs/Learn/CSS/CSS_layout/Flexbox#Cross_browser_compatibility">bien supportée</a> dans les navigateurs modernes, mais amène des problèmes dans les vieux navigateurs. IE9 ne le supporte pas du tout, et IE 10 et les vieilles versions d'iOS/desktop Safari supportent respectivement des vieilles versions incompatibles des spécifications de flexbox. Ceci amène à s'intéresser au jonglage des préfixes de navigateur si vous voulez essayer d'utiliser flexbox sur tous ces navigateurs (voir <a href="https://dev.opera.com/articles/advanced-cross-browser-flexbox/">Advanced Cross-Browser Flexbox</a> pour vous faire une idée).</li>
+</ul>
+
+<p>Les fonctionnalités de disposition ne sont pas aussi simples pour fournir des solutions de repli que de simples couleurs, ombres ou dégradés. Si les propriétés de disposition sont ignorées, la totalité de votre design sera réduit en pièces. De ce fait, vous devez utiliser une fonctionnalité de détection pour détecter si les navigateurs qui consultent votre site supportent ces caractéristiques de disposition, et appliquer différentes dispositions de manière sélective selon le résultat (nous couvrirons les fonctionnalités de détection dans un article à venir).</p>
+
+<p>Par exemple, vous pourriez appliquer une disposition flexbox sur les navigateurs modernes, et aussi appliquer une disposition en float pour les plus vieux navigateurs qui ne supportent pas flexbox.</p>
+
+<div class="note">
+<p><strong>Note </strong>: Il y a une fonctionnalité assez récente en CSS appelé <code><a href="/en-US/docs/Web/CSS/@supports">@supports</a></code>, qui vous permet d'implémenter des tests de détection de fonctionnalités natives.</p>
+</div>
+
+<h4 id="Les_problèmes_de_responsive_design">Les problèmes de responsive design</h4>
+
+<p>Le design responsive est la pratique de créer des dispositions web qui s'adaptent en fonction des facteurs de formes de l'appareil — par exemple différentes tailles d'écran, l'orientation (portait ou paysage), ou la résolution. Une disposition pour ordinateur de bureau par exemple paraîtra atroce lorsqu'elle sera affichée sur un appareil mobile, vous allez donc devoir fournir une disposition appropriée aux mobiles en utilisant les <a href="/en-US/docs/Web/CSS/Media_Queries">media queries</a>, et assurez-vous qu'il est appliqué correctement en utilisant <a href="/en-US/docs/Mozilla/Mobile/Viewport_meta_tag">viewport</a>. Vous pouvez trouver un bilan précis de telles pratiques dans <a href="/en-US/docs/Web/Apps/Progressive/Responsive/responsive_design_building_blocks">The building blocks of responsive design</a>.</p>
+
+<p>La résolution est également très préoccupante — par exemple, les appareils mobiles sont moins susceptibles d'avoir besoin de grosses images lourdes que des ordinateurs de bureau, et ont davantage tendance à avoir des connexions internet plus lentes et sans doute un échange de données coûteux qui gaspille la bande passante qui est un problème supplémentaire. De plus, certains appareils peuvent avoir une gamme de plusieurs résolutions, ce qui veut dire que des petites images peuvent s'afficher pixelisées. Il y a un nombre de techniques qui vous permette de travailler autour de tels problèmes, des simples <a href="/en-US/Apps/Progressive/Responsive/Mobile_first">mobile first media queries</a>, aux plus complexes <a href="/en-US/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images#Resolution_switching_Different_sizes">responsive image techniques</a>.</p>
+
+<p>Une autre difficulté qui peut présenter des problèmes c'est le support des fonctionnalités par les navigateurs qui rendent les techniques suscitées possibles. Les media queries ne sont pas supportés sur IE 8 ou plus vieux, donc si vous voulez utiliser une disposition mobile en premier lieu puis une disposition pour ordinateur de bureau qui applique aux vieilles versions d'IE, vous devrez appliquer un media querie {{glossary("polyfill")}} à votre page, comme <a href="https://code.google.com/archive/p/css3-mediaqueries-js/">css3-mediaqueries-js</a> ou <a href="https://github.com/scottjehl/Respond">Respond.js</a>.</p>
+
+<h2 id="Trouver_de_laide">Trouver de l'aide</h2>
+
+<p>Il y bien d'autres problèmes que vous allez rencontrer avec le HTML et le CSS ; la chose la plus important à vraiment savoir est de comment trouver des solutions en ligne.</p>
+
+<p>Parmi les meilleures sources d'information de support il y a Mozilla Developer Network (c'est où vous vous trouvez actuellement !), <a href="http://stackoverflow.com/">stackoverflow.com</a> et <a href="http://caniuse.com/">caniuse.com</a>.</p>
+
+<p>Pour utiliser le Mozilla Developer Network (MDN), la plupart des gens font une recherche de la technologie sur laquelle ils essayent de trouver des informations, et ajoutent le terme "mdn", par exemple "mdn HTML5 video". MDN contient plusieurs types de contenus utiles :</p>
+
+<ul>
+ <li>Du contenu de référence sur le support navigateur pour les technologies web côté client, par ex. la <a href="/en-US/docs/Web/HTML/Element/video">page de référence &lt;video&gt;</a>.</li>
+ <li>D'autres références de support, par ex. <a href="/en-US/docs/Web/HTML/Supported_media_formats">Media formats supported by the HTML audio and video elements</a>.</li>
+ <li>Des tutoriaux utiles qui résolvent des problèmes spécifiques, par exemple <a href="/en-US/docs/Web/Apps/Fundamentals/Audio_and_video_delivery/cross_browser_video_player">Créer un lecteur vidéo en navigateur croisé</a>.</li>
+</ul>
+
+<p><a href="http://caniuse.com/">caniuse.com</a> fournit des informations de support, tout au long avec des ressources externes. Par exemple, voir <a href="http://caniuse.com/#search=video">http://caniuse.com/#search=video</a> (vous avez juste à entrer la fonctionnalité que vous recherchez dans la boîte de recherche)</p>
+
+<p><a href="http://stackoverflow.com/">stackoverflow.com</a> (SO) est un forum en ligne où vous pouvez poser des questions et avez un ensemble de développeurs partageant leurs solutions, observez les commentaires passés, et aidez les autres développeurs. Nous vous conseillons de chercher et de regarder s'il existe déjà une réponse à votre question, avant de poster une nouvelle question. Par exemple, nous avons cherché pour "cross browser html5 video" sur SO, et très rapidement la solution <a class="question-hyperlink" href="http://stackoverflow.com/questions/16212510/html5-video-with-full-cross-browser-compatibility">HTML5 Video with full cross browser compatibility</a> est remontée.</p>
+
+<p>Par ailleurs, essayez de chercher votre moteur de recherche favori pour trouver une réponse à vos problèmes. C'est souvent utile de chercher les messages d'erreur spécifiques si vous en avez — d'autres développeurs seront susceptibles d'avoir les mêmes problèmes que vous</p>
+
+<h2 id="Résumé">Résumé</h2>
+
+<p>Vous devriez maintenant être familier avec les problèmes principaux en navigateur croisé avec HTML et CSS que vous rencontrerez en développement web, et comment faire pour les résoudre.</p>
+
+<p>{{PreviousMenuNext("Learn/Tools_and_testing/Cross_browser_testing/Testing_strategies","Learn/Tools_and_testing/Cross_browser_testing/JavaScript", "Learn/Tools_and_testing/Cross_browser_testing")}}</p>
+
+
+
+<h2 id="Dans_ce_module">Dans ce module</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Introduction">Introduction to cross browser testing</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Testing_strategies">Strategies for carrying out testing</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/HTML_and_CSS">Handling common HTML and CSS problems</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/JavaScript">Handling common JavaScript problems</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Accessibility">Handling common accessibility problems</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Feature_detection">Implementing feature detection</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Automated_testing">Introduction to automated testing</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Your_own_automation_environment">Setting up your own test automation environment</a></li>
+</ul>
diff --git a/files/fr/learn/tools_and_testing/cross_browser_testing/index.html b/files/fr/learn/tools_and_testing/cross_browser_testing/index.html
new file mode 100644
index 0000000000..22d0837e04
--- /dev/null
+++ b/files/fr/learn/tools_and_testing/cross_browser_testing/index.html
@@ -0,0 +1,48 @@
+---
+title: Test sur plusieurs navigateurs
+slug: Learn/Tools_and_testing/Cross_browser_testing
+tags:
+ - Accessibility
+ - Automation
+ - Beginner
+ - CSS
+ - CodingScripting
+ - HTML
+ - JavaScript
+ - Landing
+ - Learn
+ - Module
+ - Testing
+ - Tools
+ - TopicStub
+ - cross browser
+translation_of: Learn/Tools_and_testing/Cross_browser_testing
+---
+<div>{{LearnSidebar}}</div>
+
+<p class="summary">Ce module se concentre sur le test de projets Web sur différents navigateurs. Nous cherchons à identifier votre public cible (par exemple, de quels utilisateurs, navigateurs et appareils avez-vous le plus besoin de vous soucier?), comment procéder aux tests, les principaux problèmes auxquels vous serez confronté avec différents types de code et comment les atténuer, quels outils sont les plus utiles pour vour aider à tester et résoudre les problèmes, et comment utiliser l'automatisation pour accélérer les tests.</p>
+
+<h2 id="Prérequis">Prérequis</h2>
+
+<p>Vous devez vraiment apprendre les bases des langages <a href="/en-US/docs/Learn/HTML">HTML</a>, <a href="/en-US/docs/Learn/CSS">CSS</a>, et <a href="/en-US/docs/Learn/JavaScript">JavaScript</a> de base avant d'essayer d'utiliser les outils détaillés ici.</p>
+
+<h2 id="Guides">Guides</h2>
+
+<dl>
+ <dt><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Introduction">Introduction aux tests multi-navigateurs</a></dt>
+ <dd>Cet article débute le module en donnant un aperçu du sujet des tests multi-navigateurs, en répondant à des questions telles que "qu'est-ce que les tests multi-navigateurs?", "quels sont les types de problèmes les plus courants que vous rencontrerez?", et "quelles sont les principales approches pour tester, identifier et résoudre les problèmes?"</dd>
+ <dt><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Testing_strategies">Stratégies de réalisation des tests</a></dt>
+ <dd>Ensuite, nous explorons la réalisation de tests, en cherchant à identifier un public cible (par exemple, quels navigateurs, appareils et autres segments devez-vous vous assurer qu'ils soient testés), des stratégies de test low fi (procurez-vous une gamme d'appareils et de machines virtuelles et faire des tests adhoc si nécessaire), des stratégies de haute technologie (automatisation, utilisation d'applications de test dédiées), et des tests avec des groupes d'utilisateurs.</dd>
+ <dt><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/HTML_and_CSS">Gérer les problèmes HTML et CSS courants</a></dt>
+ <dd>Nous allons maintenant examiner spécifiquement les problèmes courants entre navigateurs que vous rencontrerez dans le code HTML et CSS, et quels outils peuvent être utilisés pour éviter les problèmes ou résoudre les problèmes qui se produisent. Cela inclut le linting code, la gestion des préfixes CSS, l'utilisation d'outils de développement de navigateur pour localiser les problèmes, utiliser des polyfills pour ajouter un support dans les navigateurs, résoudre les problèmes de design responsive, etc.</dd>
+ <dt><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/JavaScript">Gestion des problèmes JavaScript courants</a></dt>
+ <dd>Nous allons maintenant examiner les problèmes JavaScript courants entre navigateurs et comment les résoudre. Cela inclu des informations sur l'utilisation des outils de développement de navigateur pour localiser et résoudre les problèmes, l'utilisation de polyfills et de librairies pour contourner les problèmes, la mise en <span class="tlid-translation translation" lang="fr"><span title="">œuvre</span></span> des fonctionnalités JavaScript modernes dans les navigateurs plus anciens, etc.</dd>
+ <dt><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Accessibility">Gérer les problèmes d'accessibilité courants</a></dt>
+ <dd>Ensuite, nous tournons notre attention vers l'accessibilité, en fournissant des informations sur les problèmes courants, comment faire des tests simples, et comment utiliser les outils d'audit / d'automatisation pour trouver les problèmes d'accessibilité.</dd>
+ <dt><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Feature_detection">Implémentation de la détection des fonctionnalités</a></dt>
+ <dd>La détection de fonctionnalités implique de déterminer si un navigateur prend en charge un certain bloc de code et d'exécuter un code différent selon qu'il le fait (ou non), afin que le navigateur puisse toujours fournir une expérience de travail plutôt en panne / erreur dans certains navigateurs. Cet article explique comment écrire votre propre détection de fonctionnalités simple, comment utiliser une librairie pour accélérer la mise en <span class="tlid-translation translation" lang="fr"><span title="">œuvre</span></span> et des fonctionnalités natives pour la détection de fonctionnalités telles que <code>@supports</code>.</dd>
+ <dt><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Automated_testing">Introduction aux tests automatisés</a></dt>
+ <dd>Exécuter manuellement des tests sur plusieurs navigateurs et appareils, plusieurs fois par jour, peut devenir fastidieux et prendre du temps. Pour gérer cela efficacement, vous devez vous familiariser avec les outils d'automatisation. Dans cet article, nous examinons ce qui est disponible, comment utiliser les exécuteurs de tâches et les bases de l'utilisation des applications d'automatisation de test de navigateur commerciales telles que Sauce Labs et Browser Stack.</dd>
+ <dt><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Your_own_automation_environment">Configuration de votre propre environnement d'automatisation de test</a></dt>
+ <dd>Dans cet article, nous allons vous apprendre à installer votre propre environnement d'automatisation et à exécuter vos propres tests à l'aide de Selenium/WebDriver et d'une librairie de test telle que selenium-webdriver pour Node. Nous verrons également comment intégrer votre environnement de test local avec des applications commerciales telles que celles décrites dans l'article précédent.</dd>
+</dl>
diff --git a/files/fr/learn/tools_and_testing/cross_browser_testing/introduction/index.html b/files/fr/learn/tools_and_testing/cross_browser_testing/introduction/index.html
new file mode 100644
index 0000000000..64ee2e66ef
--- /dev/null
+++ b/files/fr/learn/tools_and_testing/cross_browser_testing/introduction/index.html
@@ -0,0 +1,207 @@
+---
+title: Introduction au test en navigateur croisé
+slug: Learn/Tools_and_testing/Cross_browser_testing/Introduction
+tags:
+ - Apprentissage
+ - Débutant
+ - multi navigateur
+ - navigateur croisé
+ - test
+translation_of: Learn/Tools_and_testing/Cross_browser_testing/Introduction
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{NextMenu("Learn/Tools_and_testing/Cross_browser_testing/Testing_strategies", "Learn/Tools_and_testing/Cross_browser_testing")}}</div>
+
+<p class="summary">Cet article commence en donnant un aperçu sur le sujet des test sur navigateurs (croisé), répondant aux questions telles que "qu'est-ce que le test en navigateur croisé?", "Quels sont les problèmes les plus communs que vous allez rencontrer?", et "quelles sont les principales approches pour tester, identifier, et fixer les problèmes?"</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Prérequis:</th>
+ <td>Etre familier avec les bases des langage <a href="/en-US/docs/Learn/HTML">HTML</a>, <a href="/en-US/docs/Learn/CSS">CSS</a>, et <a href="/en-US/docs/Learn/JavaScript">JavaScript</a>.</td>
+ </tr>
+ <tr>
+ <th scope="row">Objectif:</th>
+ <td>Acquérir et comprendre des concepts de haut niveau impliqués dans les tests sur multi-navigateur</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Qu'est-ce_que_le_test_en_navigateur_croisé">Qu'est-ce que le test en navigateur croisé?</h2>
+
+<p>Le test de navigateur croisé est une façon de s'assurer que les sites web et les applications que vous créez vont fonctionner sur un nombre acceptable de navigateurs web. En tant que développeur web, il en va de votre responsabilité de vous assurez que non seulement vos projets fonctionnent, mais qu'ils fonctionnent pour tout vos utilisateurs, qu'importe le nombre de navigateurs, d'appareil, ou d'outils d'assistances supplémentaires qu'ils utilisent. Vous devez penser à :</p>
+
+<ul>
+ <li>D'autres navigateurs que celui ou ceux que vous utilisez habituellement sur vos appareils, incluant les navigateurs vieillissant que certaines personnes peuvent continuer d'utiliser, qui ne supportent pas les toutes dernières fonctionnalités fignolées de CSS et JavaScript.</li>
+ <li>Différents appareils avec différentes compatibilités, du tout dernier super smartphone ou tablette, en passant par les TV intelligentes, jusqu'à la tablette la moins chère et même les anciennes versions de smartphones qui ne peuvent exécuter les navigateurs qu'avec des capacités limitées.</li>
+ <li>Certaines personnes handicapées qui naviguent sur le web avec l'aide de technologies d'assistances comme les lecteurs d'écran, ou qui n'utilisent pas de souris (certaines personnes se servent exclusivement de leur clavier).</li>
+</ul>
+
+<p>Souvenez-vous que vous n'êtes pas votre utilisateur — uniquement parce que votre site fonctionne sur votre Macbook Pro ou votre Galaxy Nexus haut de gamme, cela ne veut pas dire qu'il fonctionnera pour tout vos utilisateurs — Il y a encore un paquet de tests à effectuer !</p>
+
+<div class="note">
+<p><strong>Note</strong>: <a href="https://hacks.mozilla.org/2016/07/make-the-web-work-for-everyone/">Make the web work for everyone</a> fournit une perspective plus précise sur les différents navigateurs que les gens utilisent, leur part de marché, et les problèmes de compatibilité entre navigateurs.</p>
+</div>
+
+<p>Il est important de préciser quelque termes de terminologie. Pour commencer, quand on parle de "travailler en navigateurs croisés", on veut vraiment dire que chaque navigateur doit être capable  de fournir une expérience utilisateur acceptable. C'est potentiellement bon pour un site de ne pas fournir exactement la même expérience sur tous les navigateurs, tant que le noyau des fonctionnalités reste accessible. Avec des navigateurs modernes vous pourrez ajouter quelques animations 3D et stylisées, tandis que sur de plus vieux navigateurs vous pouvez juste utiliser un design plus plat représentant la même information. Tant que le propriétaire du site est content, alors vous avez terminé votre travail.</p>
+
+<p>D'un autre côté, ce n'est pas ok qu'un site soit fonctionnel pour les personnes voyantes mais complètement inaccessible pour des utilisateurs qui ont des problèmes de vision  parce que leur application de lecture d'écran ne peut lire aucune des données stockées sur le site.</p>
+
+<p>De plus, lorsqu'on dit "à travers un nombre acceptable de navigateurs", on ne veut pas dire 100% des navigateurs dans le monde — c'est tout simplement impossible. Vous pouvez faire des recherches d'informations (analyse sectorielle) pour savoir quels sont les types de supports et de navigateurs que vos utilisateurs vont utiliser (comme on peut en parler dans le second article — voir <a href="https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Testing_strategies#Gotta_test_%27em_all">Gotta test 'em all?</a>), mais vous ne pouvez pas tout garantir. En tant que developpeur web, vous devez convenir avec le demandeur du site d'une liste de navigateurs et d'appareils sur lesquels le code doit absolument fonctionner, au-delà de ces prérequis, vous devez vous assurer de donner un maximum de chances aux autres navigateurs de pouvoir afficher votre contenu grâce à du code préventif. Cette étape représente le défi le plus important d'un développeur web.</p>
+
+<div class="note">
+<p><strong>Note</strong>: Nous traiterons également du code préventif dans ce module.</p>
+</div>
+
+<h2 id="Pourquoi_y'a-t-il_des_problèmes_en_navigateur_croisé">Pourquoi y'a-t-il des problèmes en navigateur croisé?</h2>
+
+<p>Il y a beaucoup de raisons différentes qui amènent des problèmes en navigateur croisé, et notez qu'ici nous parlons des bug qui se comportent différemment selon les navigateurs / supports / préférences de navigateurs. Avant même d'attaquer les problèmes en navigateurs croisés, commencez déjà par fixer encore et encore tous les bugs présents dans votre propre code (voir <a href="/en-US/docs/Learn/HTML/Introduction_to_HTML/Debugging_HTML">Debugging HTML</a>, <a href="/en-US/docs/Learn/CSS/Introduction_to_CSS/Debugging_CSS">Debugging CSS</a>, et <a href="/en-US/docs/Learn/JavaScript/First_steps/What_went_wrong">What went wrong? Troubleshooting JavaScript</a> des sujets précédents afin de vous rafraichir la mémoire si nécessaire).</p>
+
+<p>Les problèmes en navigateurs croisés se produisent le plus fréquemment parce que :</p>
+
+<ul>
+ <li>Parfois les navigateurs ont des bugs, ou implémentent des fonctionnalités différemment. Cette situation n'est pas aussi grave qu'elle n'y paraît ; si on regarde IE4 et Netscape 4 qui étaient en compétition pour devenir le navigateur dominant dans les années 90,  les compagnies de navigateurs implémentaient délibérément des fonctionnalités différentes les uns des autres afin de prendre l'avantage, ce qui faisait de la vie des développeurs un véritable enfer. Les navigateurs sont biens meilleurs pour respecter les standards de nos jours, mais les bug et les différences continuent d'apparaître de temps en temps.</li>
+ <li>Certains navigateurs peuvent avoir différents niveaux d'acceptation de fonctionnalités par rapport à d'autres. C'est inévitable lorsque vous traitez avec des fonctionnalités de pointe que les navigateurs commencent seulement à implémenter, ou encore si vous devez supporter de vraiment vieux navigateurs qui ne sont plus du tout développés, ou qui ont arrêté  (c-à-d plus aucun travail effectué sur ces derniers) bien longtemps avant même qu'une nouvelle fonctionnalité n'est put être inventée. Par exemple, si vous voulez utiliser des fonctionnalités avancées de Javascript sur votre site, elles ne marcheront sûrement pas sur d'anciens navigateurs. Si vous devez supportez des vieux navigateurs, vous ne devriez pas utiliser ces fonctionnalités ou bien convetir votre code dans une ancienne syntaxe en utilisant un compileur ou quelque chose de similaire si nécessaire.</li>
+ <li>Certains appareils peuvent avoir des contraintes qui rendraient la navigation plus lente sur un site web, ou afficheraient mal le contenu. Par exemple, si un site a été designé pour être beau sur un support PC il paraîtra sûrement très serré et très difficile à lire sur un écran de mobile. Si votre site inclut une quantité importante de grosses animation ça passera sûrement sur une tablette haut de gamme, mais peut-être lent et saccadé sur un appareil de plus basse gamme.</li>
+</ul>
+
+<p>Et encore tant d'autres raisons.</p>
+
+<p>Dans de futurs articles, nous expliquerons les problèmes communs aux navigateurs croisés et examinerons les solution à ces problèmes.</p>
+
+<h2 id="Environnement_pour_tester_en_navigateurs_croisés">Environnement pour tester en navigateurs croisés</h2>
+
+<p>Toutes ces histoires de test en navigateurs croisés peuvent paraître génératrices de chaleur et effrayantes, il ne faut pas — vous avez juste à vous organiser soigneusement pour cela, et vous assurer que vous faîtes suffisamment de tests dans le bon sens afin d'être sûr que vous n'allez pas faire face à des problèmes inattendus. Si vous travaillez sur un gros projet, vous devez le tester régulièrement, afin de vous assurez que les nouvelles fonctionnalités sont accessibles à votre public cible, et que l'addition de nouveau code ne cassent pas d'anciennes fonctionnalités qui marchaient auparavant.</p>
+
+<p>Si vous attendez la fin d'un projet pour démarrer les sessions de tests, chaque bug que vous découvrirez sera une énorme charge de travail et une perte de temps conséquente, plutôt que de le tester en continue, de découvrir les bugs et de les fixer progressivement.</p>
+
+<p>Le flux de travail pour tester et fixer les bugs sur un projet peut-être diviser en quatre phases ( c'est assez dur— certaines personnes peuvent agir un peu différemment ) :</p>
+
+<p><strong>Plan initial &gt; Développement &gt; Test/découvertes &gt; Fixes/itération</strong></p>
+
+<p>Les étapes 2-4 vont tendre à se répéter autant de fois que nécessaire jusqu'à ce que l'implémentation soit aboutie. Nous aborderons les différentes parties du processus de test dans plus de détails dans des articles subséquents, pour l'instant, commençons par résumer ce qu'on peut faire dans chacune de ces étapes.</p>
+
+<h3 id="Plan_initial">Plan initial</h3>
+
+<p>Durant la phase de plan initial, vous allez probablement avoir plusieurs réunions avec le propriétaire du site/client (qui peut être votre boss, ou quelqu'un d'une entreprise extérieure pour qui vous construisez un site web), durant lesquelles vous devez déterminer exactement ce que doit être le site web — quel contenu et quelles fonctionnalités il doit proposer, à quoi il doit ressembler, etc. A partir de ce point vous devez aussi savoir de combien de temps vous disposez pour développer ce site — quelle est leur date limite, et combien vont-ils vous payer pour votre travail ? Nous n'approfondirons pas les détails à ce propos ici, mais les problèmes multi-navigateurs peuvent avoir de sérieuses incidences sur la planification.</p>
+
+<p>Une fois que vous vous êtes fait une idée des fonctionnalités requises et de quelles technologies vous allez avoir besoin pour les construire, vous pouvez commencer à rechercher le public cible — quel navigateurs, supports, etc. ce public cible va-t-il utiliser pour aller sur ce site? Le client peut déjà avoir des données à ce propos provenant de recherches qu'il aurait faites auparavant, p.e. d'un autre site web qu'il possède, ou d'une ancienne version du site sur lequel vous travaillez actuellement. Si ça n'est pas le cas, vous serez en mesure de vous faire une idée en prenant en compte d'autres sources, comme les statistiques d'utilisation pour les concurrents ou bien dans quels pays le site sera délivré. Vous pouvez évidemment vous servir un peu de votre intuition.</p>
+
+<p>Par exemple, vous pouvez être en train de construire un site e-commerce qui ne sera désservi que pour des utilisateurs dans l'Amérique du Nord. Le site devra entièrement fonctionner sur les toutes dernières versions des ordinateurs et des mobiles (iOS, Android, Windows phone) et les navigateurs les plus populaires  — cela doit inclure Chrome (et Opera car il est basé sur le même moteur de rendu que Chrome), Firefox, IE/Edge, et Safari. Il devra aussi fournir une expérience acceptable sur IE 8 et 9, et être accessible avec les conformité de l'Accessibilité Web.</p>
+
+<p>Maintenant que vous connaissez votre plate-forme de test cible, vous devriez revenir en arrière et revoir les fonctionnalités requises ainsi que les technologies que vous allez utiliser. Par exemple, si le client du site de e-commerce veut un tour WebGL 3D de chaque produit intégré dans la page produit, il devra accepter que cela ne sera juste pas possible sur les versions d'IE avant la 11ème. Vous devez vous entendre pour fournir une version du site sans cette fonctionnalité pour les utilisateurs des anciennes versions d'IE.</p>
+
+<p>Vous devriez mettre en place une liste des différents champs de problèmes potentiels.</p>
+
+<div class="note">
+<p><strong>Note</strong>: Vous pouvez trouver les informations concernant les différentes technologies et leur support par les navigateurs en recherchant les différentes fonctionnalités sur MDN — le site sur lequel vous vous trouvez! Vous pouvrez également consulter  <a href="http://caniuse.com/">caniuse.com</a>, pour d'autres détails utiles.</p>
+</div>
+
+<p>Une fois que vous êtes d'accord sur ces détails, vous pouvez continuer et démarrer le développement du site.</p>
+
+<h3 id="Développement">Développement</h3>
+
+<p>Maintenant concernant le développement du site. Vous devez séparer les différentes parties du développement en modules, par exemple vous pouvez séparer les différentes zones du site — page d'accueil, pas produit, panier, tunnel de paiement etc. Vous devrez encore subdiviser ces dernières — implémenter le header et le footer commun, implémenter la vue détaillée de la page produit, implémenter la carte du panier persistent, etc.</p>
+
+<p>Il existe plusieurs stratégies générales concernant le développement multi-navigateurs, par exemple :</p>
+
+<ul>
+ <li>Obtenir toutes les fonctionnalités qui marchent le plus possible de la même manière sur tous les navigateurs croisés. Cela peut induire d'écrire différents codes qui reproduisent la même fonctionnalité d'une manière différentes visant différents navigateurs, ou bien utiliser un {{glossary("Polyfill")}} afin d'imiter tout support manquant en utilisant Javascript ou d'autres technologies, ou utiliser une librairie qui vous autorise à écrire une seule fois le code et ensuite appliquer différents comportements en arrière-plan selon ce que le navigateur prend en charge.</li>
+ <li>Accepter que certaines choses ne vont pas se comporter de la même manière sur tous les navigateurs, et fournir différentes solutions  (acceptables) sur les navigateurs qui ne supportent pas toutes les fonctionnalités. Parfois c'est inévitable à cause des contraintes du support — un écran de cinéma ne va pas donner la même expérience visuelle qu'un écran 4 pouces de smartphone, indépendamment de comment vous programmez votre site.</li>
+ <li>Acceptez que votre site ne va juste pas marcher sur certains vieux navigateurs, et aller au-delà. Il n'y a pas de soucis à condition que votre client/base d'utilisateurs soit d'accord avec ceci.</li>
+</ul>
+
+<p>Normalement votre développement devra inclure une combinaison des trois approches ci-dessus. La chose la plus importante est que vous testiez chacune des petites étapes avant de les commiter— n'attendez pas la fin avant de commencer à tester!</p>
+
+<h3 id="Testdécouverte">Test/découverte</h3>
+
+<p>Après chaque phase d'implémentation, vous allez avoir besoin de tester les nouvelles fonctionnalités. Pour commencer, vous devez vous assurer qu'il n'y a pas des problème généraux avec votre code qui empêcheraient votre fonctionnalité de fonctionner :</p>
+
+<ol>
+ <li>Tester sur quelque navigateurs stables sur votre ordinateur, comme Firefox, Safari, Chrome, ou IE/Edge.</li>
+ <li>Faites quelque test brut, comme essayer de tester votre site exclusivement avec le clavier, ou utiliser votre site avec un lecteur d'écran afin de voir s'il est navigable.</li>
+ <li>Tester sur une plateforme mobile, comme Android ou iOS.</li>
+</ol>
+
+<p>A cet instant, résolvez tous les problèmes que vous avez trouvé sur votre nouveau code.</p>
+
+<p>Ensuite, vous devriez essayer d'étendre votre liste de navigaturs de test à une liste complète des navigateurs du public cible et commencer à vous concentrer sur l'élimination des problèmes en navigateurs croisés (voir le prochaine article <a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Testing_strategies#Gotta_test_%27em_all">determining your target browsers</a> pour plus d'informations). Par exemple:</p>
+
+<ul>
+ <li>Essayez de tester vos dernières modifications sur tous les navigateurs modernes que vous pouvez — incluant Firefox, Chrome, Opera, IE, Edge, et Safari sur ordinateur (Mac, Windows, et Linux, idéallement).</li>
+ <li>Testez sur des navigateurs de téléphones et de tablettes populaires (p.e. iOS Safari sur iPhone/iPad, Chrome et Firefox sur iPhone/iPad/Android),</li>
+ <li>Faites aussi des tests sur tous les navigateurs que vous avez ajouté dans votre liste de cibles.</li>
+</ul>
+
+<p>L'option la plus basique est de juste faire tous les tests que vous pouvez vous-même (demander à vos collègues si vous travaillez en équipe). Vous devez essayer de tester sur des supports physiques lorsque c'est possible.</p>
+
+<p>Si vous n'avez pas les moyens de tester tous les différents navigateurs, systèmes d'exploitation, et les combinaisons sur du matériel physique, vous pouvez aussi utiliser des émulateurs (émuler un support en utilisant un logiciel directement sur votre ordinateur de bureau) et des machines virtuelles (logiciel qui vous permet d'émuler une multitude de systèmes d'exploitation/ des combinaison de logiciels sur votre ordinateur de bureau). C'est un choix apprécié, particulièremenet dans certaines circonstances — par exemple, Windows ne vous autorise pas à avoir plusieurs versions de Windows installées simultanément sur la même machine, ici, utiliser plusieurs machines virtuelles est souvent l'unique solution.</p>
+
+<p>L'autre option est le groupe d'utilisateurs — créer un groupe avec des personnes extérieures à votre équipe de développement afin de tester votre site. Cela peut être un group d'amis ou de la famille, ou un groupe d'autres employés, une classe dans une université à proximité, ou une configuration de testeurs professionnel, où les gens sont payés pour tester votre site et vous fournir des résultats.</p>
+
+<p>Finallement, vous pouvez faire preuve d'astuce avec vos test en utilisant la vérification ou des outils d'automatisation; c'est un choix sensé, quand votre projet prend de l'ampleur, faire tous ces tests à la main peut commencer à devenir vraiment chronophage. Vous pouvez configurer votre propre système d'automatisation de test (<a href="http://www.seleniumhq.org/">Selenium</a> est l'application la plus populaire) qui pourra par exemple charger votre site sur un nombre de différents navigateurs, et :</p>
+
+<ul>
+ <li>voir si un clic sur un bouton amène quelque chose à se dérouler avec succès (comme par exemple, afficher une carte), afficher les résultats une fois les test terminés</li>
+ <li>prendre une impression écran de chaque navigateurs, vous permettant de constater si la disposition reste la même sur les différents écrans des navigateurs.</li>
+</ul>
+
+<p>Si vous le désirez, vous pouvez encore aller plus loin que ça. Il y a des outils professionnels disponibles comme <a href="https://saucelabs.com/">Sauce Labs</a> et <a href="https://www.browserstack.com/">Browser Stack</a> qui font ce type de choses pour vous, sans que vous aillez à vous soucier de la configuration, si vous êtes prêt à investir de l'argent dans vos test. Il est également possible de configurer un environnement qui exécutera les tests de façon automatique pour vous, et vous permet ensuite de vérifier dans vos modifications effectués de votre code si le test continue de passer.</p>
+
+<h4 id="Tester_sur_les_navigateurs_en_avant-première_(bêta)">Tester sur les navigateurs en avant-première (bêta)</h4>
+
+<p>C'est souvent une bonne idée de tester sur les versions en avant-première des navigateurs ; voir les liens suivants :</p>
+
+<ul>
+ <li><a href="https://www.mozilla.org/en-US/firefox/developer/">Firefox Developer Edition</a></li>
+ <li><a href="https://insider.windows.com/">Edge Insider Preview</a></li>
+ <li><a href="https://developer.apple.com/safari/technology-preview/">Safari Technology Preview</a></li>
+ <li><a href="https://www.google.com/chrome/browser/canary.html">Chrome Canary</a></li>
+ <li><a href="http://www.opera.com/computer/beta">Opera Developer</a></li>
+</ul>
+
+<p>C'est surtout répandu lorsque vous utiliser des technologies très récentes sur votre site, et que vous voulez les tester par rapport aux anciennes implémentations, ou si vous rencontrez un bug dans la dernières version sortie d'un navigateur, et que vous voulez vérifier si les développeurs du navigateur on fixé le bug sur une version plus récente.</p>
+
+<h3 id="Fixesitération">Fixes/itération</h3>
+
+<p>Une fois que vous avez découvert un bug, vous devez essayer de le réparer.</p>
+
+<p>La première chose à faire est de réduire l'origine du bug avec un maximum de précisions. Obtenez un maximum d'informations que vous pouvez de la personne qui a rapporté le bug — quelle plateforme(s), support(s), version(s) du navigateurs, etc. Essayer avec des configurations similaires (p.e. la même version de navigateur sur différents ordinateurs, ou plusieurs versions différentes du même navigateurs sur le même support) pour voir jusqu'à quelle échelle le bug persiste.</p>
+
+<p>Ce n'est pas forcément de votre faute — si un bug existe sur un navigateur, alors on peut espérer que le distributeur le fixera rapidement. Il est peut-être même déjà réparé — par exemple si un bug est présent sur la release 49 de Firefox, mais qu'il n'existe plus sur Firefox Nightly (version52), alors il a été fixé. S'il n'a pas été résolu, alors vous pouvez déposer un bug (voir {{anch("Reporting bugs")}}, plus bas).</p>
+
+<p>Si c'est de votre faute, vous devez le résoudre ! Trouver la cause d'un bug implique la même stratégie que pour n'importe quel bug de développement web (à nouveau, voir <a href="/en-US/docs/Learn/HTML/Introduction_to_HTML/Debugging_HTML">Debugging HTML</a>, <a href="/en-US/docs/Learn/CSS/Introduction_to_CSS/Debugging_CSS">Debugging CSS</a>, et <a href="/en-US/docs/Learn/JavaScript/First_steps/What_went_wrong">What went wrong? Troubleshooting JavaScript</a>). Une fois que vous avez découvert ce qui causait le bug, vous devez décider comment est-ce que vous allez travailler sur le navigateur en particulier qui vous pose problèmes — vous ne pouvez pas juste modifier le code du problème, cela risque de casser le code sur un autre navigateur. En général, l'approche veut qu'on fasse bifurquer le code dans une certaine direction, par exemple utilisez une fonctionnalité de détecton en code Javascript pour détecter les situations où une fonctionnalité ne marche pas, et éxecuter un code différent qui fonctionnera dans ce cas.</p>
+
+<p>Lorsque le fix a été créé, vous devrez repéter votre processus de test afin de vous assurer que votre réparation fonctionne bien, et n'a pas causé une faille autre part sur le site ou sur un autre navigateur.</p>
+
+<h2 id="Rapporter_un_bug">Rapporter un bug</h2>
+
+<p>Juste pour redire ce qui a déjà été dit au-dessus, si vous découvrez des bugs sur des navigateurs, vous devez les reporter :</p>
+
+<ul>
+ <li><a href="https://bugzilla.mozilla.org/">Firefox Bugzilla</a></li>
+ <li><a href="https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/">EdgeHTML issue tracker</a></li>
+ <li><a href="https://bugs.webkit.org/">Safari</a></li>
+ <li><a href="https://bugs.chromium.org/p/chromium/issues/list">Chrome</a></li>
+ <li><a href="https://bugs.opera.com/wizard/desktop">Opera</a></li>
+</ul>
+
+<h2 id="Résumé">Résumé</h2>
+
+<p>Cet article devrez vous avoir donné un haut niveau de compréhension des concepts les plus importants que vous devez connaître à propos du test en navigateur croisé. Armé de ce savoir, vous êtes maintenant prêt à démarrer et à commencer à apprendre à propos des stratégies de test multi-navigateur.</p>
+
+<p>{{NextMenu("Learn/Tools_and_testing/Cross_browser_testing/Testing_strategies", "Learn/Tools_and_testing/Cross_browser_testing")}}</p>
+
+<h2 id="Sur_ce_module">Sur ce module</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Introduction">Introduction to cross browser testing</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Testing_strategies">Strategies for carrying out testing</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/HTML_and_CSS">Handling common HTML and CSS problems</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/JavaScript">Handling common JavaScript problems</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Accessibility">Handling common accessibility problems</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Feature_detection">Implementing feature detection</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Automated_testing">Introduction to automated testing</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Your_own_automation_environment">Setting up your own test automation environment</a></li>
+</ul>
diff --git a/files/fr/learn/tools_and_testing/cross_browser_testing/javascript/index.html b/files/fr/learn/tools_and_testing/cross_browser_testing/javascript/index.html
new file mode 100644
index 0000000000..956c757ad4
--- /dev/null
+++ b/files/fr/learn/tools_and_testing/cross_browser_testing/javascript/index.html
@@ -0,0 +1,519 @@
+---
+title: Gérer les problèmes courants en JavaScript
+slug: Learn/Tools_and_testing/Cross_browser_testing/JavaScript
+tags:
+ - Apprentissage
+ - Débutant
+ - JavaScript
+ - Librairies
+ - détection de fonctionnalité
+ - linting
+ - navigateur croisé
+ - polyfills
+ - test
+translation_of: Learn/Tools_and_testing/Cross_browser_testing/JavaScript
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/Tools_and_testing/Cross_browser_testing/HTML_and_CSS","Learn/Tools_and_testing/Cross_browser_testing/Accessibility", "Learn/Tools_and_testing/Cross_browser_testing")}}</div>
+
+<p class="summary">Nous allons maintenant aborder les problèmes Javascript en navigateur croisé et comment les résoudre. Cela comprend des informations sur l'utilisation  des outils de dev des navigateurs pour localiser et fixer les problèmes, l'utilisation des Polyfills et de librairies pour contourner les problèmes, utiliser les fonctionnalités modernes de Javascript sur des vieux navigateurs, et plus encore.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Prérequis :</th>
+ <td>
+ <p>Connaissances de la base des langages <a href="https://developer.mozilla.org/fr/Apprendre/HTML">HTML</a>, <a href="https://developer.mozilla.org/fr/Apprendre/CSS">CSS</a> et <a href="/en-US/docs/Learn/JavaScript">JavaScript</a> ; une idée du haut niveau des <a href="https://developer.mozilla.org/fr/docs/Learn/Tools_and_testing/Cross_browser_testing/Introduction">principes du test en navigateur croisé</a>.</p>
+ </td>
+ </tr>
+ <tr>
+ <th scope="row">Objectif :</th>
+ <td>
+ <p>Être capable de diagnostiquer les problèmes courant de Javascript en navigateur croisé, et l'utilisation des outils et techniques appropriés pour les fixer.</p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Les_problèmes_avec_le_Javascript">Les problèmes avec le Javascript</h2>
+
+<p>Historiquement, Javascript présentaient des problèmes de compatibilité entre navigateurs — retour aux années 1990, les navigateurs majeurs jusqu'alors (Internet Explorer et Netscape) implémentaient des scripts dans différents langages (Netscape avait JavaScript, IE avait JScript et proposait aussi VBScript comme une option), et bien que JavaScript et JScript étaient compatibles dans une certaine mesure (les deux sont basés sur la spécification {{glossary("ECMAScript")}} ), les éléments étaient souvent implémentés avec des conflits, des incompatibilités, ce qui causait bien des cauchemards aux développeurs.</p>
+
+<p>De tels problèmes d'incompabilités ont persistés jusqu'au début des années 2000, étant donné que les vieux navigateurs étaient encore utilisés et devaient donc encore être supportés par les site web. C'est une des raisons principale pour laquelle les librairies comme JQuery ont vu le jour — pour faire abstraction des différences entre les implémentations des navigateur (par ex. voir le bout de code dans <a href="https://developer.mozilla.org/fr/docs/Web/Guide/AJAX/Premiers_pas#.C3.89tape_1_.E2.80.94_Lancement_d.27une_requ.C3.AAte_HTTP">Lancement d'une requête HTTP</a>) comme ça la développeurs n'ont qu'à écrire un simple morceau de code (voir <code><a href="http://api.jquery.com/jquery.ajax/">jQuery.ajax()</a></code>). JQuery (ou qu'importe la librarie que vous utilisez) procédera ensuite au traitement en arrière-plan, donc vous n'aurez pas à le faire.</p>
+
+<p class="entry-title">Les choses se sont bien améliorées depuis ; les navigateurs modernes font un bon travail en supportant "les fonctionnalités classiques de JavaScript", et les conditions pour utiliser ce genre de code ont diminué comme les prérequis pour supporter les plus vieux navigateurs ont diminué (gardez toutefois à l'esprit qu'elles n'ont pas tout entièrement disparues).</p>
+
+<p class="entry-title">De nos jours, la plupart des problèmes de JavaScript en navigateur croisé sont :</p>
+
+<ul>
+ <li>Lorsque la mauvaise qualité du détecteur de code du navigateur, la fonctionnalité de détection de code ou l'utilisation des <a href="https://developer.mozilla.org/fr/docs/Glossaire/Pr%C3%A9fixe_Vendeur">préfixes vendeurs</a> empêchent les navigateurs d'exécuter du code qu'autrement ils pourraient utiliser sans difficultés.</li>
+ <li>Lorsque les développeurs se servent de fonctionnalités nouvelles/naissantes JavaScript (par exemple les fonctionnalités <a href="/en-US/docs/Web/JavaScript/New_in_JavaScript/ECMAScript_6_support_in_Mozilla">ECMAScript 6</a> / <a href="/en-US/docs/Web/JavaScript/New_in_JavaScript/ECMAScript_Next_support_in_Mozilla">ECMAScript Next</a>, les APIs web modernes...) dans leur code, et trouvent que de telles fonctionnalités ne marchent pas sur d'anciens navigateurs.</li>
+</ul>
+
+<p>Nous aborderons tout ces problèmes et d'autres encore plus bas.</p>
+
+<h2 id="Résoudre_les_problèmes_généraux_en_JavaScript">Résoudre les problèmes généraux en JavaScript</h2>
+
+<p>Comme nous le disions dans l'<a href="https://developer.mozilla.org/fr/docs/Learn/Tools_and_testing/Cross_browser_testing/HTML_et_CSS#Commen%C3%A7ons_par_le_commencement_r%C3%A9soudre_les_probl%C3%A8mes_g%C3%A9n%C3%A9raux">article précédent</a> sur le HTML/CSS, vous devriez vous assurer que votre code fonctionne en général, avant de vous concentrer sur les problèmes en navigateur-croisé. Si vous n'êtes pas encore trop familier avec les bases de <a href="https://developer.mozilla.org/fr/docs/Learn/JavaScript/First_steps/What_went_wrong">La résolution JavaScript</a>, vous devriez étudier cet article avant de continuer. Il y a plusieurs problèmes courants en JavaScript avec lesquelles vous devez être attentif, comme :</p>
+
+<ul>
+ <li>Les problèmes basiques de syntaxe et de logique (une fois encore, aller voir <a href="https://developer.mozilla.org/fr/docs/Learn/JavaScript/First_steps/What_went_wrong">La résolution JavaScript</a>).</li>
+ <li>Définir des variables sûres, etc. qui sont défnies dans le périmètre correct, et que vous ne rencontrez pas des conflits entre des items déclarés à des endroits différents (voir <a href="/en-US/docs/Learn/JavaScript/Building_blocks/Functions#Function_scope_and_conflicts">Function scope and conflicts</a>).</li>
+ <li>La confusion à propos de <a href="https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Op%C3%A9rateurs/L_op%C3%A9rateur_this">this</a>, concernant le périmètre auquel il s'applique, et par conséquent si sa valeur et celle que vous souhaitiez. Vous pouvez lire <a href="https://developer.mozilla.org/fr/docs/Learn/JavaScript/Objects/Basics#Qu'est-ce_que_%C2%AB_this_%C2%BB">Qu'est-ce que "this" ?</a> pour une simple introduction ; vous devriez également étudier des exemples comme <a href="https://github.com/mdn/learning-area/blob/7ed039d17e820c93cafaff541aa65d874dde8323/javascript/oojs/assessment/main.js#L143">this one</a>, qui présente un modèle typique de sauvegarde du périmètre de <code>this</code> dans une variable séparée, puis utilise cette variable dans une fonction imbriquée pour que vous soyez sûr que vous appliquez la fonction au bon périmètre de <code>this</code>.</li>
+ <li>Utiliser les fonctions de manière incorrecte dans les boucles — par exemple, dans <a href="https://mdn.github.io/learning-area/tools-testing/cross-browser-testing/javascript/bad-for-loop.html">bad-for-loop.html</a> (voir <a href="https://github.com/mdn/learning-area/blob/master/tools-testing/cross-browser-testing/javascript/bad-for-loop.html">code source</a>), on boucle sur 10 itérations, à chaque fois on créé un paragraphe et on y ajoute un évènement gestionnaire <a href="https://developer.mozilla.org/fr/docs/Web/API/GlobalEventHandlers/onclick">onclick</a>. Lorsqu'ils sont cliqués, chacun d'entre eux doit fournir un message d'alerte contenant son numéro (la valeur de <code>i</code> au moment où il était créé), cependant chacun d'entre eux retourne <code>i</code> comme 11, parce que les boucle for font toutes leurs itérations avant que les fonctions imbriquées ne soit appelées. Si vous voulez que ça marche correctement, vous devez définir une fonction pour ajouter le gestionnaire séparément, l'appellant à chaque itération et lui passer la valeur courante de <code>para</code> et <code>i</code> à chaque fois (ou quelque chose de similaire). Voir <a href="https://mdn.github.io/learning-area/tools-testing/cross-browser-testing/javascript/good-for-loop.html">good-for-loop.html</a> (voir également le <a href="https://github.com/mdn/learning-area/blob/master/tools-testing/cross-browser-testing/javascript/good-for-loop.html">code source</a>) pour une version qui fonctionne.</li>
+ <li>S'assurer que les opérations asynchrones sont retournées avant d'essayer d'utiliser les valeurs qu'elles retournent. Par exemple, <a href="https://developer.mozilla.org/fr/docs/Web/Guide/AJAX/Premiers_pas#.C3.89tape_3_.E2.80.94_Un_exemple_simple">cet exemple Ajax</a> vérifie que la requête est complète et que la réponse a été retournée avant qu'on ait essayé d'utiliser cette réponse pour quoi que ce soit. Ce type d'opération a été rendue plus simple à gérer grâce à l'introduction des <a href="https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/Promise">Promises</a> dans le langage JavaScript.</li>
+</ul>
+
+<div class="note">
+<p><strong>Note </strong>: <a href="https://www.toptal.com/javascript/10-most-common-javascript-mistakes">Buggy JavaScript Code: The 10 Most Common Mistakes JavaScript Developers Make</a> a des discussions intéressantes à propos de ces erreurs courantes et plus encore.</p>
+</div>
+
+<h3 id="Les_linters">Les linters</h3>
+
+<p>Comme avec <a href="https://developer.mozilla.org/fr/docs/Learn/Tools_and_testing/Cross_browser_testing/HTML_et_CSS#Les_linters">le HTML et le CSS</a>, vous pouvez garantir une meilleure qualité, vous êtes moins susceptible de faire des erreurs en utilisant un linter, qui vous signale les erreurs et met en évidence les avertissement concernant les mauvaises pratiques, etc., et peut être configuré pour être plus stricte ou plus coulant dans leurs rapport d'erreur/avertissement. Les linters JavaScript/ECMAScript que nous vous recommandons sont <a href="http://jshint.com/">JSHint</a> et <a href="http://eslint.org/">ESLint</a> ; ils peuvent être utilisés de différentes façons, nous détaillerons certaines d'entre elles plus bas.</p>
+
+<h4 id="En_ligne">En ligne</h4>
+
+<p>La <a href="http://jshint.com/">page d'accueil de JSHint</a> fournit un linter en ligne, qui vous permet d'entrer votre code JavaScript sur la gauche et vous fournit un résultat sur la droite, incluant des indicateurs, des avertissements, et des erreurs.</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/14175/jshint-online.png" style="display: block; margin: 0 auto;"></p>
+
+<h4 id="Les_plugins_des_éditeurs_de_code">Les plugins des éditeurs de code</h4>
+
+<p>Ce n'est pas très pratique de devoir copier et coller votre code sur une page web pour vérifier sa validité à plusieur reprises. Ce dont vous avez vraiment besoin c'est un linter qui va s'adapter à votre espace de travail standard avec le minimum de prise de tête. Beaucoup d'éditeurs de code ont leur plugins linter, par exemple l'éditeur de code <a href="https://atom.io/">Atom</a> de Github a un plugin JSHint disponible :</p>
+
+<p>Pour l'installer :</p>
+
+<ol>
+ <li>Installez Atom (si vous n'avez pas encore une version à jour déjà installée) — téléchargez-le depuis la page Atom linkée plus haut.</li>
+ <li>Aller dans la boîte de dialogue <em>Préférences...</em> d'Atom (par ex. en choisissant <em>Atom</em> &gt; <em>Préférences... </em>sur Windows/Linux) et choisissez l'option <em>Installer</em> dans le menu gauche.</li>
+ <li>Dans le champs text <em>Rechercher packages</em>, taper "jslint" et presser Entrée/Envoyer pour rechercher des packages en liaisons avec le linting.</li>
+ <li>Vous devriez voir un package appellé <strong>lint</strong> en haut de la liste. Installez-le en premier (en utilisant le bouton <em>Installer</em>), comme les autres sont dépendants de celui-ci pour fonctionner. Ensuite, installez le plugin <strong>linter-jshint</strong>.</li>
+ <li>Une fois que les packages ont terminé de s'installer, essayez de charger un fichier JavaScript : vous verrez tous les problèmes surlignés en vert (pour les avertissements) et des cercles rouges (pour les erreurs) à côté des numéros de lignes, et un panneau séparé en bas qui vous fournit les numéros de lignes, les messages d'erreur, et parfois des valeur suggérées ou d'autres solutions.</li>
+</ol>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/14173/jshint-linter.png" style="display: block; margin: 0 auto;">D'autres éditeurs répandus ont des packages similaires de linting disponibles. Par exemple, voir la section "Plugins for text editors and IDEs" de la <a href="http://jshint.com/install/">page d'installation de JSHint</a>.</p>
+
+<h4 id="Autres_usages">Autres usages</h4>
+
+<p>Il y a d'autres façons d'utiliser de tels linter ; vous pouvez vous renseignez à ce propos sur les pages d'installation de <a href="http://jshint.com/install/">JSHint</a> et <a href="http://eslint.org/docs/user-guide/getting-started">ESLint</a>.</p>
+
+<p>Il convient de mentionner l'utilisation de ligne de commande — vous pouvez installer ces outils avec les utilitaires de ligne de commande (disponible via ILC — interface de ligne de commande) en utilisant npm (Node Package Manager — vous devrez installer <a href="https://nodejs.org/en/">NodeJS</a> en premier). Par exemple, la ligne de commande suivante installe JSHint :</p>
+
+<pre class="brush: bash">npm install -g jshint
+</pre>
+
+<p>Vous pouvez ensuite indiquer à ces outils les fichiers JavaScript que vous voulez lint, par exemple :<img alt="" src="https://mdn.mozillademos.org/files/14171/js-hint-commandline.png" style="display: block; height: 478px; margin: 0px auto; width: 697px;">Vous pouvez également utiliser ces outils avec un exécuteur de tâche/outil de build comme <a href="http://gulpjs.com/">Gulp</a> ou <a href="https://webpack.github.io/">Webpack</a> pour linter automatiquement votre JavaScript pendant le développement. (voir <a href="https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Automated_testing#Using_a_task_runner_to_automate_testing_tools">Using a task runner to automate testing tools</a> dans un article ultérieur). Voir <a href="http://eslint.org/docs/user-guide/integrations">ESLint integrations</a> pour les options de ESLint ; JSHint est supporté nativement par Grunt, et a également d'autre intégrations possibles, par ex. <a href="https://github.com/webpack/jshint-loader">JSHint loader for Webpack</a>.</p>
+
+<div class="note">
+<p><strong>Note </strong>: ESLint prend un peu plus de temps à l'installation et à la configuration que JSHint, mais il est également plus puissant.</p>
+</div>
+
+<h3 id="Les_outils_de_développement_des_navigateurs">Les outils de développement des navigateurs</h3>
+
+<p>Les outils de développement des navigateurs ont beaucoup de fonctionnalités utiles pour aider à déboguer JavaScript. Pour commencer, la console JavaScript reportera les erreurs dans votre code.</p>
+
+<p>Faîtes une copie locale de notre exemple <a href="https://github.com/mdn/learning-area/blob/master/tools-testing/cross-browser-testing/javascript/broken-ajax.html">broken-ajax.html</a> (voir aussi le <a href="https://github.com/mdn/learning-area/blob/master/tools-testing/cross-browser-testing/javascript/broken-ajax.html">code source</a>). Si vous regardez dans la console, vous verrez le résultat suivant :</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/14165/broken-ajax.png" style="display: block; height: 86px; margin: 0px auto; width: 635px;"></p>
+
+<p>Le message d'erreur affiche "TypeError: jsonObj is null", et le numéro de ligne signifiée et le 37. Si nous regardons le code source, la section de code concernée est celle-ci :</p>
+
+<pre class="brush: js">function populateHeader(jsonObj) {
+ var myH1 = document.createElement('h1');
+<strong> myH1.textContent = jsonObj['squadName'];</strong>
+ header.appendChild(myH1);
+
+ ...</pre>
+
+<p>Le code casse aussitôt qu'on essaye d'accèder à <code>jsonObj</code> (ce qui comme vous pouvez vous y attendre, est supposé être un <a href="https://developer.mozilla.org/fr/docs/Learn/JavaScript/Objects/JSON">objet JSON</a>). C'est supposé aller le chercher dans un fichier externe <code>.json</code> en utilisant l'appel XMLHttpRequest suivant :</p>
+
+<pre class="brush: js">var requestURL = 'https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json';
+var request = new XMLHttpRequest();
+request.open('GET', requestURL);
+request.send();
+
+<strong>var superHeroes = request.response;</strong>
+populateHeader(superHeroes);
+showHeroes(superHeroes);</pre>
+
+<p>Mais cela échoue.</p>
+
+<h4 id="LAPI_Console">L'API Console</h4>
+
+<p>Vous savez peut-être déjà ce qui ne va pas avec ce code, mais analysons-le un peu plus pour vous montrer comment vous pouvez l'examiner. Premièrement, il y a une API <a href="https://developer.mozilla.org/fr/docs/Web/API/Console">Console</a> qui permet au code JavaScript d'interragir avec la console JavaScript du navigateur. Il y a un nombre de fonctionnalités disponibles, mais la principale que vous utiliserez le plus souvent est <code><a href="https://developer.mozilla.org/fr/docs/Web/API/Console/log">console.log()</a></code>, qui affiche un message d'erreur personnalisé dans la console.</p>
+
+<p>Essayer d'insérer la ligne suivante juste avant la ligne 31 (en gras au-dessus) :</p>
+
+<pre class="brush: js">console.log('Response value: ' + superHeroes);</pre>
+
+<p>Rafraîchissez la page dans le navigateur, et vous obtiendrez un résultat dans la console comme celui-ci :</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/14167/console-log.png" style="display: block; height: 99px; margin: 0px auto; width: 638px;"></p>
+
+<p>Le résultat de <code>console.log()</code> montre que l'objet <code>superHeroes</code> ne semble pas contenir quoi que ce soit, bien que vous remarquerez que l'erreur a maintenant changé en "TypeError: heroes is undefined". Cela montre que l'erreur est intermittente, mettant ainsi en évidence qu'il s'agit d'une erreur asynchrone. Corrigeons l'erreur actuelle et avançons — retirer la ligne <code>console.log()</code>, et mettez à jour ce bloc de code :</p>
+
+<pre class="brush: js">var superHeroes = request.response;
+populateHeader(superHeroes);
+showHeroes(superHeroes);</pre>
+
+<p>par le suivant :</p>
+
+<pre class="brush: js">request.onload = function() {
+ var superHeroes = request.response;
+ populateHeader(superHeroes);
+ showHeroes(superHeroes);
+}</pre>
+
+<p>Cela résout le problème asynchrone, en garantissant que les fonctions ne sont pas exécutées et passent l'objet <code>superHeroes</code> jusqu'à ce que la réponse ait fini de charger et soit disponible.</p>
+
+<p>En résumé, à chaque fois que quelque chose ne marche pas et qu'une valeur ne paraît pas être ce qu'elle est censée être à un moment dans votre code, vous pouvez utiliser <code>console.log()</code> pour l'afficher et voir ce qu'il se passe.</p>
+
+<h4 id="Utiliser_le_débogueur_JavaScript">Utiliser le débogueur JavaScript</h4>
+
+<p>Nous avons résolu un problème, mais nous sommes toujours coincés avec le message d'erreur "TypeError: heroes is undefined", reporté à la ligne 51. Examinons-la maintenant, en utilisant une fonctionnalité plus sophistiquée des outils de développement web : le <a href="https://developer.mozilla.org/fr/docs/Outils/D%C3%A9bogueur">débogueur JavaScript</a> comme il est appellé dans Firefox.</p>
+
+<div class="note">
+<p><strong>Note </strong>: Des outils similaires sont disponibles dans d'autres navigateurs ; le <a href="https://developers.google.com/web/tools/chrome-devtools/#sources">Sources tab</a> dans Chrome, le Débogueur dans Safari (voir <a href="https://developer.apple.com/safari/tools/">Safari Web Development Tools</a>), etc.</p>
+</div>
+
+<p>Dans Firefox, le Débogueur se présente comme suit :</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/14169/debugger-tab.png" style="display: block; height: 253px; margin: 0px auto; width: 800px;"></p>
+
+<ul>
+ <li>Sur la gauche, vous pouvez sélectionner le script que vous voulez déboguer (dans ce cas nous n'en n'avons qu'un seul).</li>
+ <li>Le panneau central montre le code du script sélectionné.</li>
+ <li>Le panneau de droite montre des détails utiles concernant l'environnement courant — les <em>Point d'arrêts</em>, la <em>Pile d'exécution</em>, et les <em>Portées</em> actuellement actives.</li>
+</ul>
+
+<p>La fonction principale de ces outils est la possibilité d'ajouter des points d'arrêt au code — ceux sont des points où l'exécution du code s'arrête, et à ce moment vous pouvez examiner l'environnement dans son état courant et voir ce qu'il se passe.</p>
+
+<p>Mettons-nous au travail. Pour commencer, nous savons que l'erreur est renvoyée à la ligne 51. Cliquez sur la ligne numéro 51 dans le panneau central pour y ajouter un point d'arrêt (vous verrez une flèche bleue apparaître au-dessus de celle-ci). Maintenant rafraichissez la page (Cmd/Ctrl + R) — la navigateur arrêtera l'exécution du code à la ligne 51. A ce moment, le panneau de droite va se mettre à jour pour montrer des informations très utiles.</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/14163/breakpoint.png" style="display: block; margin: 0 auto;"></p>
+
+<ul>
+ <li>En-dessous de <em>Points d'arrêt</em>, vous verrez le détail du point d'arrêt que vous avez configuré.</li>
+ <li>En-dessous de <em>Pile d'exécution</em>, vous verrez deux entrées — c'est principalement une liste de série de fonctions qui ont été appellées pour amener la fonction courante à être appellée. En haut, nous avons <code>showHeroes()</code> la fonction dans laquelle nous sommes actuellement, et en-dessous nous avons <code>request.onload</code>, qui stocke la fonction de gestion d'évènement contenant l'appel à <code>showHeroes()</code>.</li>
+ <li>En-dessous de <em>Portées</em>, vous verrez la portée active courante pour la fonction que nous sommes en train d'observer. Nous n'en n'avons que deux — <code>showHeroes</code>, et <code>Window</code> (la portée globale). Chaque portée peut être déployée pour montrer les valeurs des variables à l'intérieur de la portée au moment où l'exécution du code était arrêtée.</li>
+</ul>
+
+<p>Ici, nous pouvons obtenir des informations très utiles.</p>
+
+<ol>
+ <li>Développez la portée <code>showHeroes</code> — vous pouvez voir depuis celle-ci que la variable heroes n'est pas définie, indiquant qu'accèder à la propriété <code>members</code> de <code>jsonObj</code> (première ligne de la fonction) ne marche pas.</li>
+ <li>Vous pouvez également voir que la variable <code>jsonObj</code> stock une chaîne de caractères, pas un objet JSON.</li>
+ <li>En examinant plus loin la pile d'exécutuion, cliquez sur <code>request.onload</code> dans la section <em>Pile d'exécution</em>. La vue va se mettre à jour pour afficher la fonction <code>request.onload</code> dans le panneau central, et sa portée dans la section <em>Portée</em><em>s</em>.</li>
+ <li>Maintenant si vous développez la portée de <code>request.onload</code>, vous verrez que la variable <code>superHeroes</code> est également une chaîne de caractères, pas un objet. C'est la solution — notre appel <code><a href="https://developer.mozilla.org/fr/docs/Web/API/XMLHttpRequest">XMLHttpRequest</a></code> retourne le JSON comme du texte, pas comme du JSON.</li>
+</ol>
+
+<div class="note">
+<p><strong>Note </strong>: Nous aimerions que vous essayez de résoudre ce problème par vous-même. Pour vous donner un indice, vous avez le choix entre <a href="/en-US/docs/Web/API/XMLHttpRequest/responseType">tell the XMLHttpRequest object explicitly to return JSON format</a>, ou <a href="https://developer.mozilla.org/fr/docs/Learn/JavaScript/Objects/JSON#Convertion_entre_objets_et_textes">conversion entre objet et texte</a> après l'arrivée de la réponse. Si vous restez bloqué, consultez notre exemple <a href="https://github.com/mdn/learning-area/blob/master/tools-testing/cross-browser-testing/javascript/fixed-ajax.html">fixed-ajax.html</a>.</p>
+</div>
+
+<div class="note">
+<p><strong>Note </strong>: L'onglet débogueur a tant d'autres fonctionnalités utiles que nous n'aborderons pas ici, par exemple les points d'arrêt conditionnels et les expressions espionnes. Pour bien plus d'informations, voyez la page du <a href="https://developer.mozilla.org/fr/docs/Outils/D%C3%A9bogueur">Débogueur</a>.</p>
+</div>
+
+<h3 id="Les_problèmes_de_performance">Les problèmes de performance</h3>
+
+<p>Dès que vos applis vont devenir plus complexes vous allez commencer à utiliser plus de JavaScript, vous pouvez commencer à rencontrer des problèmes de performances, particulièrement lorsque vous visionnez vos applis sur des appareils plus lents. La performance est un gros sujet, et nous n'avons pas le temps de le couvrir en détail ici. Voici quelques conseils rapides :</p>
+
+<ul>
+ <li>Eviter de charger plus de JavaSacript que nécessaire, réunissez vos scripts dans un seul fichier en utilisant une solution comme <a href="http://browserify.org/">Browserify</a>. En général, réduire le nombre de requêtes HTTP est très bon pour la performance.</li>
+ <li>S'assurer que vos fichiers sont le plus petits en les minifiant avant de les charger sur votre serveur de production. Minifier réduit tout le code en une seule et immense ligne, donnant au fichier une taille beaucoup moins importante. C'est vilain, mais vous n'avez pas besoin de la lire lorsque c'est terminé ! Cette tâche est la mieux réalisée avec un outil de minification comme <a href="https://github.com/mishoo/UglifyJS2">Uglify</a> (il y aussi une version en ligne — voir <a href="https://jscompress.com/">JSCompress.com</a>).</li>
+ <li>Lorsque que vous utilisez des APIs, assurez-vous de désactiver les fonctionnalités de l'API quand elles ne sont pas utilisées ; certains appels d'API peuvent être très coûteux en puissance de traitement. Par exemple, lorsque vous montrez un stream video, assurez-vous que s'est désactivé quand vous ne pouvez pas le voir. Quand vous tracer la localisation d'un appareil en utilisant des appels répétés de Géolocalisation, assurez-vous de le désactiver quand l'utilisateur arrête de l'utiliser.</li>
+ <li>Les animations peuvent être très coûteuses pour la performance. Beaucoup de librairies JavaScript fournissent des possibilités d'animation programmée avec JavaScript, mais c'est beaucoup plus rentable de faire les animations via les fonctionnalités natives des navigateurs comme <a href="https://developer.mozilla.org/fr/docs/Web/CSS/Animations_CSS">les Animations CSS</a> (ou la naissante <a href="/en-US/docs/Web/API/Web_Animations_API">Web Animations API</a>) qu'en JavaScript. Lisez  <a href="https://hacks.mozilla.org/2016/08/animating-like-you-just-dont-care-with-element-animate/">Animating like you just don’t care with Element.animate</a> pour des théories très utiles sur l'animation coûteuse, des conseils sur comment améliorer la performance des animations, et des informations à propos de l'API Web Animations.</li>
+</ul>
+
+<div class="note">
+<p><strong>Note </strong>: Le <a href="https://www.smashingmagazine.com/2012/11/writing-fast-memory-efficient-javascript/" rel="bookmark" title="Read 'Writing Fast, Memory-Efficient JavaScript'"><span class="headline">Writing Fast, Memory-Efficient JavaScript</span></a> de Addy Osmani contient beaucoup de détails et de astuces impeccables pour améliorer les performances en JavaScript.</p>
+</div>
+
+<h2 id="Les_problèmes_JavaScript_en_navigateur_croisé">Les problèmes JavaScript en navigateur croisé</h2>
+
+<p>Dans cette section, nous regarderons certains des problèmes JavaScript les plus courants en navigateur croisé. Nous la décomposerons en :</p>
+
+<ul>
+ <li>Utiliser les fonctionnalités JavaScript principales et modernes</li>
+ <li>Utiliser les fonctionnalités modernes de l'API Web</li>
+ <li>Utiliser des mauvais détecteurs de code de navigateur</li>
+ <li>Les problèmes de performance</li>
+</ul>
+
+<h3 id="Utiliser_des_fonctionnalités_JavaScriptAPI_modernes">Utiliser des fonctionnalités JavaScript/API modernes</h3>
+
+<p>Dans l'<a href="https://developer.mozilla.org/fr/docs/Learn/Tools_and_testing/Cross_browser_testing/HTML_et_CSS#Les_vieux_navigateurs_ne_supportant_pas_les_fonctionnalit%C3%A9s_r%C3%A9centes">article précédent</a> nous décrivions quelques façons dont les erreurs HTML et CSS et les fonctionnalités non reconnues peuvent être gérées grâce à la nature du langage. JavaScript n'est toutefois pas autant permissif que le HTML et le CSS — si le moteur de JavaScript rencontre une faute ou une syntaxe inconnue, le plus souvent il renverra des erreurs.</p>
+
+<p>Il y a plusieurs fonctionnalités modernes du langage JavaScript décrites dans les versions récentes des spécifications (<a href="https://developer.mozilla.org/fr/docs/Web/JavaScript/Nouveaut%C3%A9s_et_historique_de_JavaScript/Support_ECMAScript_2015_par_Mozilla">ECMAScript 6</a> / <a href="https://developer.mozilla.org/fr/docs/Web/JavaScript/Nouveaut%C3%A9s_et_historique_de_JavaScript/Support_ECMAScript_Next_par_Mozilla">ECMAScript Next</a>) qui ne marchent tout simplement pas sur les plus vieux navigateurs. Certaines d'entre elles sont des améliorations syntaxiques (essentiellement une façon plus simple, adéquate d'écrire ce que vous pouvez déjà écrire en utilisant des fonctionnalités existantes), et certaines offrent de nouvelles possibilités intéressantes.</p>
+
+<p>Par exemple :</p>
+
+<ul>
+ <li>Les <a href="https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/Promise">Promises</a> sont une super nouvelle fonctionnalité pour réaliser des opérations asynchrones et s'assurer que c'est opérations sont complètes avant que le code qui s'appuie sur eux ne soit utiliser pour autre chose. A titre d'exemple, l'<a href="https://developer.mozilla.org/fr/docs/Web/API/WindowOrWorkerGlobalScope/fetch">API Fetch</a> (un équivalent moderne de <a href="https://developer.mozilla.org/fr/docs/Web/API/XMLHttpRequest">XMLHTTPRequest</a>) utilise les promises pour rapporter les ressources à travers le réseau et s'assurer que la réponse a été retournée avant qu'elles ne soient utilisées (par exemple afficher une image dans un élément {{htmlelement("img")}} ). Elles ne sont pas du tout supportées par IE mais sont supportées par tous les navigateurs modernes.</li>
+ <li>Les fonctions fléchées apportent une syntaxe courte, plus convenable pour écrire des <a href="/en-US/docs/Learn/JavaScript/Building_blocks/Functions#Anonymous_functions">anonymous functions</a>, ce qui a aussi d'autres avantages (voir <a href="https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Fonctions/Fonctions_fl%C3%A9ch%C3%A9es">Fonctions Fléchées</a>). Comme exemple rapide, voir <a href="https://mdn.github.io/learning-area/tools-testing/cross-browser-testing/javascript/arrow-function.html">arrow-function.html </a>(voir aussi le <a href="https://github.com/mdn/learning-area/blob/master/tools-testing/cross-browser-testing/javascript/arrow-function.html">code source</a>). Les fonctions fléchées sont supportées par tous les navigateurs modernes, excepté par IE et Safari.</li>
+ <li>Déclarer <a href="https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Strict_mode">le mode strict</a> en haut de votre code JavaScript l'amène à être décomposé en une liste de règles plus strictes, impliquant que plus d'avertissements et d'erreurs seront retournés, et certaines choses seront rejetées qui auraient normalement été acceptées. C'est probablement une bonne idée d'utiliser le mode stricte, comme il permet une amélioration et une meilleur efficacité du code, bien qu'il ait un support limité/incomplet selon les navigateurs (voir <a href="https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Strict_mode#Le_mode_strict_dans_les_navigateurs">Le mode strict dans les navigateurs</a>).</li>
+ <li><a href="https://developer.mozilla.org/fr/docs/Web/JavaScript/Tableaux_typ%C3%A9s">Les tableaux typés</a> permettent au code JavaScript d'accéder et de manipuler des données binaires brutes, ce qui est indispensable pour les APIs navigateur par exemple qui commencent à manipuler les streams des données vidéo et audio brutes.</li>
+</ul>
+
+<p>Il y a également beaucoup de nouvelles APIs qui apparaissent dans les navigateurs récents, qui ne fonctionnent pas sur les plus vieux navigateurs, par exemple :</p>
+
+<ul>
+ <li>L'<a href="https://developer.mozilla.org/fr/docs/Web/API/API_IndexedDB">API IndexedDB</a>, L'<a href="https://developer.mozilla.org/fr/docs/Web/API/Web_Storage_API">API Web Storage</a>, et d'autres pour stocker des données d'un site web côté client.</li>
+ <li>L'<a href="https://developer.mozilla.org/fr/docs/Web/API/Web_Workers_API">API Web Workers</a> pour exécuter du JavaScript dans un thread séparé, aidant à améliorer la performance.</li>
+ <li>L'<a href="https://developer.mozilla.org/fr/Apprendre/WebGL">API WebGl</a> pour des graphiques 3D réels.</li>
+ <li>L'<a href="https://developer.mozilla.org/fr/docs/Web/API/Web_Audio_API">API Web Audio</a> pour de la manipulation audio avancée.</li>
+ <li>L'<a href="https://developer.mozilla.org/fr/docs/Web/API/WebRTC_API">API WebRTC</a> pour la connectivité multi-personne, de la vidéo/audio en temps réel (par ex. une vidéo conférence)</li>
+ <li>L'<a href="https://developer.mozilla.org/fr/docs/Web/API/WebVR_API">API WebVR</a> pour concevoir des expériences en réalité virtuelle dans le navigateur (par ex. contrôler une vue 3D avec de l'introduction de données depuis le disque dur VR)</li>
+</ul>
+
+<p>Il y a plusieurs stratégies pour gérer les incompatibilités entre navigateurs concernant le support de fonctionnalité ; explorons les plus courantes.</p>
+
+<div class="note">
+<p><strong>Note </strong>: Ces stratégies n'existent pas dans des endroits distincts — bien sûr, vous pouvez les combiner autant que nécessaire. Par exemple, vous pourriez utiliser une fonction de détection pour déterminer si une fonctionnalité est supportée ; si elle ne l'est pas, vous pouvez ensuite exécuter le code pour charger un polyfill ou une libraire pour gérer le manque de support.</p>
+</div>
+
+<h4 id="Fonctionnalité_de_détection">Fonctionnalité de détection</h4>
+
+<p>L'idée derrière une fonctionnalité de détection est que vous pouvez exécuter un test pour déterminer si une fonctionnalité est supportée dans le navigateur courant, et ensuite exécuter conditionnellement un code pour fournir une expérience acceptable sur chaque navigateur qui supporte et ne supporte pas la fonctionnalité. A titre d'exemple rapide, l'<a href="https://developer.mozilla.org/fr/docs/Using_geolocation">API Geolocalisation</a> (qui présente des données de localisation pour l'appareil sur lequel le navigateur est en train d'être exécuté) a un point d'entrée principal pour son utilisation — une propriété <code>geolocation</code> disponible dans l'objet global <a href="https://developer.mozilla.org/fr/docs/Web/API/Navigator">Navigator</a>.  Par conséquent, vous pouvez détecter si le navigateur supporte la géolocalisation ou non en utilisant quelque chose comme suit :</p>
+
+<pre class="language-js"><span class="keyword token">if</span><span class="punctuation token">(</span><span class="string token">"geolocation"</span> <span class="keyword token">in</span> navigator<span class="punctuation token">)</span> <span class="punctuation token">{</span>
+ navigator<span class="punctuation token">.</span>geolocation<span class="punctuation token">.</span><span class="function token">getCurrentPosition</span><span class="punctuation token">(</span><span class="keyword token">function</span><span class="punctuation token">(</span>position<span class="punctuation token">)</span> <span class="punctuation token">{</span>
+ // show the location on a map, perhaps using the Google Maps API
+ <span class="punctuation token">}</span><span class="punctuation token">)</span><span class="punctuation token">;
+}</span> <span class="keyword token">else</span> <span class="punctuation token">{</span>
+ // Give the user a choice of static maps instead perhaps
+<span class="punctuation token">}</span></pre>
+
+<p>Vous pouvez également écrire un test de ce type pour une fonctionnalité CSS, par exemple en testant l'existence de <em><a href="https://developer.mozilla.org/fr/docs/Web/API/HTMLElement/style">element.style.property</a></em> (par ex. <code>paragraph.style.transform !== undefined</code>). Mais autant pour CSS que JavaScript, il est probablement préférable d'utiliser une librairie de fonction de détection établie plutôt que d'écrire la votre tout le temps. Modernizr est la norme standard pour les tests de fonction de détection.</p>
+
+<p>Enfin, ne confondez pas fonction de détection avec <strong>le détecteur navigateur</strong> (qui détecte quel navigateur en particulier accède au site) — c'est une terrible pratique qui devrait être découragée à tout prix. Voir {{anch("Using bad browser sniffing code")}}, plus tard, pour plus de détails.</p>
+
+<div class="note">
+<p><strong>Note </strong>: Certaines fonctionnalités sont connues pour être indétectables — voir la liste des <a href="https://github.com/Modernizr/Modernizr/wiki/Undetectables">Undetectables</a> de Modernizr.</p>
+</div>
+
+<div class="note">
+<p><strong>Note </strong>: La fonction de détection sera couverte avec beaucoup plus de détails dans son propre article dédié, plus tard dans le module.</p>
+</div>
+
+<h4 id="Les_librairies">Les librairies</h4>
+
+<p>Les librairies JavaScript sont essentiellement une partie externe d'unités de code que vous pouvez attacher à vos pages, afin de vous procurer une quantité de fonctionnalités toutes prêtes qui peuvent être utilisées immédiatement, constituant un gain de temps dans le processus. Beaucoup de librairies ont sûrement été créées parce que leurs développeurs écrivaient une liste de fonctions utiles courantes pour leur faire gagner du temps dans leur futurs projets, et ils décidèrent de les lâcher dans la nature parce que d'autres personnes pourraient aussi les trouver utiles.</p>
+
+<p>Les librairies Javascript ont tendance à se réunir en quelques types principaux (certaines librairies serviront plus d'un de ces types) :</p>
+
+<ul>
+ <li>Les librairies utilitaires : Fournissent une quantité de fonctions pour rendre les tâches sans intérêts plus simples et moins ennuyantes à gérer. <a href="http://jquery.com/">jQuery</a> par exemple fournit son propre système de sélecteurs et de librairies de manipulation de DOM, pour permettre le choix du type de sélecteur CSS, des éléments en JavaScript et une construction du DOM plus simple. Ce n'est plus aussi important aujourd'hui nous avons des fonctionnalités modernes comme les méthodes {{domxref("Document.querySelector()")}}/{{domxref("Document.querySelectorAll()")}}/{{domxref("Node")}} disponibles selon les navigateurs, mais ça peut toujours être utile quand vous avez besoin de supporter de plus vieux navigateurs.</li>
+ <li>Les librairies de confort : Rendent les choses difficiles plus facile à faire. Par exemple, l'<a href="https://developer.mozilla.org/fr/Apprendre/WebGL">API WebGL</a> est vraiment complexe et  se révèle difficile à écrire directement, alors la librairie <a href="https://threejs.org/">Three.js</a> (et d'autres) est construite au-dessus de WebGL et apporte une API plus simple pour créer des objets 3D courants, des aspects, des textures etc. L'<a href="https://developer.mozilla.org/fr/docs/Web/API/Service_Worker_API">API Service Worker </a>est aussi très complexe à utiliser, alors des librairies de code ont commencé à apparaitre pour rendre des cas d'usage des Service Worker plus facile à implémenter (voir le <a href="https://serviceworke.rs/">Service Worker Cookbook</a> pour plusieurs extrait de code utiles).</li>
+ <li>Les librairies d'effets : Ces librairies sont conçues pour vous permettre d'ajouter facilement des effets spéciaux à votre site web. C'était plus utile quand {{glossary("DHTML")}} était à la mode, et implémentait des effets impliquant beaucoup de JavaScript complexe, mais de nos jours les navigateurs ont construit une quantité de fonctionnalités en CSS3 et des APIs pour implémenter les effets plus facilement. Pour une liste de librairies, se référer à <a href="https://www.javascripting.com/animation/">JavaScripting.com/animation</a>.</li>
+ <li>Les librairies d'UI : Fournissent des méthodes pour implémenter des fonctionnalités UI complexes qui serait autrement compliquées à implémenter et à faire fonctionner en navigateur croisé, par exemple <a href="http://jqueryui.com/">jQuery UI</a> et <a href="http://foundation.zurb.com/">Foundation</a>. Elles ont tendance à être utilisées comme les bases de la configuration de sites complets ; c'est souvent difficile de les implémenter uniquement pour une fonctionnalité UI.</li>
+ <li>Les librairies de nomalisation : Vous fournissent une syntaxe simple qui vous permet de compléter facilement une tâche sans avoir à vous soucier des différences entre navigateur. la librairie utilisera les APIs appopriées en arrière-plan donc la fonctionnalité marchera qu'importe le navigateur (en théorie). Par exemple, <a href="https://github.com/localForage/localForage">LocalForage</a> est une librairie pour le stockage de données côté client, qui fournit une syntaxe simple pour stocker et extraire les données. En arrière-plan, elle utilise la meilleure API que la navigateur possède pour stocker les données,  que ça soit <a href="https://developer.mozilla.org/fr/docs/Web/API/API_IndexedDB">IndexedDB</a>, <a href="https://developer.mozilla.org/fr/docs/Web/API/Web_Storage_API">Web Storage</a>, ou encore WebSQL (qui est maintenant désapprouvée, mais qui est encore supportée dans certaines vieilles versions de Safari/IE). Comme autre exemple, JQuery.</li>
+</ul>
+
+<p>Lorsque vous choissisez une librairie pour l'utiliser, assurez-vous qu'elle fonctionne sur l'ensemble des navigateurs que vous voulez supporter, et tester vos implémentations minutieusement. Assurez-vous également que la librairie est répandue et bien supportée, et qu'elle ne va pas devenir obsolète la semaine prochaine. Parler à d'autres développeurs pour savoir ce qu'ils peuvent vous recommander, regarder l'activité et combien de contributeurs la librairie a sur Github (ou qu'importe où elle est stockée), etc.</p>
+
+<div class="note">
+<p><strong>Note </strong>: <a href="https://www.javascripting.com/">JavaScripting.com</a> vous donne une idée d'à peu près combien de librairies JavaScript sont disponibles, et peut être utile pour trouver une librairie dans un but précis.</p>
+</div>
+
+<p>L'utilisation de librairie à un niveau basique consiste à télécharger les fichiers de la librairie (JavaScript, peut-être un peu de CSS ou d'autres dépendances) et à les attacher à votre page (par ex. via un élément {{htmlelement("script")}}, bien qu'il y ait normalement plein d'autres options d'utilisation pour de telles librairies, comme les installer comme des composants <a href="https://bower.io/">Bower</a>, ou les inclure comme des dépendances avec le module de paquets <a href="https://webpack.github.io/">Webpack</a>. Vous devrez lire les pages d'installation individuelles des librairies pour plus d'information.</p>
+
+<div class="note">
+<p><strong>Note </strong>: Vous allez aussi tomber sur des frameworks JavaScript pendant votre voyage dans le Web, comme <a href="http://emberjs.com/">Ember</a> et <a href="https://angularjs.org/">Angular</a>. Alors que les librairies sont souvent utilisées pour résoudre des problèmes individuels et ajoutées dans des sites existants, les frameworks ont tendances à être utilisés plus pour des solutions complètes pour développer des applications web complexes.</p>
+</div>
+
+<h4 id="Les_Polyfills">Les Polyfills</h4>
+
+<p>Les polyfills sont aussi des sortes de fichiers JavaScript externes que vous pouvez ajouter à votre projet, mais ils sont différents des librairies — là où les librairies améliorent les fonctionnalités existantes et rendent les choses plus simples, les polyfills apportent des fonctionnalités qui n'existent pas du tout. Les polyfills utilisent JavaScript ou d'autres technologies pour créer entièrement du support pour des fonctionnalités qu'un navigateur ne supporte pas nativement. Par exemple, vous pouvez utiliser un polyfill comme <a href="https://github.com/stefanpenner/es6-promise">es6-promise</a> pour faire fonctionner les promises sur des navigateurs où elles ne fonctionneraient pas nativement.</p>
+
+<p>La liste des modernizr <a href="https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-Browser-Polyfills">HTML5 Cross Browser Polyfills</a> est utile pour trouver des polyfills pour différents objectifs. Une fois encore, renseignez-vous sur eux avant de les utiliser — assurez-vous qu'ils fonctionnent et qu'ils sont maintenus.</p>
+
+<p>Observons cet exercice — dans cet exemple nous allons utiliser un polyfill Fetch pour fournir du support pour une API Fetch dans de vieux navigateurs ; nous avons toutefois également besoin d'utiliser le polyfill es6-promise, comme Fetch utilise largement les promises, et les navigateurs qui ne les supportent pas seront toujours bloqués.</p>
+
+<ol>
+ <li class="gh-header-title instapaper_title">Pour commencer, faîtes une copie locale de notre exemple <a href="https://github.com/mdn/learning-area/blob/master/tools-testing/cross-browser-testing/javascript/fetch-polyfill.html">fetch-polyfill.html</a> et de <a href="https://github.com/mdn/learning-area/blob/master/tools-testing/cross-browser-testing/javascript/flowers.jpg">notre belle image de fleurs</a> dans un nouveau répertoire. Nous allons écrire du code pour récupérer l'image de fleurs et l'afficher sur la page.</li>
+ <li class="gh-header-title instapaper_title">Ensuite, sauvegarder les copies de <a href="https://raw.githubusercontent.com/github/fetch/master/fetch.js">Fetch polyfill</a> et de <a href="https://raw.githubusercontent.com/stefanpenner/es6-promise/master/dist/es6-promise.js">es6-promises polyfill</a> dans le même répertoire que le HTML.</li>
+ <li class="gh-header-title instapaper_title">Appliquer les scripts de polyfill à la page en utilisant le code suivant — placez-les au-dessus de l'élément {{htmlelement("script")}} existant ainsi ils seront déjà disponibles sur la page quand on essaiera d'utiliser Fetch :
+ <pre class="brush: js">&lt;script src="es6-promise.js"&gt;&lt;/script&gt;
+&lt;script src="fetch.js"&gt;&lt;/script&gt;</pre>
+ </li>
+ <li>Dans le {{htmlelement("script")}} original, ajoutez le code suivant :</li>
+ <li>
+ <pre class="brush: js">var myImage = document.querySelector('.my-image');
+
+fetch('flowers.jpg').then(function(response) {
+ response.blob().then(function(myBlob) {
+ var objectURL = URL.createObjectURL(myBlob);
+ myImage.src = objectURL;
+ });
+});</pre>
+ </li>
+ <li>Maintenant si vous le chargez dans un navigateur qui ne supporte pas Fetch (Safari et IE sont des candidats de choix), vous devriez quand même voir l'image de la fleur apparaitre — cool !<br>
+ <img alt="" src="https://mdn.mozillademos.org/files/14183/fetch-image.jpg" style="border-style: solid; border-width: 1px; display: block; margin: 0px auto;"></li>
+</ol>
+
+<div class="note">
+<p><strong>Note </strong>: Vous pouvez consulter notre version terminée sur <a href="http://mdn.github.io/learning-area/tools-testing/cross-browser-testing/javascript/fetch-polyfill-finished.html">fetch-polyfill-finished.html</a> (voir aussi le <a href="https://github.com/mdn/learning-area/blob/master/tools-testing/cross-browser-testing/javascript/fetch-polyfill-finished.html">code source</a>).</p>
+</div>
+
+<div class="note">
+<p class="gh-header-title instapaper_title"><strong>Note</strong> : Une fois encore, il y a plusieurs manières différentes d'utiliser les différents polyfills que vous allez rencontrer — consulter chaque documentation individuelle d'un polyfill.</p>
+</div>
+
+<p>Une chose à laquelle vous devez penser est "pourquoi devrions-nous toujours charger le code polyfill, même si nous n'en avons pas besoin ?" C'est une bonne remarque — plus vos sites vont devenir complexes et plus vous aller commencer à utiliser de librairies, de polyfills, etc., vous pouvez commencer à charger beaucoup de code supplémentaire, qui peut commencer à affecter la performance, spécialement sur des appareils peu puissants. Il est donc normal de ne charger les fichiers que quand ils sont nécessaires.</p>
+
+<p>Faire cela nécessite un peu de code supplémentaire dans votre JavaScript. Vous avez besoin d'un test de détection de caractéristiques qui détecte si le navigateur supporte la fonctionnalité que vous essayez d'utiliser :</p>
+
+<pre class="brush: js"><code class="language-js"><span class="hljs-keyword">if</span> (browserSupportsAllFeatures()) {
+ main();
+} <span class="hljs-keyword">else</span> {
+ loadScript(<span class="hljs-string">'polyfills.js'</span>, main);
+}
+
+<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">main</span>(err) </span>{
+ <span class="hljs-comment">// actual app code goes in here</span>
+}</code></pre>
+
+<p>En premier temps on exécute une condition qui vérifie si la fonction <code>browserSupportAllFeatures()</code> retourne true. Si oui, on exécute la fonction <code>main()</code>, qui contiendra tout le code de notre app. <code>browserSupportAllFeatures()</code> ressemble à ça :</p>
+
+<pre class="brush: js"><code class="language-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">browserSupportsAllFeatures</span>() </span>{
+ <span class="hljs-keyword">return</span> <span class="hljs-built_in">window</span>.Promise &amp;&amp; <span class="hljs-built_in">window</span>.fetch;
+}</code></pre>
+
+<p>Ici on vérifie si l'objet <code><a href="https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/Promise">Promise</a></code> et la fonction <code><a href="https://developer.mozilla.org/fr/docs/Web/API/WindowOrWorkerGlobalScope/fetch">fetch()</a></code> existent dans le navigateur. Si les deux existent, la fonction retourne true. Si la fonction retourne <code>false</code>, alors on exécute le code à l'intérieur de la deuxième partie de la condition — elle exécute une fonction appelée loadScript(), qui charge les polyfills dans la page, puis exécute <code>main()</code> après que le chargement soit terminé. <code>loadScript()</code> ressemble à ça :</p>
+
+<pre class="brush: js"><code class="language-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">loadScript</span>(<span class="hljs-params">src, done</span>) </span>{
+ <span class="hljs-keyword">var</span> js = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'script'</span>);
+ js.src = src;
+ js.onload = <span class="hljs-function"><span class="hljs-keyword">function</span>() </span>{
+ done();
+ };
+ js.onerror = <span class="hljs-function"><span class="hljs-keyword">function</span>() </span>{
+ done(<span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">'Failed to load script '</span> + src));
+ };
+ <span class="hljs-built_in">document</span>.head.appendChild(js);
+}</code>
+</pre>
+
+<p>Cette fonction créé un nouvel élément <code>&lt;script&gt;</code>, puis applique son attribut <code>src</code> au chemin que nous avons spécifié en premier argument (<code>'polyfills.js'</code> dont nous parlions dans le code au-dessus). Une fois qu'il est chargé, nous exécutons la fonction que nous avons spécifié en deuxième argument (<code>main()</code>). Si une erreur se produit pendant le chargement du script, on continue d'appeler la fonction, mais avec une erreur personnalisée que nous pouvons retrouver pour faciliter le débug d'un problème s'il arrive.</p>
+
+<p>Notez que ce polyfills.js correspond aux deux polyfills que nous utilisons réunis dans un fichier. Nous l'avons fait manuellement, mais il y a des solutions intelligentes qui généreront automatiquement des paquets pour vous — voir <a href="http://browserify.org/">Browserify</a> (pour un tutoriel de départ voir <a href="https://www.sitepoint.com/getting-started-browserify/">Getting started with Browserify</a>). C'est une bonne idée de paqueter les fichiers JS en un seul comme ça — cela réduit le nombre de requêtes HTTP ce qui améliore la performance de votre site.</p>
+
+<p>Vous pouvez voir le code en direct sur <a href="http://mdn.github.io/learning-area/tools-testing/cross-browser-testing/javascript/fetch-polyfill-only-when-needed.html">fetch-polyfill-only-when-needed.html</a> (voir aussi <a href="https://github.com/mdn/learning-area/blob/master/tools-testing/cross-browser-testing/javascript/fetch-polyfill-only-when-needed.html">le code source</a>). Nous aimerions être clairs sur le fait qu'on ne peut s'attribuer ce code — il a été écrit à la base par Philip Walton. Aller voir son article <a href="https://philipwalton.com/articles/loading-polyfills-only-when-needed/">Loading Polyfills Only When Needed</a> pour le code original, et beaucoup d'explications utiles autour de ce large sujet.</p>
+
+<div class="note">
+<p><strong>Note </strong>: Il y a certaines options externes à prendre en considération, par exemple <a href="https://polyfill.io/v2/docs/">Polyfill.io</a> — c'est une librairie méta-polyfill qui va regarder toutes les capacités de chaque navigateur et appliquer les polyfills nécessaires, selon quelles APIs et fonctionnalités JS vous utilisez dans votre code.</p>
+</div>
+
+<h4 id="Le_transpiling_Javascript">Le transpiling Javascript</h4>
+
+<p>Une autre option qui et devenue populaire pour les gens qui veulent utiliser des fonctionnalités Javascript modernes dès maintenant consiste à convertir le code qui utilise les fonctionnalités ECMAScript 6/ECMAScript 2015 en une version qui fonctionnera sur les vieux navigateurs.</p>
+
+<div class="note">
+<p><strong>Note </strong>: Cela s'appelle le "transpiling" — vous n'êtes pas en train de compiler du code à un niveau inférieur pour qu'il soit exécuté sur un ordinateur (comme vous l'auriez fait avec du code C) ; en fait, vous êtes en train de le transformer dans une syntaxe qui existe à un niveau similaire d'abstraction pour qu'il puisse être utilisé de la même manière, mais avec des conditions légèrement différentes (dans ce cas, transformer un type de JavaScript dans un autre).</p>
+</div>
+
+<p>Pour l'exemple, nous parlions des fonctions fléchées (voir <a href="http://mdn.github.io/learning-area/tools-testing/cross-browser-testing/javascript/arrow-function.html">arrow-function.html</a> en direct, et voir le <a href="https://github.com/mdn/learning-area/blob/master/tools-testing/cross-browser-testing/javascript/arrow-function.html">code source</a>) plus tôt dans l'article, qui ne marchent que sur les tout nouveaux navigateurs :</p>
+
+<pre class="brush: js">() =&gt; { ... }</pre>
+
+<p>Nous pouvons le transpiler en une traditionnelle et démodée fonction anonyme, donc il fonctionnera aussi sur les vieux navigateurs :</p>
+
+<pre class="brush: js">function() { ... }</pre>
+
+<p>L'outil recommandé pour transpiler du JavaScript est généralement <a href="https://babeljs.io/">Babel</a>. Il fournit la capacité de transpilation pour des fonctionnalités de langages qui sont appropriées à la transpilation. Pour les fonctionnalités qui peuvent juste être facilement transpilées en un équivalent plus ancien, Babel offre aussi des polyfills pour apporter du support.</p>
+
+<p>La meilleure façon d'essayer Babel et d'utiliser la <a href="https://babeljs.io/repl/">version en ligne</a>, qui vous permet d'entrer votre code source sur la gauche, et une version transpilée sort sur la droite.</p>
+
+<div class="note">
+<p><strong>Note </strong>: Il y a plein de façon d'utiliser Babel (exécuteurs de tâche, outil d'automatisation, etc.), comme vous le verrez sur la <a href="https://babeljs.io/docs/setup/">page d'installation</a>.</p>
+</div>
+
+<h3 id="Utiliser_une_mauvaise_détection_de_code_de_navigateur">Utiliser une mauvaise détection de code de navigateur</h3>
+
+<p>Tous les navigateurs ont un <strong>user-agent</strong>, qui identifie de quel navigateur il s'agit (version, nom, OS, etc.) Durant cette époque sombre où la plupart des gens utilisaient Netscape ou Internet Explorer, les développeurs avaient l'habitude d'utiliser les dénommés <strong>détecteur de code de navigateur</strong> pour détecter quel navigateur l'utilisateur utilisait et leur fournir le code approprié pour qu'il fonctionne sur ce navigateur.</p>
+
+<p>Le code utilisé ressemble à quelque chose comme ça (bien que ça soit un exemple simplifié) :</p>
+
+<pre class="brush: js">var ua = navigator.userAgent;
+
+if(ua.indexOf('Firefox') !== -1) {
+ // run Firefox-specific code
+} else if(ua.indexOf('Chrome') !== -1) {
+ // run Chrome-specific code
+}</pre>
+
+<p>L'idée était assez bonne — détecter quel navigateur affiche le site, et exécuter le code approprié pour s'assurer que le navigateur sera à même de bien utiliser votre site.</p>
+
+<div class="note">
+<p><strong>Note </strong>: Essayez maintenant d'ouvrir votre console JavaScript et d'exécuter navigator.userAgent pour voir ce qui est retourné.</p>
+</div>
+
+<p>Cependant, le temps passant, les développeurs ont commencé à voir des graves problèmes avec cette approche. Pour commencer, le code était source d'erreur. Et si une nouvelle fonctionnalité ne marche pas sur disons, Firefox 10 et inférieur, on implémente du code pour détecter cela, puis Firefox 11 arrive — est-ce qu'il supportera cette fonctionnalité ? Firefox 11 ne sera sûrement pas supporté parce qu'il n'est pas Firefox 10. Vous aurez à changer tout votre code de détection régulièrement.</p>
+
+<p>Beaucoup de développeurs on implémenté de mauvais détecteur de code de navigateur et ne l'ont pas maintenu, et les navigateurs ont commencé à être bloqués en allant sur des sites web contenant des fonctionnalités qu'ils avaient déjà implémenté. C'est devenu une pratique commune que les navigateurs commencent à mentir à propos de quel navigateur ils étaient dans leur chaîne d'user-agent (ou déclarer qu'ils étaient tous les navigateurs), pour passer outre les détecteurs de code. Les navigateurs ont également implémenté des moyens pour permettre aux utilisateurs de changer quels chaîne d'user-agent le navigateur doit retourné lorsqu'il est interrogé par du JavaScript. Tout cela fait du détecteur de code bien plus qu'une source d'erreur, et d'inutilité.</p>
+
+<div class="note">
+<p><strong>Note </strong>: Vous devriez lire <a href="http://webaim.org/blog/user-agent-string-history/">History of the browser user-agent string</a> de Aaron Andersen pour une présentation utile et amusante de cette situation.</p>
+</div>
+
+<p>La leçon à retenir ici est — ne JAMAIS utiliser de détecteur de code. Le seul cas d'usage pour le détecteur de code de nos jours c'est si vous implémentez un fix pour un bug pour une version très particulière d'un navigateur en particulier. Même dans ce cas, la plupart des bugs sont fixés rapidement dans le cycle rapide des sorties des navigateurs. Cela n'arrive pas très souvent. {{anch("Feature detection")}} est presque toujours une meilleure option — si vous détectez si une fonctionnalité est supportée, vous n'aurez pas besoin de changer votre code quand de nouvelles versions de navigateur sortiront, et les tests sont bien plus fiables.</p>
+
+<p>Si vous rejoignez un projet existant où il y a déjà de la détection de navigateur, regardez si elle peut être remplacée avec quelque chose de plus pratique. La détection de navigateur est à l'origine de toutes sortes de bugs curieux, comme {{bug(1308462)}}.</p>
+
+<h3 id="Gérer_les_préfixes_JavaScript">Gérer les préfixes JavaScript</h3>
+
+<p>Dans l'article précédent, nous parlions quelque peu de la <a href="https://developer.mozilla.org/fr/docs/Learn/Tools_and_testing/Cross_browser_testing/HTML_et_CSS#Gestion_des_pr%C3%A9fixes_CSS">gestion des préfixes CSS</a>. Alors, les nouvelles implémentations JavaScript utilisent parfois aussi des préfixes, bien que JavaScript utilise le camel case plutôt que l'hyphenation comme CSS. Par exemple, si un préfixe est utilisé sur un objet d'une toute belle API appelée <code>Ojbect</code> :</p>
+
+<ul>
+ <li>Mozilla utilisera <code>mozObject</code></li>
+ <li>Chrome/Opera/Safariutiliseront <code>webkitObject</code></li>
+ <li>Microsoft utilisera <code>msObject</code></li>
+</ul>
+
+<p>Voici un exemple, issu de notre <a href="http://mdn.github.io/violent-theremin/">demo violent-theremin</a> (voir le <a href="https://github.com/mdn/violent-theremin">code source</a>), qui utilise une combinaison de l'<a href="https://developer.mozilla.org/fr/docs/Web/HTML/Canvas">API Canvas</a> et de l'<a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API">API Web Audio</a> pour créer un outil de dessin marrant (et bruyant) :</p>
+
+<pre class="brush: js">var AudioContext = window.AudioContext || window.webkitAudioContext;
+var audioCtx = new AudioContext();</pre>
+
+<p>Dans le cas de l'API Web Audio, les principaux points d'entrée pour utiliser l'API étaient supportés dans Chrome/Opera via les versions préfixées <code>webkit</code> (ils supportent dorénavant les versions non préfixées). Le moyen le plus simple de contourner cette situation est de créer une nouvelle version des objets qui sont  préfixés dans certains navigateurs, et de la rendre égale à la version non préfixée, OU à la version préfixée (OU n'importe quelles versions préfixées qui méritent d'être éxaminées) — quelle que soit celle supportée par le navigateur affichant le site elle sera utilisée.</p>
+
+<p>Ensuite utilisez cet objet pour manipuler l'API, plutôt que l'original. Dans ce cas nous créons un constructeur <a href="https://developer.mozilla.org/fr/docs/Web/API/AudioContext">AudioContext</a> modifié, puis nous créons une nouvelle instance de contexte audio à utiliser pour notre codage Web Audio.</p>
+
+<p>Ce modèle peut être appliqué pour toutes les fonctionnalités JavaScript préfixées. Les librairies/polyfills JavaScript utilise également ce type de code, pour faire abstraction au maximum des différences entre navigateurs pour le développeur.</p>
+
+<p>Une fois encore, les fonctions préfixées n'ont jamais été supposées être utilisées sur des sites web en production — elles sont sujettes au changement ou au retrait sans avertissement, et causent de problèmes en navigateur croisé. Si vous persistez à utiliser des fonctions préfixées, assurez-vous d'utiliser les bonnes. Vous pouvez voir quels navigateurs nécessitent des préfixes pour les différents fonctionnalités JavaScript/API sur les pages de références MDN, et des site comme <a href="http://caniuse.com/">caniuse.com</a>. Si vous n'êtes pas sûr, vous pouvez aussi vérifier en faisant quelques test directement dans des navigateurs.</p>
+
+<p>Par exemple, essayez d'aller dans la console de développeur de votre navigateur et commencez à taper</p>
+
+<pre class="brush: js">window.AudioContext</pre>
+
+<p>Si cette fonctionnalité est supportée par votre navigateur, elle s'autocomplètera.</p>
+
+<h2 id="Trouver_de_laide">Trouver de l'aide</h2>
+
+<p>Il y'a bien d'autres problèmes que vous allez rencontrer avec le JavaScript ; la chose la plus importante à vraiment savoir est comment trouver des réponses en ligne. Consultez <a href="https://developer.mozilla.org/fr/docs/Learn/Tools_and_testing/Cross_browser_testing/HTML_et_CSS#Trouver_de_l'aide">la section Trouver de l'aide</a> de l'article sur le HTML et CSS pour nos meilleurs conseils.</p>
+
+<h2 id="Résumé">Résumé</h2>
+
+<p>Voilà c'est le JavaScript. Facile hein ? Peut-être pas aussi facile, mais cet article devrait au moins vous donner un départ, et quelques idées sur comment attaquer les problèmes liés au JavaScript que vous allez rencontrer.</p>
+
+<p>{{PreviousMenuNext("Learn/Tools_and_testing/Cross_browser_testing/HTML_and_CSS","Learn/Tools_and_testing/Cross_browser_testing/Accessibility", "Learn/Tools_and_testing/Cross_browser_testing")}}</p>
+
+
+
+<h2 id="Dans_ce_module">Dans ce module</h2>
+
+<ul>
+ <li><a href="https://developer.mozilla.org/fr/docs/Learn/Tools_and_testing/Cross_browser_testing/Introduction">Introduction au test en navigateur croisé</a></li>
+ <li><a href="https://developer.mozilla.org/fr/docs/Learn/Tools_and_testing/Cross_browser_testing/Testing_strategies">Stratégies pour mener à bien vos tests</a></li>
+ <li><a href="https://developer.mozilla.org/fr/docs/Learn/Tools_and_testing/Cross_browser_testing/HTML_et_CSS">Gérer les problèmes courants en HTML et CSS</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/JavaScript">Handling common JavaScript problems</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Accessibility">Handling common accessibility problems</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Feature_detection">Implementing feature detection</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Automated_testing">Introduction to automated testing</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Your_own_automation_environment">Setting up your own test automation environment</a></li>
+</ul>
diff --git a/files/fr/learn/tools_and_testing/cross_browser_testing/testing_strategies/index.html b/files/fr/learn/tools_and_testing/cross_browser_testing/testing_strategies/index.html
new file mode 100644
index 0000000000..ea67dd363c
--- /dev/null
+++ b/files/fr/learn/tools_and_testing/cross_browser_testing/testing_strategies/index.html
@@ -0,0 +1,362 @@
+---
+title: Stratégies pour mener à bien vos tests
+slug: Learn/Tools_and_testing/Cross_browser_testing/Testing_strategies
+translation_of: Learn/Tools_and_testing/Cross_browser_testing/Testing_strategies
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/Tools_and_testing/Cross_browser_testing/Introduction","Learn/Tools_and_testing/Cross_browser_testing/HTML_and_CSS", "Learn/Tools_and_testing/Cross_browser_testing")}}</div>
+
+<p class="summary">Cet article commence en donnant un aperçu sur le sujet des tests sur navigateurs (croisé), répondant aux questions telles que "qu'est-ce que le test en navigateur croisé ?", "Quels sont les problèmes les plus communs que vous allez rencontrer ?", et "quelles sont les principales approches pour tester, identifier, et fixer les problèmes ?"</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Prérequis :</th>
+ <td>Connaissances avec le noyau des langages <a href="/en-US/docs/Learn/HTML">HTML</a>, <a href="/en-US/docs/Learn/CSS">CSS</a>, et <a href="/en-US/docs/Learn/JavaScript">JavaScript</a> ; une idée du haut niveau<a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Introduction"> des principes du test en navigateur croisé</a>.</td>
+ </tr>
+ <tr>
+ <th scope="row">Objectif :</th>
+ <td>
+ <p>Obtenir une compréhension des concepts de haut-niveau impliqués dans le test en navigateur croisé.</p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Testez-les_tous">Testez-les tous ?</h2>
+
+<p>Lorsque vous faîtes du test en navigateur croisé, vous devez établir une liste de navigateurs que vous avez besoin de tester pour démarrer. Il n'y a aucun moyen que vous puissiez tester toutes les combinaisons de navigateurs et d'appareils que vos utilisateurs peuvent utiliser pour voir votre site — il y en a juste beaucoup trop, et de nouveaux apparaissent à longueur de temps.</p>
+
+<p>Vous devriez plutôt essayer de vous assurer que votre site fonctionne sur les appareils et les navigateurs cibles les plus importants, et coder de manière défensive afin de donner à votre site le support le plus large qu'il puisse atteindre.</p>
+
+<p>Par coder de manière défensive, nous voulons dire essayer de construire une solution de repli intelligente comme ça si une fonctionnalité ou un style ne marche pas sur un navigateur, le site sera capable de rétrograder à quelque chose de moins palpitant qui continuera de fournir une expérience utilisateur acceptable — le noyau de l'information est toujours accessible, par exemple, même si l'aspect n'est pas aussi beau.</p>
+
+<p>L'objectif est de mettre en place une liste des navigateurs/appareils sur laquelle vous pouvez vous appuyer lors de vos tests. Vous pouvez la faire aussi simple ou compliquée que vous le souhaitez — par exemple, une approche répandue est d'établir différents grades de niveau de support, quelque chose comme :</p>
+
+<ol>
+ <li>Grade A : Navigateurs communs/modernes — Connu pour leur capacité. Tester complètement et fournir un support complet.</li>
+ <li>Grade B : Navigateurs plus vieux/ayant moins de capacité — connu pour leur incapacité. Tester, et fournir une expérience plus basique qui donne un accès total au principal de l'information et des services.</li>
+ <li>Grade C : Navigateurs rares/inconnus — ne pas tester, mais supposer qu'ils sont capables. Fournir le site complet, qui devrait marcher, au moins avec les solutions de replis disponibles grâce à notre code défensif.</li>
+</ol>
+
+<p>Tout au long des sections à venir, nous allons mettre en place une liste de support dans ce format.</p>
+
+<div class="note">
+<p><strong>Note </strong>: Yahoo est le premier à avoir rendu cette approche répandue, avec leur approche de <a href="https://github.com/yui/yui3/wiki/Graded-Browser-Support">Support de navigateur classé</a>.</p>
+</div>
+
+<h3 id="Déductions_logiques">Déductions logiques</h3>
+
+<p>Vous pouvez les appeler "hypothèses" ou "intuitions". Ce n'est pas une approche précise, scientifique, mais en tant que personne qui a une expérience de l'industrie web vous aurez une particulièrement bonne idée du minimum de navigateurs que vous devriez tester. Cela peut former une bonne base pour votre liste de support.</p>
+
+<p>Par exemple, si vous habitez en Europe de l'Ouest ou en Amérique du Nord, vous devez savoir que la plupart des gens utilisent des ordinateurs de bureau/portable Windows et Mac, et que les navigateurs principaux sont Chrome, Firefox, Safari, IE, et Edge. Vous n'aurez sûrement besoin que de tester uniquement les dernières versions des trois premiers, étant donné que ces navigateurs reçoivent des mises à jour régulières. Pour Edge et IE vous n'aurez que besoin de tester les deux dernières versions ; ils doivent tous aller dans le niveau de grade A.</p>
+
+<div class="note">
+<p><strong>Note </strong>: Vous ne pouvez avoir qu'une seule version d'IE ou d'Edge installée sur une machine à la fois, vous aurez donc probablement besoin d'utiliser une machine virtuelle, ou une autre stratégie pour faire les tests nécessaires. Voir {{anch("Virtual machines")}} plus tard.</p>
+</div>
+
+<p>Beaucoup de personnes utilisent iOS et Android, vous aurez donc aussi besoin de tester les dernières versions d'iOS Safari, les deux dernières versions de l'ancien Android stock browser, et Chrome et Firefox pour iOS et Android. Idéalement, vous devriez tester sur un téléphone et une tablette de chaque système d'exploitation, afin de vous assurer que les designs responsives fonctionnent bien.</p>
+
+<p>Vous savez aussi peut-être qu'un certain nombre de personnes continue d'utiliser IE 9. C'est vieux et peu compétent, donc mettons-le dans le niveau de grade B.</p>
+
+<p>Ce qui nous donne pour l'instant la liste de support suivante :</p>
+
+<ol>
+ <li>Grade A : Chrome et Firefox pour Windows/Mac, Safari pour Mac, Edge et IE pour Windows (les deux dernières versions de chacun), iOS Safari pour iPhone/iPad, Android stock browser (les deux dernières versions) sur téléphone/tablette, Chrome et Firefox pour Android (les deux dernières versions) sur téléphone/tablette.</li>
+ <li>Grade B : IE 9 pour Windows</li>
+ <li>Grade C : n/a</li>
+</ol>
+
+<p>Si vous vivez autre part, ou travaillez sur un site qui va être livré autre part (par ex. dans un pays ou un endroit en particulier), alors vous aurez sûrement des navigateurs communs différents à tester.</p>
+
+<div class="note">
+<p><strong>Note </strong>: "Le PDG de mon entreprise utilise un Blackberry, nous devons donc nous assurer que cela apparaîtra parfaitement sur ce support" peut aussi être un argument persuasif.</p>
+</div>
+
+<h3 id="Les_statistiques_de_support_navigateur">Les statistiques de support navigateur</h3>
+
+<p>Une mesure utile à laquelle vous pouvez faire appel pour déduire vos choix de test sur navigateur, c'est les statistiques de support navigateur. Il y a plusieurs sites qui fournissent de telles informations, par exemple :</p>
+
+<ul>
+ <li><a href="https://www.netmarketshare.com/browser-market-share.aspx?qprid=2&amp;qpcustomd=0">Netmarketshare</a></li>
+ <li><a href="http://gs.statcounter.com/">Statcounter</a></li>
+</ul>
+
+<p>Ils sont tous les deux très orientés sur l'Amérique du Nord, et ne sont pas particulièrement précis, mais ils peuvent vous donner une idée des tendances générales.</p>
+
+<p>Par exemple, allons sur <a href="https://www.netmarketshare.com/browser-market-share.aspx?qprid=2&amp;qpcustomd=0">Netmarketshare</a>. Vous pouvez voir qu'Opera est listé comme ayant une petit mais visible chiffre d'usage, donc nous devrions l'ajouter à notre liste de support en grade C.</p>
+
+<p>IE8 est classé comme étant significatif également, mais il est plus vieux et plus très efficace. Opera Mini est aussi remarquable, mais il n'est pas très compétent en termes d'exécution de Javascript complexe au démarrage, etc. (voir <a href="https://dev.opera.com/articles/opera-mini-and-javascript/">Opera Mini et JavaScript</a> pour plus de détails). Nous devrions aussi les ajouter dans le niveau B.</p>
+
+<h3 id="Utiliser_l'analyse_des_données">Utiliser l'analyse des données</h3>
+
+<p>Une source de données plus précise, si vous pouvez l'obtenir, vient d'une appli d'analyse comme <a href="https://www.google.com/analytics/">Google Analytics</a>. C'est une application qui vous donnera des stats sur exactement quels navigateurs les gens utilisent pour naviguer sur votre site. Bien entendu, cela implique que vous avez déjà un site sur lequel l'utiliser, donc ça n'est pas super pour de tout nouveaux sites.</p>
+
+<p>Mais une analyse historique peut être utile pour trouver des statistiques de support afin d'exercer une influence sur une nouvelle version du site d'une entreprise, ou une nouvelle fonctionnalité que vous être en train d'ajouter sur un site existant. Si elles vous sont accessibles, elles sont bien plus précises que les statistiques globales des navigateurs comme celles mentionnées plus haut.</p>
+
+<h4 id="Configurer_Google_analytics">Configurer Google analytics</h4>
+
+<ol>
+ <li>En premier lieu, vous avez besoin d'un compte Google. Utilisez ce compte afin de vous inscrire sur <a href="https://www.google.com/analytics/">Google Analytics</a>.</li>
+ <li>Choisissez l'option <a href="https://analytics.google.com/analytics/web/">Google Analytics</a> (web), et cliquez sur le bouton <em>S'inscrire</em>.</li>
+ <li>Entrez les détails sur votre site/appli dans la page d'inscription. C'est très intuitif à configurer ; le champ le plus important où il ne faut pas se tromper est l'URL du site web. Cela doit être l'URL racine de votre site/appli.</li>
+ <li>Une fois que vous avez terminé de tout remplir, appuyer sur le bouton <em>Get Tracking ID</em>, ensuite acceptez les modalités de services qui apparaissent.</li>
+ <li>La prochaine page vous fournit quelques extraits de code et d'autres instructions. Pour un site web basique, ce que vous avez besoin de faire, c'est de copier le bloc de code <em>Website tracking </em>et de le coller sur toutes les différentes pages que vous voulez suivre en utilisant Google Analytics sur votre site. Vous pouvez le placer en-dessous de la balise fermante <code>&lt;/body&gt;</code>, ou n'importe où d'approprié qui le garderait de se mélanger avec le code de votre application.</li>
+ <li>Téléchargez vos modifications sur le serveur de développement, ou autre part où vous avez besoin de votre code.</li>
+</ol>
+
+<p>C'est bon ! Votre site devrait maintenant être prêt à commencer à reporter l'analyse de données.</p>
+
+<h4 id="Etudier_l'analyse_des_données">Etudier l'analyse des données</h4>
+
+<p>Vous devriez maintenant être capable de retourner sur la page d'accueil <a href="https://analytics.google.com/analytics/web">Analytics Web</a>, et commencer à regarder les données que vous avez collecté à propos de votre site (bien entendu, vous devez laisser passer un peu de temps afin de permettre aux données de votre site d'être collectées.)</p>
+
+<p>Par défaut, vous devriez voir ce tableau de rapport, comme ceci :</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/14081/analytics-reporting.png" style="border-style: solid; border-width: 1px; display: block; height: 386px; margin: 0px auto; width: 700px;"></p>
+
+<p>Il y a une énorme quantité de donnée que vous pouvez regarder en utilisant Google Analytics — des rapports personnalisés dans différentes catégories, etc. — et nous n'avons pas le temps pour tous les aborder. <a href="https://support.google.com/analytics/answer/1008015">Démarrer avec Analytics</a> fournit une aide utile sur les rapports (et plus) pour les débutants.</p>
+
+<p>Vous devriez aussi vous intéresser aux différentes options du menu gauche, et voir quels types de données vous pouvez trouver. Par exemple, vous pouvez trouver quels navigateurs et quels systèmes d'exploitation vos utilisateurs utilisent en sélectionnant <em>Audience</em> &gt; <em>Technologie</em> &gt; <em>Navigateur &amp; OS</em> du menu gauche.</p>
+
+<div class="note">
+<p><strong>Note </strong>: Lorsque vous utilisez Google Analytics, vous devez pour prévenir des biais trompeurs, par ex. "Nous n'avons aucun utilisateur de Firefox Mobile" peut vous amener à ne pas vous soucier de supporter Firefox Mobile. Mais vous n'allez pas avoir un seul utilisateur de Firefox Mobile si le site ne fonctionnait pas dessus dès le départ.</p>
+</div>
+
+<h3 id="Autres_cas">Autres cas</h3>
+
+<p>Il y a d'autres cas que vous devriez aussi probablement prendre en compte. Vous devez assurément inclure l'accessibilité en tant que condition nécessaire de test de niveau A (nous couvrirons exactement qu'est-ce que vous devez tester dans notre article sur la Gestion des problèmes commun d'accessibilité).</p>
+
+<p>Vous pouvez avoir à prendre d'autres considérations supplémentaires. Si vous êtes en train de créer une sorte d'intranet pour fournir les chiffres d'affaires aux managers, et tous les managers ont reçu des téléphones Windows par exemple, vous devez faire du support IE pour mobile une priorité.</p>
+
+<h3 id="Liste_de_support_finale">Liste de support finale</h3>
+
+<p>Donc, notre liste de support finale devrait finir par ressemble à ça :</p>
+
+<ol>
+ <li>Grade A : Chrome et Firefox pour Windows/Mac, Safari pour Mac, Edge et IE pour Windows (les deux dernières versions de chaque), iOS Safari pour iPhone/iPad, Android stock browser (les deux dernières versions) pour téléphone/tablette, Chrome et Firefox pour Android (les deux dernières versions) sur téléphone/tablette. L'accessibilité qui passe les tests courants.</li>
+ <li>Grade B : IE 8 et 9 pour Windows, Opera Mini.</li>
+ <li>Grade C : Opera, d'autres bons navigateurs modernes.</li>
+</ol>
+
+<h2 id="Qu'est-ce_que_vous_allez_tester">Qu'est-ce que vous allez tester ?</h2>
+
+<p>Lorsque vous ajouter une nouveauté à votre code de base qui nécessite d'être testée, avant de commencer vos tests, vous devez rédiger une liste des conditions des tests qui ont besoin de passer pour être admises. Ces conditions peuvent être visuelles ou fonctionnelles — combiner les deux afin de mettre en place une fonctionnalité web utilisable.</p>
+
+<p>Considérez l'exemple suivant (voir le <a href="https://github.com/mdn/learning-area/blob/master/tools-testing/cross-browser-testing/strategies/hidden-info-panel.html">code source</a>, et aussi l'<a href="http://mdn.github.io/learning-area/tools-testing/cross-browser-testing/strategies/hidden-info-panel.html">exemple exécuté en direct</a>) :</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/14083/sliding-box-demo.png" style="border-style: solid; border-width: 1px; display: block; height: 455px; margin: 0px auto; width: 700px;"></p>
+
+<p>Les critères de test pour cette fonctionnalité peuvent être rédigés comme ceci :</p>
+
+<p>Grade A et B :</p>
+
+<ul>
+ <li>Le bouton doit être activable par le mécanisme de contrôle primaire de l'utilisateur, qu'importe ce qu'il est — cela doit inclure la souris, le clavier, et le tactile.</li>
+ <li>Appuyer sur le bouton doit faire apparaître/disparaître la boîte d'information.</li>
+ <li>Le texte doit être lisible.</li>
+ <li>Les utilisateurs malvoyants utilisant des lecteurs d'écran doivent pouvoir accéder au texte.</li>
+</ul>
+
+<p>Grade A :</p>
+
+<ul>
+ <li>La boîte d'information doit s'animer de façon fluide quand elle apparaît/disparaît</li>
+ <li>Le gradient et l'ombre du texte doivent apparaître afin de mettre en valeur l'aspect de la boîte.</li>
+</ul>
+
+<p>Vous avez dû remarquer que le texte dans l'exemple ne fonctionne pas sur IE8 — selon notre liste de support c'est un problème, que vous devez résoudre, peut-être en utilisant une librairie de détection afin d'implémenter la fonctionnalité d'une autre manière si le navigateur ne supporte pas les transitions CSS (voir Implémenter une fonctionnalité de détection, plus tard dans le cours)</p>
+
+<p>Vous avez aussi dû remarquer que le bouton n'est pas utilisable en se servant du clavier — cela a aussi besoin d'être résolu. Peut-être que nous pouvons utiliser un peu de Javascript afin d'implémenter un contrôle clavier pour le basculement, ou utiliser une tout autre méthode ?</p>
+
+<p>Ces critères de test sont utiles, parce que :</p>
+
+<ul>
+ <li>Ils vous donnent une série d'étapes à suivre lorsque vous jouer des tests.</li>
+ <li>Ils peuvent être facilement transformés en listes d'instructions à suivre pour les groupes d'utilisateurs lorsqu'ils effectuent des tests (par ex. "essayer d'activer les bouton en utilisant votre souris, et ensuite le clavier...") — voir {{anch("User testing")}}, voir plus bas.</li>
+ <li>Ils peuvent aussi apporter une base pour rédiger les tests automatiques. C'est plus simple d'écrire de tels tests si vous savez exactement ce que vous voulez tester, et quelles sont les conditions de succès (voir Utiliser un outil d'automatisation pour les tests automatiques de navigateurs, plus tard dans cette série).</li>
+</ul>
+
+<h2 id="Mettre_en_place_ensemble_un_labo_de_test">Mettre en place ensemble un labo de test</h2>
+
+<p>Une option pour effectuer les tests sur navigateurs et de faire les tests par vous-mêmes. Pour faire cela, vous allez sûrement utiliser une combinaison d'appareils physiques actuels, et simuler des environnements (utiliser soit un émulateur ou une machine virtuelle).</p>
+
+<h3 id="Les_appareils_physiques">Les appareils physiques</h3>
+
+<p>C'est généralement le mieux d'avoir de vrais supports pour exécuter le navigateur que vous voulez tester — cela fournit la plus grande précision en termes de comportement et sur l'ensemble de l'expérience utilisateur. Vous allez sûrement avoir besoin de quelque chose comme suit, pour un labo d'appareils de bas niveau :</p>
+
+<ul>
+ <li>Un Mac, avec les navigateurs installés que vous avec besoin de tester — cela peut inclure Firefox, Chrome, Opera et Safari.</li>
+ <li>Un PC Windows, avec les navigateurs installés que vous avez besoin de tester — cela peut inclure Edge (ou IE), Chrome, Firefox et Opera.</li>
+ <li>Un téléphone et une tablette Android haut de gamme avec les navigateurs installés que vous avez besoin de tester — cela peut inclure Chrome, Firefox, et Opera Mini pour Android, bien entendu l'original Android stock browser.</li>
+ <li>Un téléphone et une tablette iOS haut de gamme avec les navigateurs installés que vous avez besoin de tester — cela peut inclure iOS Safari, et Chrome, Firefox, et Opera Mini pour iOS.</li>
+</ul>
+
+<p>Les éléments suivants sont également une bonne option, si vous pouvez les obtenir :</p>
+
+<ul>
+ <li>Un PC Linux sous la main, dans le cas où vous avez besoin de tester des bugs spécifiques sur des versions de navigateurs de Linux. Les utilisateurs de Linux utilisent généralement Firefox, Opera, et Chrome. Si vous n'avez qu'une seule machine de disponible, vous pouvez envisager de créer une machine en dual boot exécutant Linux et Windows sur des partitions séparées. L'installeur d'Ubuntu rend cela assez facile à configurer ; voir <a href="https://help.ubuntu.com/community/WindowsDualBoot">WindowsDualBoot</a> pour de l'aide à ce propos.</li>
+ <li>Une paire d'appareils mobile bas de gamme, afin que vous puissiez tester la performance des fonctionnalités comme les animations sur des processeurs faibles.</li>
+</ul>
+
+<p>Votre machine de travail principale peut aussi être un support pour installer d'autre outils pour une objectif spécifique, comme des outils de vérification de l'accessibilité, des lecteurs d'écran, et des émulateurs/machines virtuelles.</p>
+
+<p>Certaines grandes entreprises ont des labos d'appareils qui stockent une sélection très large de différents appareils, permettant aux développeurs de traquer les bugs sur des combinaisons de navigateur/appareil très précises. Les plus petites entreprises et les indépendants n'ont généralement pas les moyens de s'offrir des labos aussi sophistiqués, ils ont donc tendance à avoir des labos plus petits, des émulateurs, des machines virtuelles et des applis de tests commerciales.</p>
+
+<p>Nous couvrirons chacune des autres options plus bas.</p>
+
+<div class="note">
+<p><strong>Note </strong>: Certains efforts ont été effectué afin de créer des labos d'appareils accessibles au public — voir <a href="https://opendevicelab.com/">Open Device Labs</a>.</p>
+</div>
+
+<div class="note">
+<p><strong>Note </strong>: Nous devons aussi prendre en considération l'accessibilité — il y a plusieurs outils utiles que vous pouvez installer sur votre machine afin de faciliter les tests d'accessibilité, mais nous les couvrirons dans l'article Gestion des problèmes communs d'accessibilité, plus tard dans le cours.</p>
+</div>
+
+<h3 id="Les_émulateurs">Les émulateurs</h3>
+
+<p>Les émulateurs sont essentiellement des programmes qui s'exécutent à l'intérieur de votre ordinateur et simulent des appareils ou des conditions particulières d'appareil d'un certain type, ils vous permettent de faire certains tests plus aisément qu'en ayant à trouver une combinaison de matériels/logiciels à tester.</p>
+
+<p>Un émulateur peut être aussi simple à tester qu'une condition d'appareil. Par exemple, si vous voulez faire quelques tests rapides et sales de la largeur/hauteur de vos media queries pour le responsive design, vous pouvez utiliser le<a href="/en-US/docs/Tools/Responsive_Design_Mode"> Mode Design Responsive</a> de Firefox. Safari possède également un mode similaire, qui peut être activé en allant dans <em>Safari</em> &gt; <em>Préférences</em>, et en cochant <em>Show Develop menu</em>, puis en choisissant <em>Develop &gt; Enter Responsive Design Mode</em>. Chrome propose également quelque chose de similaire : Device mode (voir <a href="https://developers.google.com/web/tools/chrome-devtools/device-mode/">Simuler un Appareil Mobile avec le Device Mode</a>).</p>
+
+<p>Le plus souvent, vous allez devoir installer un émulateur. Les appareils/navigateurs les plus courants que vous allez devoir tester sont les suivants :</p>
+
+<ul>
+ <li>L'officiel <a href="https://developer.android.com/studio/">Android Studio IDE</a> pour développer des applis Android, il est assez pesant juste pour tester des sites web sur Google Chrome ou le vieux Stock Android browser, mais il est fournit avec un <a href="https://developer.android.com/studio/run/emulator.html">émulateur</a> Robuste. Si vous voulez quelque chose d'un peu plus léger, <a href="http://leapdroid.com/">LeapDroid</a> est une bonne option pour Windows et <a href="http://www.andyroid.net/">Andy</a> est une option acceptable qui s'exécute aussi bien sur Windows que sur Mac.</li>
+ <li>Apple fournit une appli appelée <a href="https://developer.apple.com/library/content/documentation/IDEs/Conceptual/iOS_Simulator_Guide/Introduction/Introduction.html">Simulator</a> qui s'exécute au-dessus de l'environnement de développement <a href="https://developer.apple.com/xcode/">XCode</a>, et émule iPad/iPhone/Apple Watch/Apple TV. Il comprend le navigateur natif iOS Safari. Il n'est malheureusement disponible que pour Mac.</li>
+</ul>
+
+<p>Vous pouvez facilement trouver des simulateurs pour les autres environnements d'appareil mobile, par exemple :</p>
+
+<ul>
+ <li><a href="https://developer.blackberry.com/develop/simulator/">Blackberry</a> (émulateur disponible pour Windows, Mac OSX et Linux).</li>
+ <li>Vous pouvez simuler <a href="https://dev.opera.com/articles/installing-opera-mini-on-your-computer/">Opera Mini</a> tel quel si vous voulez le tester.</li>
+ <li>Il y a des émulateurs disponibles pour les OSs Windows Mobile : voir <a href="https://msdn.microsoft.com/en-us/library/windows/apps/ff402563(v=vs.105).aspx">Les émulateurs pour les Windows Phone 8</a> et <a href="https://msdn.microsoft.com/en-us/windows/uwp/debug-test-perf/test-with-the-emulator">Test avec l'Emulateur Microsoft pour Windows 10 Mobile</a> (il ne fonctionnent que sur Windows).</li>
+</ul>
+
+<div class="note">
+<p><strong>Note </strong>: Beaucoup d'émulateurs requièrent actuellement l'utilisation d'une machine virtuelle (voir en-dessous) ; quand c'est le cas, les instructions sont souvent fournies, et/ou l'utilisation de la machine virtuelle est inclue dans l'installeur de l'émulateur.</p>
+</div>
+
+<h3 id="Les_machines_virtuelles">Les machines virtuelles</h3>
+
+<p>Les machines virtuelles sont des applications qui s'exécutent sur le bureau de votre ordinateur et vous permettent d'exécuter les simulations de tous les systèmes d'exploitation, chacun compartimenté sur son propre disque dur virtuel (souvent représenté par un seul large fichier existant sur le disque dur de la machine hôte). Il y a plusieurs applis de machine virtuelle populaire, comme <a href="www.parallels.com/">Parallels</a>, <a href="http://www.vmware.com/">VMWare</a>, et <a href="https://www.virtualbox.org/wiki/Downloads">Virtual Box</a>; personnellement, nous préférons la dernière, parce qu'elle est gratuite.</p>
+
+<div class="note">
+<p><strong>Note </strong>: Nous avons besoin de beaucoup d'espace disponible sur le disque dur pour exécuter les émulations de machine virtuelle ; chaque système d'exploitation que vous émulez peut prendre beaucoup de mémoire. Vous aurez tendance à choisir l'espace de disque dur que vous voulez pour chaque installation ; vous pouvez vous en sortir avec environ 10Go, mais certaines sources recommandent d'augmenter à 50Go ou plus, alors le système d'exploitation s'éxécutera de façon fiable. Une bonne option fournit par la plupart des applis de machine virtuelle est de créer des disques durs à allocations dynamiques qui grossissent et rétrécissent en fonction que les besoins surviennent.</p>
+</div>
+
+<p>Pour utiliser Virtual Box, vous avez besoin de :</p>
+
+<ol>
+ <li>Procurez-vous un disque d'installation ou une image (par ex. un ISO) du système d'exploitation que vous voulez émuler. Virtual Box est en mesure de vous les fournir ; la plupart, comme les OSs de Windows, sont des produits commerciaux qui ne peuvent être distribués gratuitement.</li>
+ <li><a href="https://www.virtualbox.org/wiki/Downloads">Téléchargez l'installeur approprié</a> pour votre système d'exploitation et installez-le.</li>
+ <li>Ouvrez l'appli ; vous verrez une vue ressemblant à ceci : <img alt="" src="https://mdn.mozillademos.org/files/14089/virtualbox.png" style="display: block; height: 512px; margin: 0px auto; width: 700px;"></li>
+ <li>Pour créer une nouvelle machine virtuelle, appuyer sur le bouton <em>Nouveau</em> dans le coin en haut à gauche.</li>
+ <li>Suivez les instructions et remplissez les boîtes de dialogues suivantes comme il se doit. Vous allez :
+ <ol>
+ <li>Donner un nom à votre machine virtuelle</li>
+ <li>Choisir un système d'exploitation et une version que vous allez installer dessus</li>
+ <li>Préciser combien de RAM doit être allouée (nous vous recommandons quelque chose comme 2048Mo, ou 2Go)</li>
+ <li>Créer un disque dur virtuel (choisissez les options pas défaut à travers les trois boîtes de dialogues contenant <em>Créer un disque dur virtuel maintenant</em>, <em>IDV (image disque virtuelle)</em>, <em>Allocation dynamique</em>)</li>
+ <li>Choisissez l'emplacement du fichier et la taille du disque dur virtuel (choisir un nom sensé et un emplacement facile à garder, et pour la dimension préciser quelque chose autour de 50Go, ou autant que vous pensez que c'est nécessaire)</li>
+ </ol>
+ </li>
+</ol>
+
+<p>Maintenant la nouvelle virtual box devrait apparaître dans le menu gauche de la fenêtre de l'interface principale de Virtual Box. A ce stade, vous pouvez double-cliquer dessus pour ouvrir la virtual box — cela commencera à démarrer la machine virtuelle, mais il n'y aura pas encore le système d'exploitation d'installé. A cet instant vous devez préciser à la boîte de dialogue l'image de votre programme d'installation, et les étapes s'exécuteront une par une dans la machine virtuelle, exactement comme si c'était un vrai ordinateur.</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/14085/virtualbox-installer.png" style="display: block; margin: 0 auto;"></p>
+
+<div class="warning">
+<p><strong>Important </strong>: Vous devez vous assurez que vous avez l'image du système d'exploitation que vous voulez installer sur la machine virtuelle existante à ce stade, et l'installer complètement. Si vous annulé le processus à ce stade, cela peut rendre la machine virtuelle inutilisable, et vous amener à la supprimer et en créer une nouvelle. Ce n'est pas fatal, mais c'est ennuyant.</p>
+</div>
+
+<p>Une fois que le processus est complété, vous devriez avoir une machine virtuelle exécutant un système d'exploitation à l'intérieur d'une fenêtre sur votre ordinateur hôte.</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/14087/virtualbox-running.png" style="display: block; margin: 0 auto;"></p>
+
+<p>Vous devez vous occuper de l'installation de ce système d'exploitation virtuel exactement comme d'une installation réelle — par exemple, de même que vous devez installer les navigateurs que vous voulez tester, installez un programme d'antivirus pour vous protégez des virus.</p>
+
+<p>Avoir plusieurs machines virtuelles est très utile, particulièrement pour les test IE/Edge sur Windows — sur Windows, vous n'êtes pas autorisé à avoir de multiples versions du navigateur par défaut installé, donc vous pouvez vous construire une librairie de machines virtuelles afin de gérer les différents tests requis, par ex. :</p>
+
+<ul>
+ <li>Windows 10 avec Edge 14</li>
+ <li>Windows 10 avec Edge 13</li>
+ <li>Windows 8.1 avec IE11</li>
+ <li>Windows 8 avec IE10</li>
+ <li>Windows 7 avec IE9</li>
+ <li>Windows XP avec IE8</li>
+ <li>Windows XP avec IE7</li>
+ <li>Windows XP avec IE6</li>
+</ul>
+
+<div class="note">
+<p><strong>Note </strong>: Une autre bonne chose à propos des machines virtuelles, c'est que les images de disque virtuel sont clairement autonomes. Si vous travaillez en équipe, vous pouvez créer une image disque, puis la copier et vous la passer. Assurez-vous juste d'avoir les licences requises pour exécuter toutes les copies de Windows ou qu'importe ce que vous exécutez, si c'est un produit licencié.</p>
+</div>
+
+<h3 id="Automatisation_et_applis_commerciales">Automatisation et applis commerciales</h3>
+
+<p>Comme précisé dans le chapitre précédent, vous pouvez vous retirer beaucoup de peine concernant les tests de navigateur en utilisant un système d'automatisation. Vous pouvez configurer votre propre système d'automatisation de test (<a href="http://www.seleniumhq.org/">Selenium</a> est devenue l'appli de choix la plus répandue), ce qui nécessite une certaine configuration, mais peut être très satisfaisant lorsque votre travail arrive à terme.</p>
+
+<p>Il y a également des outils commercials disponibles comme <a href="https://saucelabs.com/">Sauce Labs</a> et <a href="https://www.browserstack.com/">Browser Stack</a> qui font ce genre de choses pour vous, sans que vous ayez a vous souciez de la configuration, si vous êtes prêt à investir dans vos tests.</p>
+
+<p>Nous aborderons comment utiliser de tels outils plus tard dans ce module.</p>
+
+<h2 id="Les_tests_utilisateurs">Les tests utilisateurs</h2>
+
+<p>Avant de poursuivre, nous finirons cet article en abordant les tests utilisateurs — cela peut être une bonne option si vous avez un groupe d'utilisateurs volontaires pour tester votre nouvelle fonctionnalité. Ne perdez pas de vue que cela peut être aussi peu ou beaucoup sophistiqué que vous le désirez — votre groupe d'utilisateurs peut être un groupe d'amis, un groupe de collègues, ou un groupe de volontaires bénévoles ou rémunérés, cela dépend si vous avez de l'argent à dépenser en test.</p>
+
+<p>La plupart du temps vous permettrez à vos utilisateurs de regarder la page ou la vue contenant la nouvelle fonctionnalité sur un serveur de développement, de cette manière vous n'exposez pas le site final ou les modifications en direct avant qu'il ne soit terminé. Vous devez leur recommander de suivre certaines étapes et de rapporter les résultats qu'ils ont obtenu. Il est important d'établir une liste d'étapes (parfois appelé script) vous aurez ainsi plus de résultats fiables se rapportant à ce que vous essayez de tester. Nous avons mentionné cela dans la section {{anch("What are you going to test")}} plus haut — c'est facile de transformer les critères de test détaillés ici en étapes à suivre. Par exemple, ce qui suit devrait fonctionner pour un utilisateur voyant :</p>
+
+<ul>
+ <li>Cliquez plusieurs fois sur le bouton en point d'interrogation en utilisant votre souris sur votre ordinateur de bureau. Rafraîchir la fenêtre du navigateur.</li>
+ <li>Sélectionnez et activer plusieurs fois le bouton en point d'interrogation en utilisant votre clavier sur votre ordinateur de bureau.</li>
+ <li>Touchez plusieurs fois le bouton en point d'interrogation sur l'écran tactile de votre appareil.</li>
+ <li>Activer le bouton devrait faire apparaitre/disparaître la boîte d'information. Est-ce que cela fonctionne, dans chacun des trois cas ci-dessus ?</li>
+ <li>Est-ce que le texte est lisible ?</li>
+ <li>Est-ce que le boîte d'information s'anime sans problème lorsqu'elle apparaît/disparait ?</li>
+</ul>
+
+<p>Lorsque vous exécutez les tests, cela peut aussi être une bonne idée de :</p>
+
+<ul>
+ <li>Configurer si possible un profil navigateur séparé, avec les extensions et ces autres types de choses des navigateurs désactivées, et exécuter vos tests sur ce profile (voir <a href="https://support.mozilla.org/en-US/kb/profile-manager-create-and-remove-firefox-profiles">Utiliser le Profile Manager pour créer et retirer des profiles Firefox</a> et <a href="https://support.google.com/chrome/answer/2364824">Share Chrome with others or add personas</a>, par exemple).</li>
+ <li>Utiliser le mode navigation privée sur votre navigateur lorsque vous exécutez vos tests, quand il est disponible (par ex. <a href="https://support.mozilla.org/en-US/kb/private-browsing-use-firefox-without-history">Private Browsing</a> sur Firefox, <a href="https://support.google.com/chrome/answer/95464">Incognito Mode</a> sur Chrome) grâce à cela les cookies et les fichiers temporaires ne seront pas sauvegardés.</li>
+</ul>
+
+<p>Ces étapes sont conçues pour s'assurer que le navigateur que vous êtes en train de tester est aussi "pure" que possible. C-à-d qu'il n'y a rien d'installé qui pourrait affecter les résultats des tests.</p>
+
+<div class="note">
+<p><strong>Note </strong>: Une autre option faiblement utile, si vous avez le matériel disponible est de tester vos sites sur des téléphones bas de gammes/d'autres appareils — plus vos sites vont s'agrandir et les fonctionnalités avoir plus d'effets, plus vous avez des chances que votre site subisse des ralentissements, il vous faut donc prendre la performance comme une nouvelle considération importante. Essayer de faire marcher vos fonctionnalités sur des appareils bas de gamme, cela rendra l'expérience bien meilleure sur des appareils haut de gamme.</p>
+</div>
+
+<div class="note">
+<p><strong>Note </strong>: Certains environnement de développement côté serveur fournissent des mécanismes très utiles pour sortir les modifications sur le site pour seulement un sous-ensemble d'utilisateurs, très utile pour sortir des fonctionnalités testées par un sous-ensemble d'utilisateurs sans avoir besoin de mettre en place un serveur de développement séparé. Un bon exemple est <a href="https://github.com/jsocol/django-waffle">Django Waffle Flags</a>.</p>
+</div>
+
+<h2 id="Résumé">Résumé</h2>
+
+<p>Après avoir lu cet article vous devriez maintenant avoir une bonne idée de ce que vous pouvez faire pour identifier votre liste de public cible/navigateur cible, et ensuite efficacement mener à bien vos tests en navigateur croisé en se basant sur cette liste.</p>
+
+<p>La prochaine fois nous tournerons notre attention sur les problèmes concrets de votre code que vos tests peuvent révéler, en commençant avec le HTML et le CSS.</p>
+
+<p>{{PreviousMenuNext("Learn/Tools_and_testing/Cross_browser_testing/Introduction","Learn/Tools_and_testing/Cross_browser_testing/HTML_and_CSS", "Learn/Tools_and_testing/Cross_browser_testing")}}</p>
+
+<p> </p>
+
+<h2 id="Dans_ce_module">Dans ce module</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Introduction">Introduction to cross browser testing</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Testing_strategies">Strategies for carrying out testing</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/HTML_and_CSS">Handling common HTML and CSS problems</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/JavaScript">Handling common JavaScript problems</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Accessibility">Handling common accessibility problems</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Feature_detection">Implementing feature detection</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Automated_testing">Introduction to automated testing</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Your_own_automation_environment">Setting up your own test automation environment</a></li>
+</ul>
+
+<p> </p>
diff --git a/files/fr/learn/tools_and_testing/understanding_client-side_tools/index.html b/files/fr/learn/tools_and_testing/understanding_client-side_tools/index.html
new file mode 100644
index 0000000000..c954b9395a
--- /dev/null
+++ b/files/fr/learn/tools_and_testing/understanding_client-side_tools/index.html
@@ -0,0 +1,39 @@
+---
+title: Understanding client-side web development tools
+slug: Learn/Tools_and_testing/Understanding_client-side_tools
+tags:
+ - Beginner
+ - CSS
+ - Deployment
+ - HTML
+ - JavaScript
+ - Learn
+ - Tools
+ - TopicStub
+ - Transformation
+ - client-side
+ - linting
+translation_of: Learn/Tools_and_testing/Understanding_client-side_tools
+---
+<div>{{LearnSidebar}}</div>
+
+<p class="summary">Les outils côté client peuvent être intimidants, mais cette série d'articles vise à illustrer le but de certains des types d'outils côté client les plus courants, à expliquer les outils que vous pouvez enchaîner, comment les installer à l'aide de gestionnaires de packages et les contrôler à l'aide de la ligne de commande. Nous terminons en fournissant un exemple complet de chaîne d'outils vous montrant comment devenir productif.</p>
+
+<h2 id="Conditions_prérequises">Conditions prérequises</h2>
+
+<p>Vous devez vraiment apprendre les bases des langages <a href="/en-US/docs/Learn/HTML">HTML</a>, <a href="/en-US/docs/Learn/CSS">CSS</a>, et <a href="/en-US/docs/Learn/JavaScript">JavaScript</a> avant d'essayer d'utiliser les outils détaillés ici.</p>
+
+<h2 id="Guides">Guides</h2>
+
+<dl>
+ <dt><a href="/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Overview">Vue d'ensemble de l'outillage côté client</a></dt>
+ <dd>Dans cet article, nous vous proposons un aperçu des outils Web modernes, des types d'outils disponibles et de l'endroit où vous les rencontrerez dans le cycle de vie du développement d'applications Web, et comment trouver de l'aide sur des outils individuels.</dd>
+ <dt><a href="/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Command_line">Cours intensif en ligne de commande</a></dt>
+ <dd>Dans votre processus de développement, vous devrez sans aucun doute exécuter une commande dans le terminal (ou sur la "ligne de commande" - ce sont en fait la même chose). Cet article fournit une introduction au terminal, les commandes essentielles que vous devrez y saisir, comment enchaîner des commandes et comment ajouter vos propres outils d'interface de ligne de commande (CLI).</dd>
+ <dt><a href="/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Package_management">Principes de base de la gestion des paquets</a></dt>
+ <dd>Dans cet article, nous examinerons en détail les gestionnaires de paquets pour comprendre comment nous pouvons les utiliser dans nos propres projets - pour installer les dépendances des outils de projet, les maintenir à jour, etc.</dd>
+ <dt><a href="/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Introducing_complete_toolchain">Introduction d'une chaîne d'outils complète</a></dt>
+ <dd>Dans les deux derniers articles de la série, nous solidifierons vos connaissances en matière d'outillage en vous guidant tout au long du processus de création d'un exemple de chaîne d'outils d'étude de cas. Nous irons de la mise en place d'un environnement de développement sensible et de la mise en place d'outils de transformation au déploiement effectif de votre application sur Netlify. Dans cet article, nous allons présenter l'étude de cas, configurer notre environnement de développement et configurer nos outils de transformation de code.</dd>
+ <dt><a href="/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Deployment">Déployer notre application</a></dt>
+ <dd>Dans le dernier article de notre série, nous prenons l'exemple de chaîne d'outils que nous avons construit dans l'article précédent et nous l'ajoutons afin de pouvoir déployer notre exemple d'application. Nous poussons le code sur GitHub, le déployons à l'aide de Netlify et vous montrons même comment ajouter un test simple au processus.</dd>
+</dl>
diff --git a/files/fr/learn/tools_and_testing/understanding_client-side_tools/ligne_de_commande/index.html b/files/fr/learn/tools_and_testing/understanding_client-side_tools/ligne_de_commande/index.html
new file mode 100644
index 0000000000..74d503b7d4
--- /dev/null
+++ b/files/fr/learn/tools_and_testing/understanding_client-side_tools/ligne_de_commande/index.html
@@ -0,0 +1,487 @@
+---
+title: Cours express sur la ligne de commande
+slug: Learn/Tools_and_testing/Understanding_client-side_tools/Ligne_de_commande
+tags:
+ - CLI
+ - Côté client
+ - Débutant
+ - Outils
+ - Terminal
+ - ligne de commande
+ - npm
+translation_of: Learn/Tools_and_testing/Understanding_client-side_tools/Command_line
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/Tools_and_testing/Understanding_client-side_tools/Overview","Learn/Tools_and_testing/Understanding_client-side_tools/Package_management", "Learn/Tools_and_testing/Understanding_client-side_tools")}}</div>
+
+<p>Au cours de tout process de développement, vous allez très certainement être confronté à la nécessité d'exécuter des commandes dans un terminal (ce que l'on appelle "travailler en ligne de commande"). Cet article vous propose une introduction au terminal et vous dévoile les commandes essentielles dont vous aurez besoin, la façon de les chaîner, et comment ajouter vos propres outils d'interface en ligne de commande (CLI, command line interface).</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Prérequis :</th>
+ <td>
+ <p>Être familiarisé avec les bases des langages</p>
+ <a href="/en-US/docs/Learn/HTML">HTML</a>, <a href="/en-US/docs/Learn/CSS">CSS</a>, et <a href="/en-US/docs/Learn/JavaScript">JavaScript</a>.</td>
+ </tr>
+ <tr>
+ <th scope="row">Objectif :</th>
+ <td>
+ <p>Comprendre ce qu'est la ligne de commande, savoir quelles sont les commandes de base que vous devriez connaître, et comment installer de nouveaux outils de ligne de commande.</p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 class="western" id="Bienvenue_sur_le_terminal">Bienvenue sur le terminal</h2>
+
+<p>Le terminal est une interface de texte pour l'exécution de programmes qui utilisent un langage lui-même textuel . Quel que soit le type d'outils que vous allez utiliser pour le développement web, il y a de grandes chances que vous soyez amené à travailler en ligne de commande pour les utiliser (vous rencontrerez aussi l'appellation "console" ou encore "CLI tools" pour désigner de tels outils d'interface en ligne de commande).</p>
+
+<p>Il existe de nombreux outils pour travailler en ligne de commande ; certains sont pré-installés sur votre système, et une infinité d'autres sont disponibles sur des dépôts de "paquets" (packages). Ces dépôts sont un peu comme des magasins spécialisés (pour la plupart) dans les outils de ligne de commande et les logiciels. Nous allons voir un peu plus loin dans ce chapitre comment installer certains de ces outils, et nous en apprendrons plus sur les dépôts de paquets dans le prochain chapitre.</p>
+
+<p>L'une des critiques les plus fréquentes envers la ligne de commande, c'est que l'utilisateur courant n'en a pratiquement aucune expérience. Se retrouver devant un terminal pour la première fois peut être vraiment intimidant : un écran vide, un curseur qui clignote, et rien ou presque pour vous aider à en tirer quelque chose.</p>
+
+<p>Malgré cette apparence rebutante, le terminal est pourtant un outil puissant, et nous pouvons vous promettre qu'avec une petite formation et un peu de pratique, son utilisation vous deviendra bien plus facile ! C'est la raison pour laquelle nous vous proposons ce chapitre - pour vous aider à démarrer dans cet environnement apparemment inhospitalier.</p>
+
+<p>.</p>
+
+<h3 class="western" id="Quelle_est_lorigine_du_terminal">Quelle est l'origine du terminal ?</h3>
+
+<p>Elle se situe dans les années 50-60, et son aspect d'alors ne ressemble pas du tout à ce que nous connaissons aujourd'hui (heureusement). Vous pouvez en apprendre davantage sur la page de Wikipédia <a href="https://fr.wikipedia.org/wiki/Terminal_(informatique)">Terminal (informatique)</a>.</p>
+
+<p>Depuis, le terminal est resté un élément constant de tout système d'exploitation - des ordinateurs de bureau aux serveurs du cloud (qui n'est pas vraiment un nuage) en passant par les micro-cartes comme la Raspberry PI Zero et même les téléphones mobiles. Il offre un accès direct au système de fichiers de l'ordinateur et à des fonctionnalités de bas niveau, ce qui le rend incroyablement apte à accomplir rapidement des tâches complexes, à condition de savoir ce que vous faites.</p>
+
+<p>Il est également utile pour automatiser certaines tâches, comme par exemple modifier les titres de centaines de fichiers instantanément - par exemple changer tous les "ch01-xxxx.png" en "ch02-xxxx.png", ce qui vous prendrait un temps considérable si vous deviez le faire à la main dans la fenêtre d'un gestionnaire de fichiers.</p>
+
+<p>En tous cas, le terminal ne va pas disparaître de si tôt.</p>
+
+<h3 class="western" id="À_quoi_ressemble_un_terminal">À quoi ressemble un terminal ?</h3>
+
+<p>Vous pouvez voir ci-dessous les apparences de quelques terminaux émulés par des programmes courants.</p>
+
+<p>Les images suivantes montrent les invites de commande disponibles sous Windows – il y a une panoplie d’options, du programme « cmd » au « powershell » - qui peuvent être lancées depuis le menu de démarrage en tapant le nom du programme.</p>
+
+<p><img alt="A vanilla windows cmd line window, and a windows powershell window" src="https://mdn.mozillademos.org/files/17183/win-terminals.png" style="border-style: solid; border-width: 1px; display: block; height: 261px; margin: 0px auto; width: 900px;"></p>
+
+<p>Et ci-dessous, vous pouvez voir l’application de terminal pour macOS.</p>
+
+<p><img alt="A basic vanilla mac terminal" src="https://mdn.mozillademos.org/files/17180/mac-terminal.png" style="display: block; height: 223px; margin: 0px auto; width: 500px;"></p>
+
+<h3 class="western" id="Comment_ouvrir_un_terminal">Comment ouvrir un terminal ?</h3>
+
+<p>Beaucoup de développeurs se servent aujourd'hui de terminaux de type Unix (c'est-à-dire le terminal en lui-même plus les outils auxquels il donne accès). Beaucoup de tutoriels sur le web sont basés sur ces terminaux Unix qu'ils considèrent (malheureusement) comme universels, mais nous allons voir dans cette section comment ouvrir un terminal sur le système de votre choix.</p>
+
+<h4 id="LinuxUnix">Linux/Unix</h4>
+
+<p>Comme indiqué plus haut, les systèmes Linux/Unix disposent d'un terminal par défaut, présent dans vos Applications.</p>
+
+<h4 id="macOS">macOS</h4>
+
+<p>macOS a un système nommé Darwin qui réside sous l'interface graphique. Darwin est un système de type Unix, qui fournit le terminal, et l'accès aux outils de bas niveau. Darwin est dans l'ensemble assez proche d'Unix pour ne pas nous causer trop de problèmes lors de notre progression dans cet article.</p>
+
+<p>Ce terminal est disponible sur macOS dans Applications/Utilitaires/Terminal.</p>
+
+<h4 id="Windows">Windows</h4>
+
+<p>Comme pour d'autres outils de programmation, c’est un peu une tradition pour Windows de ne pas faciliter l’utilisation du terminal (ou ligne de commande) par rapport à d’autres systèmes d’exploitation. Mais les choses s’améliorent.</p>
+
+<p>Traditionnellement aussi, Windows a depuis longtemps eu son propre programme de type « terminal », appelé « cmd » (« l’invite de commande »), mais celui-ci n’est en rien comparable aux commandes Unix, et il est en fait équivalent au programme DOS des temps héroïques.</p>
+
+<p>On trouve malgré tout de meilleurs programmes qui offrent une expérience de terminal sur Windows, tels que Powershell (<a href="https://github.com/PowerShell/PowerShell">voir ici pour l’installer</a>), et Gitbash (qui fait partie de la trousse à outils <a href="https://gitforwindows.org/">git for Windows</a>).</p>
+
+<p>Quoi qu’il en soit, aujourd’hui, la meilleure option est le « Windows Subsystem for Linux » (WSL) – une couche de compatibilité qui permet de lancer des systèmes d’exploitation Linux directement dans Windows 10, ce qui vous permet d’avoir un « vrai terminal », sans recourir à une machine virtuelle.</p>
+
+<p>Vous pouvez l’installer gratuitement directement à partir du Windows store. Toute la documentation utile est disponible dans la <a href="https://docs.microsoft.com/en-us/windows/wsl">Windows Subsystem for Linux Documentation</a> .</p>
+
+<p><img alt="a screenshot of the windows subsystem for linux documentation" src="https://mdn.mozillademos.org/files/17184/wsl.png" style="border-style: solid; border-width: 1px; display: block; height: 665px; margin: 0px auto; width: 1000px;"></p>
+
+<p>Si vous vous demandez quelle option choisir sur Windows, nous vous recommandons vivement de vous décider pour le WSL. Vous pourriez certes vous en tenir à l’invite de commande par défaut (« cmd »), et faire tourner pas mal d’outils correctement, mais tout sera bien plus facile si vous avez une meilleure équivalence avec les outils Unix.</p>
+
+<h4 class="western" id="En_passant_quelle_est_la_différence_entre_ligne_de_commande_et_terminal">En passant, quelle est la différence entre ligne de commande et terminal ?</h4>
+
+<p>En général, vous rencontrerez ces deux termes utilisés de façon interchangeable. Techniquement, un terminal (ou console) est un logiciel qui se connecte à un shell au démarrage. Un shell correspond à votre session et à votre environnement de session (où des choses comme l’invite de commande et les raccourcis peuvent être personnalisés). La ligne de commande quant à elle (ou prompt) est la ligne de texte où vous entrez des commandes et où le curseur clignote.</p>
+
+<h3 id="Est-ce_quil_faut_se_servir_du_terminal">Est-ce qu'il <em>faut </em>se servir du terminal?</h3>
+
+<p>Bien que les outils disponibles à partir de la ligne de commande soient très riches, si vous utilisez des outils tels que <a href="https://code.visualstudio.com/">Visual Studio Code</a> vous allez avoir accès à une quantité d’extensions que vous pourrez utiliser pour vous aider dans l’édition et vous allez pouvoir vous passer presque complètement du terminal lui-même. Cependant, vous ne pourrez pas trouver une extension sur votre éditeur de code pour tout ce que vous voudrez faire – en définitive, vous devrez malgré tout vous confronter au terminal.</p>
+
+<h2 id="Les_commandes_intégrées_de_base">Les commandes intégrées de base</h2>
+
+<p>Assez parlé — voyons maintenant quelques commandes utilisables dans un terminal ! Voici, clés en main, un petit aperçu de tout ce que l'on peut faire en ligne de commande, avec la référence des outils pertinents dans chaque cas :</p>
+
+<ul>
+ <li>Naviguer dans le système de fichiers de votre ordinateur en accomplissant des tâches basiques telles que créer, copier, renommer et effacer :
+ <ul>
+ <li>Se déplacer dans l'arborescence des répertoires : <code>cd</code></li>
+ <li>Créer des répertoires : <code>mkdir</code></li>
+ <li>Créer des fichiers (et modifier leurs métadonnées): <code>touch</code></li>
+ <li>Copier des fichiers : <code>cp</code></li>
+ <li>Déplacer des fichiers : <code>mv</code></li>
+ <li>Supprimer des fichiers ou des répertoires : <code>rm</code></li>
+ </ul>
+ </li>
+ <li>Télécharger des fichiers à partir d'URL spécifiques : <code>curl</code></li>
+ <li>Rechercher des fragments de texte dans des parties de texte de taille importante : <code>grep</code></li>
+ <li>Afficher le contenu d'un fichier page par page: <code>less</code>, <code>cat</code></li>
+ <li>Manipuler et transformer des flux de texte (par exemple remplacer toutes les occurrences de <code>&lt;div&gt;</code> dans un fichier HTML par <code>&lt;article&gt;</code>): <code>awk</code>, <code>tr</code>, <code>sed</code></li>
+</ul>
+
+<div class="blockIndicator note">
+<p><strong>Note </strong>: On trouve  sur le web un bon nombre de tutoriels de qualité qui permettent d'aller beaucoup plus loin avec la ligne de commande — ceci n'est qu'une brève introduction ! L'auteur de ces lignes lui-même a sa propre <a href="https://terminal.training/?coupon=mdn">série de vidéos de formation au terminal</a> (80% de réduction en utilisant le code mdn au moment du paiement — 19$).</p>
+</div>
+
+<p>Pour aller plus loin, voyons maintenant comment utiliser quelques-uns de ces outils en ligne de commande. Commencez par ouvrir votre programme de terminal (ou console) !</p>
+
+<h3 id="Navigation_en_ligne_de_commande">Navigation en ligne de commande</h3>
+
+<p>Lorsque vous vous mettez sur la ligne de commande, vous allez inévitablement devoir naviguer vers un répertoire spécifique pour y "faire quelque chose". Tous les systèmes d'exploitation (du moins avec un paramétrage par défaut) démarrent leur terminal dans votre répertoire d'utilisateur, et il y a des chances pour que vous souhaitiez vous rendre de là à un autre emplacement.</p>
+
+<p>La commande <code>cd</code> vous permet de changer de répertoire (Change Directory). Techniquement, cd n'est pas un programme mais une commande intégrée. Cela signifie que votre système d'exploitation la fournit de façon native, et aussi que vous ne pouvez pas l'effacer accidentellement - bonne nouvelle ! Cela dit, vous n'avez pas besoin de vous soucier de savoir si une commande est intégrée ou non, mais vous pouvez garder à l'esprit que les commandes intégrées sont présentes sur les systèmes basés sur Unix.</p>
+
+<p>Pour changer de répertoire, vous tapez <code>cd</code> dans votre terminal, suivi par le répertoire dans lequel vous voulez vous rendre. En supposant que le répertoire (ou dossier) <code>Desktop</code> se trouve dans votre répertoire utilisateur, vous allez donc taper <code>cd Desktop</code> (voir les copies d'écran ci-dessous).</p>
+
+<p><img alt="results of the cd Desktop command being run in a variety of windows terminals - the terminal location moves into the desktop" src="https://mdn.mozillademos.org/files/17182/win-terminals-cd.png" style="border-style: solid; border-width: 1px; display: block; height: 349px; margin: 0px auto; width: 500px;"></p>
+
+<p>Sur un système en langue française, vous trouverez plus fréquemment "Bureau" plutôt que "Desktop". Essayez de taper ceci dans votre terminal système (sur un système en langue anglaise, bien sûr conservez "Desktop") :</p>
+
+<pre class="brush: bash notranslate">cd Bureau</pre>
+
+<p>Si vous voulez revenir au répertoire précédent, utilisez les deux points :</p>
+
+<pre class="brush: bash notranslate">cd ..</pre>
+
+<div class="blockIndicator note">
+<p><strong>Note</strong>: Raccourci vraiment utile sur un terminal, la touche <kbd>tab</kbd> émule la saisie automatique des mots dont vous connaissez l'existence, ce qui vous évite de les taper en entier. Par exemple, après avoir tapé les deux commandes ci-dessus, essayez de taper <code>cd B</code> puis de presser la touche <kbd>tab</kbd> — cela devrait saisir automatiquement le nom de répertoire <code>Bureau</code>, à condition qu'il soit présent dans le répertoire courant. Gardez ceci à l'esprit tout en poursuivant.</p>
+</div>
+
+<p>Si le répertoire que vous visez est placé assez loin dans l'arborisation des fichiers, il vous faut connaître le chemin (on dit souvent path, qui est le terme anglais) pour vous y rendre. Cela devient en général plus facile à mesure que vous vous familiarisez avec la structure de votre système de fichiers, mais si vous n'êtes pas sûr vous pouvez le retrouver en combinant la commande <code>ls</code> avec des clicks dans votre Explorer ou autre gestionnaire graphique de fichiers, ce qui va vous permettre de voir où se trouve le répertoire (ou dossier) cherché par rapport à votre répertoire actuel (= répertoire courant).</p>
+
+<p>Par exemple, si vous vouliez aller dans un dossier nommé <code>src</code>, qui se trouve dans un dossier nommé <code>projet</code>, qui est lui-même sur le <code>Bureau</code>, vous pourriez taper ces trois commandes pour y arriver à partir de votre dossier utilisateur :</p>
+
+<pre class="brush: bash notranslate">cd Bureau
+cd projet
+cd src</pre>
+
+<p>Mais c'est une perte de temps — à la place, vous pouvez taper une seule commande, avec les différents éléments du chemin séparés par des slashes, exactement de la même manière que lorsque vous spécifiez les chemins d'accès à des images ou autres assets en CSS, HTML, ou JavaScript :</p>
+
+<pre class="brush: bash notranslate">cd Bureau/projet/src</pre>
+
+<p>Notez que si vous commencez le chemin par un slash, vous le rendez absolu, par exemple <code>/Utilisateurs/votre-nom/Bureau</code>. Omettre le premier slash comme nous l'avons fait ci-dessus construit un chemin relatif à votre répertoire de travail actuel. C'est exactement la même chose qu'une URL dans un navigateur. Un slash au début signifie "à la racine du site web", alors qu'omettre le slash signifie "l'URL est relative à ma page courante".</p>
+
+<div class="blockIndicator note">
+<p><strong>Note</strong>: Sur windows vous devez utiliser des backslashes et non des slashes, p. ex. <code>cd Bureau\projet\src</code> — cela peut vous paraître vraiment étrange, mais si la question vous intéresse,<a href="https://www.youtube.com/watch?v=5T3IJfBfBmI"> regardez cette vidéo YouTube</a> (en anglais) qui présente une explication par l'un des ingénieurs principaux de Microsoft.</p>
+</div>
+
+<h3 id="Lister_le_contenu_dun_répertoire">Lister le contenu d'un répertoire</h3>
+
+<p><code>ls</code> (de l'anglais list) est la commande intégrée Unix qui va vous permettre de lister le contenu du répertoire dans lequel vous vous trouvez. Notez que cela ne fonctionnera pas avec l'invite de commande par défaut de Windows (<code>cmd</code>) — la commande équivalente est <code>dir</code>.</p>
+
+<p>Essayez de taper ceci dans votre terminal :</p>
+
+<pre class="brush: bash notranslate">ls</pre>
+
+<p>Vous obtenez la liste des fichiers et répertoires de votre répertoire de travail courant, mais l'information est vraiment basique - vous n'avez que les noms des items, sans savoir s'il s'agit d'un fichier, d'un répertoire, ou d'autre chose. Heureusement, une petite modification dans l'utilisation de la commande va vous donner beaucoup plus d'informations.</p>
+
+<h3 id="Présentation_des_options_de_commandes">Présentation des options de commandes</h3>
+
+<p>La plupart des commandes de terminal possèdent des options - ce sont des modificateurs que vous ajoutez à la fin d'une commande pour obtenir un comportement légèrement différent. Il s'agit en général d'un espace suivi d'un tiret puis d'une ou de plusieurs lettres.</p>
+
+<p>Voyez par exemple ce que vous obtenez en essayant ceci :</p>
+
+<pre class="brush: bash notranslate">ls -l </pre>
+
+<p>Avec <code>ls</code>, l'option <code>-l</code> (<em>tiret l, "dash ell</em>" en anglais) vous donne une liste avec un fichier ou répertoire par ligne et pas mal d'autres informations. Les répertoires ("directories") sont repérés pas la lettre "d" au tout début de la ligne. Nous pouvons y entrer avec la commande <code>cd</code>.</p>
+
+<p>Voici ci-dessous une copie d'écran avec un terminal macOS “vanilla” en haut, et en bas un terminal personnalisé avec quelques icônes supplémentaires et des couleurs pour le rendre plus vivant — les deux affichent le résultat de la commande <code>ls -l</code> :</p>
+
+<p><img alt="A vanilla mac terminal and a more colorful custom mac terminal, showing a file listing - the result of running the ls -l command" src="https://mdn.mozillademos.org/files/17181/mac-terminals-ls.png" style="border-style: solid; border-width: 1px; display: block; height: 360px; margin: 0px auto; width: 500px;"></p>
+
+<div class="blockIndicator note">
+<p><strong>Note</strong>: Pour savoir exactement quelles sont les options d'une commande, vous pouvez consulter sa <a href="https://fr.wikipedia.org/wiki/Man_(Unix)">page de manuel</a> (<a href="https://en.wikipedia.org/wiki/Man_page">man page</a> en anglais). Pour cela, tapez la commande <code>man</code> suivie du nom de la commande que vous cherchez, par exemple <code>man ls</code>. La page de manuel va s'ouvrir dans le lecteur de texte par défaut de votre terminal (par exemple, <code><a href="https://en.wikipedia.org/wiki/Less_(Unix)">less</a></code> sur mon terminal), et vous allez pouvoir faire défiler la page avec les touches de flèches ou un mécanisme similaire. La page de manuel liste toutes les options de façon très détaillée, ce qui peut être un peu intimidant au début, mais au moins vous savez où les trouver si vous en avez besoin. Lorsque vous avez terminé avec la page de manuel, vous la refermez avec la commande "quitter" de votre visionneur de texte (pour <code>less</code> c'est "q" ; si ce n'est pas évident cherchez sur Internet).</p>
+</div>
+
+<div class="blockIndicator note">
+<p><strong>Note</strong>: Pour lancer une commande avec des options multiples, on peut en général les regrouper dans une seule chaîne de caractères après le tiret, par exemple <code>ls -lah</code>, ou <code>ls -ltrh</code>. Exercez-vous à consulter la page man de <code>ls</code> pour savoir ce que vous donnent ces options !</p>
+</div>
+
+<p>Maintenant que vous connaissez ces deux commandes fondamentales, allez un peu fouiller dans votre système de fichiers en naviguant à partir de votre répertoire.</p>
+
+<h3 id="Créer_copier_déplacer_supprimer">Créer, copier, déplacer, supprimer</h3>
+
+<p>Il y existe un certain nombre d'autres commandes d'utilité basique dont vous allez probablement pas mal vous servir en travaillant sur un terminal. Elles sont assez simples, aussi nous n'allons pas les expliquer avec autant de détails que les deux précédentes.</p>
+
+<p>Jouez avec elles dans un répertoire que vous aurez créé quelque part de façon à ne pas effacer accidentellement quoi que ce soit d'important, en vous servant des exemples donnés pour vous guider :</p>
+
+<ul>
+ <li><code>mkdir</code> — crée un nouveau répertoire à l'intérieur du répertoire courant. Par exemple, <code>mkdir mon-super-site</code> va créer un nouveau répertoire nommé <code>mon-super-site</code>.</li>
+ <li><code>rmdir</code> — efface le répertoire dont le nom est passé, mais seulement s'il est vide. Par exemple  <code>rmdir mon-super-site</code> va supprimer le répertoire que nous avons créé ci-dessus. Si vous voulez supprimer un répertoire qui n'est pas vide (ainsi que tout ce qu'il contient), vous pouvez utiliser l'option <code>-r</code> (<em>recursive</em>), mais cela est dangereux. Assurez-vous de n'avoir pas besoin plus tard de quelque chose qui se trouverait dans le répertoire, car il aura définitivement disparu.</li>
+ <li><code>touch</code> — crée un nouveau fichier vide dans le répertoire courant. Par exemple, <code>touch mdn-exemple.md</code> crée un fichier vide nommé <code>mdn-exemple.md</code>.</li>
+ <li><code>mv</code> — déplace un fichier à partir de l'emplacement spécifié en premier vers celui spécifié en second, par exemple <code>mv mdn-exemple.md mdn-exemple.txt</code> (les emplacements sont écrits sous la forme de chemins - <em>file paths</em>). Cette commande déplace un fichier nommé <code>mdn-exemple.md</code> situé dans le répertoire courant vers une fichier nommé <code>mdn-exemple.txt</code> dans le répertoire courant. Techniquement, le fichier est déplacé, mais d'un point de vue pratique, cette commande renomme en fait le fichier.</li>
+ <li><code>cp</code> — d'un usage similaire à <code>mv</code>, <code>cp</code> copie le fichier à l'emplacement spécifié en premier vers celui spécifié en second. Par exemple, <code>cp mdn-exemple.txt mdn-exemple.txt.bak</code> crée une copie de <code>mdn-exemple.txt</code> nommée <code>mdn-exemple.txt.bak</code> (bien entendu vous pouvez la nommer comme vous voulez).</li>
+ <li><code>rm</code> — supprimer le fichier spécifié. Par exemple, <code>rm mdn-exemple.txt</code> efface un fichier unique nommé <code>mdn-exemple.txt</code>. Notez que cet effacement est permanent et ne peut pas être annulé comme lorsque vous placez un fichier dans la corbeille de votre Bureau dans votre interface utilisateur.</li>
+</ul>
+
+<div class="blockIndicator note">
+<p><strong>Note</strong> : Beaucoup de commandes de terminal autorisent l'emploi d'astérisques comme caractère "joker", dont le sens est "une séquence de caractères quelconque". Cela vous permet d'exécuter une commande en une seule fois sur un nombre potentiellement important de fichiers qui correspondent au modèle donné. À titre d'exemple, <code>rm mdn-*</code> va effacer tous les fichiers qui commencent par <code>mdn-</code>. <code>rm mdn-*.bak</code> va effacer tous les fichiers qui commencent par <code>mdn- </code>et finissent par <code>.bak</code>.</p>
+</div>
+
+<h2 id="Le_terminal_—_une_pratique_à_risque">Le terminal — une pratique à risque ?</h2>
+
+<p>Nous y avons déjà fait allusion, et soyons clairs - travailler sur terminal demande de la prudence. Des commandes simples ne présentent pas trop de risques, mais dès que vous commencez à combiner des commandes plus complexes, il vous faut réfléchir soigneusement à ce qu'elle va exécuter, et essayer de la tester avant de la lancer effectivement dans le répertoire voulu.</p>
+
+<p>Supposons que vous ayez 1000 fichiers texte dans un répertoire, et que vous vouliez les parcourir en supprimant uniquement ceux dont le nom comprend une certaine chaîne de caractères. Si vous ne faites pas attention, vous risquez d'effacer quelque chose d'important et de perdre du coup une somme de travail. Une bonne habitude à prendre consiste à écrire votre ligne de commande dans un éditeur de texte, à la construire à votre idée, et ensuite à faire une copie de sauvegarde de votre répertoire avant d'essayer la commande sur celui-ci.</p>
+
+<p>Autre astuce intéressante : si vous n'êtes pas à l'aise avec l'idée d'essayer des lignes de commande sur votre propre machine, le site <a href="https://glitch.com/">Glitch.com</a> est un bon endroit pour le faire en toute sécurité. En plus d'être un lieu génial pour tester du code de développement web, les projets vous donnent accès à un terminal qui vous permet de lancer toutes les commandes que vous voulez, sans risquer d'endommager votre propre machine.</p>
+
+<p><img alt="a double screenshot showing the glitch.com home page, and the glitch terminal emulator" src="https://mdn.mozillademos.org/files/17179/glitch.png" style="height: 848px; width: 900px;"></p>
+
+<p>Le site <a href="https://tldr.sh/">tldr.sh</a> est une formidable ressource pour obtenir un aperçu de commandes particulières. C'est un service de documentation géré de façon communautaire, similaire à MDN, mais dédié aux commandes de terminal.</p>
+
+<p>Dans la section suivante, nous allons monter d'un cran (et même de plusieurs), et voir comment nous pouvons combiner plusieurs outils en ligne de commande pour révéler toute la puissance du terminal par rapport à l'interface graphique habituelle.</p>
+
+<h2 id="Combiner_des_commandes_grâce_aux_pipes">Combiner des commandes grâce aux "pipes"</h2>
+
+<p>L'usage du terminal prend toute sa valeur lorsque vous commencez à chaîner les commandes en utilisant le symbole <code>|</code> ("pipe" ou "tuyau" en français). Voyons comment on peut faire cela sur un exemple très rapide.</p>
+
+<p>Nous avons déjà vu <code>ls</code>, qui liste le contenu du répertoire courant :</p>
+
+<pre class="brush: bash notranslate">ls</pre>
+
+<p>Mais comment nous y prendre si nous voulons compter le nombre de fichiers et de répertoires à l'intérieur du répertoire courant ? <code>ls</code> n'est pas capable de faire cela à lui seul.</p>
+
+<p>Il existe un autre outil Unix nommé <code>wc</code>. Celui-ci compte les mots, lignes, caractères, ou octets de la donnée qu'on lui passe, quelle qu'elle soit. Il peut s'agir d'un fichier texte — l'exemple ci-dessous donne le nombre de lignes de <code>monfichier.txt</code> :</p>
+
+<pre class="brush: bash notranslate">wc -l monfichier.txt</pre>
+
+<p>Mais <code>wc</code> est également capable de compter les lignes de tout ce qui lui est passé par un <strong>pipe</strong>. Par exemple, la commande ci-dessous compte les lignes renvoyées par la commande <code>ls</code>  (lignes qui seraient normalement affichées sur le terminal) et affiche ce décompte à la place :</p>
+
+<pre class="brush: bash notranslate">ls | wc -l</pre>
+
+<p>Comme <code>ls</code> affiche chaque fichier ou répertoire sur une nouvelle ligne, on obtient bien le compte des répertoires et des fichiers.</p>
+
+<p>Comment ça marche ? Le comportement général des outils de ligne de commande (unix) consiste à afficher du texte dans le terminal (ce qu'on appelle aussi "imprimer sur la sortie standard (standard input)" ou  <code>STDOUT</code>). Un bon nombre de commandes peuvent aussi lire du contenu à partir d'un flux d'entrée (appelé "entrée standard (standard input)" ou <code>STDIN</code>).</p>
+
+<p>L'opérateur pipe peut <em>connecter</em> ces entrées et sorties, ce qui nous permet de construire des opérations de plus en plus complexes selon nos besoins — la sortie d'une commande devient l'entrée de la commande suivante. Dans le cas présent, <code>ls</code> enverrait normalement sa sortie sur <code>STDOUT</code>, mais au lieu de cela la sortie de <code>ls</code> est passée par un pipe à <code>wc</code>, qui la prend en entrée, compte ses lignes et imprime ce décompte sur <code>STDOUT</code>.</p>
+
+<h2 id="Un_exemple_un_peu_plus_complexe">Un exemple un peu plus complexe</h2>
+
+<p>Occupons-nous maintenant de quelque chose d'un peu plus compliqué. Nous allons d'abord essayer de récupérer le contenu de la page MDN "fetch" en utilisant la commande <code>curl</code>  (dont on peut se servir pour faire une requête de contenu à partir d'URLs), sur <a href="https://developer.mozilla.org/en-US/docs/Web/API/fetch">https://developer.mozilla.org/en-US/docs/Web/API/fetch</a>.</p>
+
+<p>En fait, cette URL est celle de l'ancien emplacement de la page. Lorsque vous l'entrez dans un nouvel onglet de votre navigateur, vous êtes (finalement) redirigé sur <a href="https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch">https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch</a>.</p>
+
+<p>Par conséquent, si vous utilisez curl pour faire une requête à https://developer.mozilla.org/docs/Web/API/fetch, vous n'aurez pas de résultat. Essayez :</p>
+
+<pre class="brush: bash notranslate">curl https://developer.mozilla.org/en-US/docs/Web/API/fetch</pre>
+
+<p>Nous devons dire explicitement à <code>curl</code> de suivre les redirections en utilisant l'option <code>-L</code>.</p>
+
+<p>Examinons également les en-têtes retournées par <code>developer.mozilla.org</code> en utilisant l'option <code>-I</code> de <code>curl</code>, et affichons toutes les redirections en passant la sortie de <code>curl</code> à <code>grep</code> grâce à un pipe (on va demander à <code>grep</code> de renvoyer toutes les lignes qui contiennent le mot "location").</p>
+
+<p>Essayez maintenant la ligne suivante, et vous allez constater qu'il y a en fait trois redirections avant d'atteindre la page finale :</p>
+
+<pre class="brush: bash notranslate">curl https://developer.mozilla.org/docs/Web/API/fetch -L -I | grep location</pre>
+
+<p>Votre sortie devrait ressembler à ceci (<code>curl</code> va d'abord afficher des compteurs et autres informations de téléchargement) :</p>
+
+<pre class="brush: bash notranslate">location: /en-US/docs/Web/API/fetch
+location: /en-US/docs/Web/API/GlobalFetch/GlobalFetch.fetch()
+location: /en-US/docs/Web/API/GlobalFetch/fetch
+location: /en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch</pre>
+
+<p>Bien que ce résultat soit artificiel, nous pourrions le pousser un peu plus loin et remplacer <code>location:</code> par le nom de domaine, de façon à avoir des URLs complètes. Pour cela, nous allons ajouter <code>awk</code> à notre formule (il s'agit d'un langage de programmation tout comme JavaScript, Ruby ou Python, mais beaucoup plus ancien !).</p>
+
+<p>Essayez de lancer cette commande :</p>
+
+<pre class="brush: bash notranslate">curl https://developer.mozilla.org/docs/Web/API/fetch -L -I | grep location | awk '{ print "https://developer.mozilla.org" $2 }'</pre>
+
+<p>Votre sortie finale devrait ressembler à ceci :</p>
+
+<pre class="brush: bash notranslate">https://developer.mozilla.org/en-US/docs/Web/API/fetch
+https://developer.mozilla.org/en-US/docs/Web/API/GlobalFetch/GlobalFetch.fetch()
+https://developer.mozilla.org/en-US/docs/Web/API/GlobalFetch/fetch
+https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch</pre>
+
+<p>En combinant ces commandes nous avons personnalisé la sortie pour qu'elle montre les URLs complètes vers lesquels le serveur de Mozilla effectue les redirections lorsque nous lui soumettons la requête pour l'URL <code>/docs/Web/API/fetch</code>.<br>
+ Développer votre connaissance du système en apprenant le fonctionnement de ces simples outils et comment les intégrer à votre arsenal pour résoudre des problèmes bien particuliers - cela vous sera d'une grande utilité tout au long des années à venir.</p>
+
+<h2 id="Ajoutez_des_super-pouvoirs_!">Ajoutez des super-pouvoirs !</h2>
+
+<p>À présent que nous avons jeté un œil à quelques-unes des commandes intégrées dont votre système est pré-équipé, voyons comment installer un outil tiers de CLI et nous en servir.</p>
+
+<p>La plus grande partie du vaste écosystème d'outils installables pour le développement web front-end se trouve sous <a href="https://www.npmjs.com">npm</a>, un service privé d'hébergement de packages qui fonctionne en étroite interaction avec Node.js. Celui-ci se développe peu à peu — vous pouvez vous attendre à davantage de fournisseurs de packages avec le temps.</p>
+
+<p><a href="https://nodejs.org/fr/">L'installation de Node.js</a> installe en même temps l'outil de ligne de commande npm (ainsi que npx, un outil supplémentaire centré sur npm), qui est la porte d'entrée pour l'installation d'outils de ligne de commande additionnels. Node.js et npm fonctionnent de la même façon sur tous les systèmes : macOS, Windows, ainsi que Linux.</p>
+
+<p>Allons-y : installez npm sur votre système à partir de l'URL ci-dessus qui va vous permettre de télécharger et de lancer un installeur Node.js approprié à votre système d'exploitation. Si cela vous est proposé, assurez-vous d'inclure npm dans l'installation.</p>
+
+<p><img alt="the node.js installer on windows, showing the option to include npm" src="https://mdn.mozillademos.org/files/17185/npm-install-option.png" style="border-style: solid; border-width: 1px; display: block; height: 469px; margin: 0px auto; width: 600px;"></p>
+
+<p>Un certain nombre d'outils variés vous attendent dans le prochaine article ; pour l'instant nous allons nous faire la main sur <a href="https://prettier.io/">Prettier</a>. Prettier est un outil de formatage de code normatif qui se présente comme ayant "peu d'options". Moins d'options, cela évoque plus de simplicité. Vu comme on peut parfois être débordé par la complexité de certains outils, le concept  "peu d'options" peut se révéler très attractif.</p>
+
+<h3 id="Où_installer_nos_outils_de_CLI">Où installer nos outils de CLI ?</h3>
+
+<p>Avant de nous lancer dans l'installation de Prettier, une question se pose — "où allons-nous l'installer ?"</p>
+
+<p><code>npm</code> nous donne le choix entre une installation globale — ce qui nous permet d'y avoir accès de n'importe où — ou bien locale, dans le dossier du projet en cours.</p>
+
+<p>Il y a des pour et des contre pour les deux options — la liste ci-dessous est loin d'être exhaustive:</p>
+
+<table class="standard-table">
+ <thead>
+ <tr>
+ <th scope="col">Pour l'installation globale</th>
+ <th scope="col">Contre l'installation globale</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>Accessible partout dans votre terminal</td>
+ <td>Peut ne pas être compatible avec votre codebase.</td>
+ </tr>
+ <tr>
+ <td>Installation en une fois</td>
+ <td>Les autres développeurs de votre équipe n'auront pas accès à ces outils, par exemple si vous partagez votre codebase sur un outil comme git.</td>
+ </tr>
+ <tr>
+ <td>Moins d'espace disque</td>
+ <td>En lien avec le point précédent, rend le code du projet plus difficile à répliquer (si vous installez vos outils en local, ils peuvent être configurés comme des dépendances et installés avec <code>npm install</code>).</td>
+ </tr>
+ <tr>
+ <td>Stabilité de la version</td>
+ <td></td>
+ </tr>
+ <tr>
+ <td>Donne l'impression d'être une commande unix comme les autres</td>
+ <td></td>
+ </tr>
+ </tbody>
+</table>
+
+<p>Bien que la liste des <em>contre </em>soit plus courte, l'impact négatif d'une installation globale est potentiellement beaucoup plus lourd que les bénéfices. Cela dit, pour l'instant, nous allons choisir l'installation globale dans un but de simplicité. Nous examinerons davantage les installations locales et leur intérêt dans notre prochain article.</p>
+
+<h3 id="Installation_de_Prettier">Installation de Prettier</h3>
+
+<p>Dans cette partie nous allons installer Prettier en tant qu'utilitaire global de ligne de commande.</p>
+
+<p>Prettier est un outil de formatage de code normatif pour les développeurs front-end, centré sur le langage JavaScript et ses dérivés, avec un support pour HTML, CSS, SCSS, JSON et plus.</p>
+
+<p>Prettier offre les avantages suivants :</p>
+
+<ul>
+ <li>Il épargne la surcharge cognitive que représente le maintien manuel d'une cohérence de style au travers de l'ensemble de vos fichiers de code, en le faisant automatiquement à votre place.</li>
+ <li>Il aide les débutants en développement web à formater leur code selon les bonnes pratiques.</li>
+ <li>Il peut s'installer sur tout système d'exploitation et même comme partie intégrante des outils du projet, de sorte que les collègues et amis qui travaillent sur votre code utilisent le même style que vous.</li>
+ <li>On le peut le configurer pour qu'il s'exécute à la sauvegarde, en cours de frappe, ou encore au moment de publier votre code (grâce à des outils supplémentaires que nous verrons plus loin dans ce module).</li>
+</ul>
+
+<p>Après avoir installé node, ouvrez votre terminal et lancez les commandes suivantes pour installer Prettier :</p>
+
+<pre class="brush: bash notranslate">npm install --global prettier</pre>
+
+<p>Lorsque la commande a terminé son exécution, l'outil Prettier est disponible sur sur votre terminal, partout dans votre système de fichiers.</p>
+
+<p>En lançant la commande sans argument, comme pour beaucoup d'autres commandes, vous obtiendrez les informations d'utilisation et d'aide. Essayez :</p>
+
+<pre class="brush: bash notranslate">prettier</pre>
+
+<p>La sortie devrait ressembler à ceci :</p>
+
+<pre class="brush: bash notranslate">Usage: prettier [options] [file/glob ...]
+
+By default, output is written to stdout.
+Stdin is read if it is piped to Prettier and no files are given.
+
+…</pre>
+
+<p>Cela vaut toujours la peine d'au moins survoler les informations sur l'utilisation, même lorsqu'elles sont longues. Vous pourrez ainsi mieux comprendre à quoi l'outil est censé servir.</p>
+
+<h3 id="Un_peu_de_pratique">Un peu de pratique</h3>
+
+<p>Jouons un peu avec Prettier pour que vous puissiez voir comment il fonctionne.</p>
+
+<p>Tout d'abord, créez un nouveau répertoire à un endroit que vous pourrez retrouver facilement, par exemple un répertoire nommé <code>prettier-test</code> sur votre <code>Bureau</code>.</p>
+
+<p>Ensuite collez le code suivant dans un fichier que vous enregistrez dans ce répertoire sous le nom <code>index.js.</code></p>
+
+<pre class="brush: js notranslate">const myObj = {
+a:1,b:{c:2}}
+function printMe(obj){console.log(obj.b.c)}
+printMe(myObj)</pre>
+
+<p>Nous pouvons exécuter prettier sur un code source simplement pour vérifier s'il nécessite une correction. Passez dans votre répertoire avec <code>cd</code> et essayez de lancer cette commande :</p>
+
+<pre class="brush: bash notranslate">prettier --check index.js</pre>
+
+<p>Vous devriez obtenir quelque chose comme</p>
+
+<pre class="brush: bash notranslate">Checking formatting...
+index.js
+Code style issues found in the above file(s). Forgot to run Prettier?
+</pre>
+
+<p>Le style nécessite donc des corrections. Pas de problème. On va les appliquer en ajoutant l'option <code>--write</code> à la commande prettier, ce qui nous laisse nous concentrer sur l'aspect utile de l'écriture du code.</p>
+
+<p>Essayez maintenant de lancer cette version de la commande :</p>
+
+<pre class="brush: bash notranslate">prettier --write index.js</pre>
+
+<p>La sortie ressemble maintenant à ceci</p>
+
+<pre class="brush: bash notranslate">Checking formatting...
+index.js
+Code style issues fixed in the above file(s).</pre>
+
+<p>Mais le plus important, c'est que votre fichier JavaScript a été reformaté :</p>
+
+<pre class="brush: js notranslate">const myObj = {
+ a: 1,
+ b: { c: 2 },
+};
+function printMe(obj) {
+ console.log(obj.b.c);
+}
+printMe(myObj);</pre>
+
+<p>Vous pouvez intégrer cette opération automatisée à votre workflow. L'intérêt des outils réside justement dans l'automatisation ; personnellement, notre préférence va  au type d'automatisme qui se produit de façon transparente, sans qu'aucune configuration soit nécessaire.</p>
+
+<p>Il existe de nombreuses façons de mettre en oeuvre des automatismes avec Prettier, et bien qu'elles dépassent le cadre de cet article, vous trouverez de l'aide dans d'excellentes ressources en ligne, dont certaines grâce aux liens ci-après. Vous pouvez lancer prettier :</p>
+
+<ul>
+ <li>Avant de faire un commit sur un dépôt git en utilisant <a href="https://github.com/typicode/husky">Husky</a>.</li>
+ <li>Chaque fois que vous cliquez sur "sauvegarder" dans votre éditeur de code, qu'il s'agisse de <a href="https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode">VS Code</a>, d'<a href="https://atom.io/packages/prettier-atom">Atom</a>, ou de <a href="https://packagecontrol.io/packages/JsPrettier">Sublime Text</a>.</li>
+ <li>En tant qu'élément des contrôles continus d'intégration grâce à des outils tels que <a href="https://github.com/features/actions">Github Actions</a>.</li>
+</ul>
+
+<p>Nous préférons personnellement la deuxième solution — quand on code par exemple sur VS Code, Prettier entre en jeu et nettoie le formatage lors de chaque  enregistrement. Vous trouverez dans les<span> </span><a href="https://prettier.io/docs/en/">Prettier docs</a><span> </span><span>beaucoup plus d'informations sur les différentes façons d'utiliser Prettier.</span></p>
+
+<h2 id="Autres_outils_à_essayer">Autres outils à essayer</h2>
+
+<p>Voici une courte liste de quelques outils supplémentaires que vous pouvez vous amuser à tester :</p>
+
+<ul>
+ <li><code><a href="https://github.com/sharkdp/bat">bat</a></code> — Un <code>cat</code>  plus "beau" (<code>cat</code> affiche le contenu d'un fichier)<em> (NdT : probable jeu de mot en anglais, où cat = chat et bat = chauve-souris)</em>.</li>
+ <li><code><a href="http://denilson.sa.nom.br/prettyping/">prettyping</a></code> — implémentation visuellement améliorée de la commande <code>ping</code> (<code>ping</code> permet de tester si un serveur répond).</li>
+ <li><code><a href="http://hisham.hm/htop/">htop</a></code> — Pour visualiser les processus en cours, ce qui est intéressant lorsque votre ventilateur de CPU se met à faire un bruit de moteur d'avion et que vous souhaitez identifier le programme responsable.</li>
+ <li><code><a href="https://tldr.sh/#installation">tldr</a></code> — client tldr (mentionné plus haut dans ce chapitre) en ligne de commande.</li>
+</ul>
+
+<p>L'auteur a aussi <a href="https://remysharp.com/2018/08/23/cli-improved">décrit certains de ses favoris</a> accompagnés de copies d'écrans si vous avez envie de creuser davantage le sujet.</p>
+
+<p>Notez que certains de ces outils nécessitent l'installation préalable de npm, ainsi que nous l'avons fait pour Prettier.</p>
+
+<h2 id="Résumé">Résumé</h2>
+
+<p>Nous voilà parvenus au terme de cette brève revue du terminal ou ligne de commande. Dans la suite, nous allons nous pencher plus en détail sur les package managers, et sur les possibilités qu'ils nous offrent.</p>
+
+<p>{{PreviousMenuNext("Learn/Tools_and_testing/Understanding_client-side_tools/Overview","Learn/Tools_and_testing/Understanding_client-side_tools/Package_management", "Learn/Tools_and_testing/Understanding_client-side_tools")}}</p>
+
+<h2 id="Dans_ce_module">Dans ce module</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Overview">Client-side tooling overview</a></li>
+ <li><a href="https://wiki.developer.mozilla.org/fr/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Ligne_de_commande">Cours express sur la ligne de commande</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Package_management">Package management basics</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Introducing_complete_toolchain">Introducing a complete toolchain</a></li>
+ <li><a href="/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Deployment">Deploying our app</a></li>
+</ul>