From 57469bf4ff5418e48a73ed04048e866d6b191995 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phaneDucasse?= Date: Mon, 26 Aug 2024 14:17:11 +0200 Subject: [PATCH] doing a simple pass looking for a glitch --- ...hap06-TinyBlog-SeasideUserComponents-FR.md | 36 +++++++++---------- .../Chap07-TinyBlog-Authentification-FR.md | 26 +++++++------- Chapters/Chap08-TinyBlog-Admin-FR.md | 26 +++++++------- Chapters/Chap09-TinyBlog-SeasideREST-FR.md | 32 ++++++++--------- Chapters/Chap11-TinyBlog-Mustache-FR.md | 2 +- Chapters/Chap12-TinyBlog-Export-FR.md | 12 +++---- Chapters/Chap14-TinyBlog-Loading-FR.md | 8 ++--- Chapters/Chap15-TinyBlog-SavingCode-FR.md | 2 +- _support/templates/latex/main.mustache | 4 +-- 9 files changed, 74 insertions(+), 74 deletions(-) diff --git a/Chapters/Chap06-TinyBlog-SeasideUserComponents-FR.md b/Chapters/Chap06-TinyBlog-SeasideUserComponents-FR.md index 57c85a2..dd21167 100644 --- a/Chapters/Chap06-TinyBlog-SeasideUserComponents-FR.md +++ b/Chapters/Chap06-TinyBlog-SeasideUserComponents-FR.md @@ -1,11 +1,11 @@ ## Des composants web pour TinyBlog -Dans ce chapitre, commençons par définir une interface publique permettant d'afficher les bulletins \(posts\) du blog. Nous raffinons cela dans le chapitre suivant. +Dans ce chapitre, commençons par définir une interface publique permettant d'afficher les bulletins (posts) du blog. Nous raffinons cela dans le chapitre suivant. Si vous avez le sentiment d'être un peu perdu, la figure *@ApplicationArchitectureUserWithoutCategory@* vous montre les composants sur lesquels nous allons travailler dans ce chapitre. -![L'architecture des composants utilisateurs \(par opposition à administration\).](figures/ApplicationArchitectureUserWithoutCategory.pdf width=75&label=ApplicationArchitectureUserWithoutCategory) +![L'architecture des composants utilisateurs (par opposition à administration).](figures/ApplicationArchitectureUserWithoutCategory.pdf width=75&label=ApplicationArchitectureUserWithoutCategory) Le travail présenté dans la suite est indépendant de celui sur Voyage et sur la base de données MongoDB. Les instructions pour charger le code des chapitres précédents sont disponibles dans le chapitre *@cha:loading@*. @@ -30,7 +30,7 @@ WAComponent subclass: #TBScreenComponent ``` -Les différents composants d'interface de TinyBlog ont besoin d'accéder aux règles métier de l'application. Dans le protocole 'accessing', créons une méthode `blog` qui retourne une instance de `TBBlog` \(ici notre singleton\). Notez que cette méthode pourrait renvoyer l'instance de blog avec laquelle elle a été configurée au préalable. +Les différents composants d'interface de TinyBlog ont besoin d'accéder aux règles métier de l'application. Dans le protocole 'accessing', créons une méthode `blog` qui retourne une instance de `TBBlog` (ici notre singleton). Notez que cette méthode pourrait renvoyer l'instance de blog avec laquelle elle a été configurée au préalable. ``` TBScreenComponent >> blog @@ -40,7 +40,7 @@ TBScreenComponent >> blog ``` -Par la suite, si l'on souhaite étendre TinyBlog pour qu'un utilisateur puisse avoir plusieurs blogs, il suffira de modifier cette méthode pour utiliser des informations stockées dans la session active \(Voir `TBSession` dans le chapitre suivant\). +Par la suite, si l'on souhaite étendre TinyBlog pour qu'un utilisateur puisse avoir plusieurs blogs, il suffira de modifier cette méthode pour utiliser des informations stockées dans la session active (Voir `TBSession` dans le chapitre suivant). Définissez la méthode `renderContentOn:` de ce composant comme suit temporairement. Notez que pour l'instant, nous n'affichons pas ce composant donc rafraichir votre browser ne vous montre rien de nouveau et c'est normal. @@ -92,7 +92,7 @@ TBApplicationRootComponent >> children ``` -Si vous rafraichissez votre browser, vous allez voir l'affichage produit par le sous-composant `TBScreenComponent` qui affiche pour l'instant le texte: `Hello from TBScreenComponent` \(voir la figure *@fig:Hello@*\). +Si vous rafraichissez votre browser, vous allez voir l'affichage produit par le sous-composant `TBScreenComponent` qui affiche pour l'instant le texte: `Hello from TBScreenComponent` (voir la figure *@fig:Hello@*). ![Premier visuel du composant `TBScreenComponent`.](figures/HelloFromScreenComponent.png width=75&label=fig:Hello) @@ -126,7 +126,7 @@ TBBlog createDemoPosts Définissons une en-tête commune à toutes les pages de TinyBlog dans un composant nommé `TBHeaderComponent`. -Ce composant sera inséré dans la partie supérieure de chaque composant \(`TBPostsListComponent` par exemple\). Nous appliquons le schéma décrit ci-dessus: définition d'une classe, référence depuis la classe utilisatrice, et redéfinition de la méthode `children`. +Ce composant sera inséré dans la partie supérieure de chaque composant (`TBPostsListComponent` par exemple). Nous appliquons le schéma décrit ci-dessus: définition d'une classe, référence depuis la classe utilisatrice, et redéfinition de la méthode `children`. Nous définissons d'abord sa classe, puis nous allons y faire référence depuis la classe qui l'utilise. Ce faisant, nous allons montrer comment un composant exprime sa relation à un sous-composant. @@ -143,7 +143,7 @@ WAComponent subclass: #TBHeaderComponent Complétons maintenant la classe `TBScreenComponent` afin qu'elle affiche une instance de `TBHeaderComponent`. -Pour rappel, `TBScreenComponent` est la super-classe abstraite \(nous l'utilisons directement pour l'instant\) de tous nos composants dans l'architecture finale. Cela signifie que toutes les sous-classes de `TBScreenComponent` seront des composants avec une en-tête. +Pour rappel, `TBScreenComponent` est la super-classe abstraite (nous l'utilisons directement pour l'instant) de tous nos composants dans l'architecture finale. Cela signifie que toutes les sous-classes de `TBScreenComponent` seront des composants avec une en-tête. Pour éviter d'instancier systématiquement le composant `TBHeaderComponent` à chaque fois qu'un composant est appelé, créons et initialisons une variable d'instance `header` dans `TBScreenComponent`. ``` @@ -174,7 +174,7 @@ Notez que nous avons une méthode spécifique pour créer le composant en-tête. ### Relation composite-composant -En Seaside, les sous-composants d'un composant doivent être retournés par le composite en réponse au message `children`. Définissons que l'instance du composant `TBHeaderComponent` est un enfant de `TBScreenComponent` dans la hiérarchie des composants Seaside \(et non entre classes Pharo\). Dans cet exemple, nous spécialisons la méthode `children` pour qu'elle retourne une collection contenant un seul élément qui est l'instance de `TBHeaderComponent` référencée depuis la variable `header`. +En Seaside, les sous-composants d'un composant doivent être retournés par le composite en réponse au message `children`. Définissons que l'instance du composant `TBHeaderComponent` est un enfant de `TBScreenComponent` dans la hiérarchie des composants Seaside (et non entre classes Pharo). Dans cet exemple, nous spécialisons la méthode `children` pour qu'elle retourne une collection contenant un seul élément qui est l'instance de `TBHeaderComponent` référencée depuis la variable `header`. ``` TBScreenComponent >> children @@ -185,7 +185,7 @@ TBScreenComponent >> children ### Rendu visuel de la barre de navigation -Affichons maintenant le composant dans la méthode `renderContentOn:` \(protocole 'rendering'\) : +Affichons maintenant le composant dans la méthode `renderContentOn:` (protocole 'rendering') : ``` TBScreenComponent >> renderContentOn: html @@ -214,12 +214,12 @@ TBHeaderComponent >> renderBrandOn: html ``` -L'en-tête \(header\) est affichée à l'aide d'une barre de navigation Bootstrap. +L'en-tête (header) est affichée à l'aide d'une barre de navigation Bootstrap. Si vous faites un rafraichissement de l'application dans votre navigateur web vous devez voir apparaitre l'en-tête comme sur la figure *@navBlog@*. ![TinyBlog avec une barre de navigation.](figures/navBlog.png width=75&label=navBlog) -Par défaut dans une barre de navigation Bootstrap, il y a un lien sur le titre de l'application \(`tbsNavbarBrand` \) qui permet de revenir à la page de départ du site. +Par défaut dans une barre de navigation Bootstrap, il y a un lien sur le titre de l'application (`tbsNavbarBrand` ) qui permet de revenir à la page de départ du site. #### Améliorations possibles @@ -229,9 +229,9 @@ Le nom du blog devrait être paramétrable à l'aide d'une variable d'instance d ### Liste des posts -Créons un composant `TBPostsListComponent` pour afficher la liste des bulletins \(posts\) - ce qui reste d'ailleurs le but d'un blog. Ce composant constitue la partie publique du blog offerte aux lecteurs du blog. +Créons un composant `TBPostsListComponent` pour afficher la liste des bulletins (posts) - ce qui reste d'ailleurs le but d'un blog. Ce composant constitue la partie publique du blog offerte aux lecteurs du blog. -Pour cela, définissons une sous-classe de `TBScreenComponent` \(comme illustré dans la figure *@compt2@*\): +Pour cela, définissons une sous-classe de `TBScreenComponent` (comme illustré dans la figure *@compt2@*): ``` TBScreenComponent subclass: #TBPostsListComponent @@ -244,7 +244,7 @@ TBScreenComponent subclass: #TBPostsListComponent ![Le composant `ApplicationRootComponent` utilise le composant `PostsListComponent`.](figures/ComponentRelationship2.pdf width=75&label=compt2) -Nous pouvons maintenant modifier le composant principal de l'application \(`TBApplicationRootComponent`\) pour qu'il affiche ce nouveau composant. Pour cela nous modifions sa méthode `initialize` ainsi: +Nous pouvons maintenant modifier le composant principal de l'application (`TBApplicationRootComponent`) pour qu'il affiche ce nouveau composant. Pour cela nous modifions sa méthode `initialize` ainsi: ``` TBApplicationRootComponent >> initialize @@ -253,7 +253,7 @@ TBApplicationRootComponent >> initialize ``` -Ajoutons également une méthode setter \(`main:`\) qui nous permettra par la suite, de changer dynamiquement le sous-composant à afficher tout en gardant le composant actuel \(instance de `TBPostsListComponent`\) par défaut. +Ajoutons également une méthode setter (`main:`) qui nous permettra par la suite, de changer dynamiquement le sous-composant à afficher tout en gardant le composant actuel (instance de `TBPostsListComponent`) par défaut. ``` TBApplicationRootComponent >> main: aComponent @@ -262,7 +262,7 @@ TBApplicationRootComponent >> main: aComponent -Ajoutons une méthode `renderContentOn:` \(protocole rendering\) provisoire pour tester l'avancement de notre application \(voir figure *@elementary@*\). Notez que cette méthode fait un appel à la méthode `renderContentOn:` de la super-classe qui va afficher le composant en-tête. +Ajoutons une méthode `renderContentOn:` (protocole rendering) provisoire pour tester l'avancement de notre application (voir figure *@elementary@*). Notez que cette méthode fait un appel à la méthode `renderContentOn:` de la super-classe qui va afficher le composant en-tête. ``` TBPostsListComponent >> renderContentOn: html @@ -280,7 +280,7 @@ Si vous rafraichissez la page de TinyBlog dans votre navigateur, vous devriez ob ### Le composant Post -Nous allons maintenant définir le composant `TBPostComponent` qui affiche le contenu d'un bulletin \(post\). +Nous allons maintenant définir le composant `TBPostComponent` qui affiche le contenu d'un bulletin (post). Chaque bulletin du blog sera représenté visuellement par une instance de `TBPostComponent` qui affiche le titre, la date et le contenu d'un bulletin. Nous allons obtenir la situation décrite par la figure *@compt3@*. @@ -343,7 +343,7 @@ TBPostComponent >> renderContentOn: html -### Afficher les bulletins \(posts\) +### Afficher les bulletins (posts) Il ne reste plus qu'à modifier la méthode `renderContentOn:` de la classe `TBPostsListComponent` pour afficher l'ensemble des bulletins visibles présents dans la base. diff --git a/Chapters/Chap07-TinyBlog-Authentification-FR.md b/Chapters/Chap07-TinyBlog-Authentification-FR.md index 72ae05a..dfc1c9b 100644 --- a/Chapters/Chap07-TinyBlog-Authentification-FR.md +++ b/Chapters/Chap07-TinyBlog-Authentification-FR.md @@ -8,7 +8,7 @@ La figure *@ApplicationArchitectureAdminHeader@* montre un aperçu de l'architec ![Gérant l'authentification pour accéder à l'administration.](figures/ApplicationArchitectureAdminHeader.pdf width=75&label=ApplicationArchitectureAdminHeader) Nous commençons par mettre en place une première version permettant de naviguer entre la partie publique TinyBlog rendue par le composant -gérant la liste des bulletins \(`TBPostsListComponent`\) et une première version de la partie d'administration du site comme sur la figure *@SimpleAdminLink@*. +gérant la liste des bulletins (`TBPostsListComponent`) et une première version de la partie d'administration du site comme sur la figure *@SimpleAdminLink@*. Cela va nous permettre d'illustrer l'invocation de composant. Nous intègrerons ensuite un composant d'identification sous la forme d'une boîte modale. @@ -16,7 +16,7 @@ Cela va nous permettre d'illustrer comment la saisie de champs utilise de maniè Enfin, nous montrerons aussi comment stocker l'utilisateur connecté dans la session courante. -### Composant d'administration simple \(v1\) +### Composant d'administration simple (v1) Définissons un composant d'administration très simple. Ce composant hérite de la classe `TBScreenComponent` comme mentionné dans un chapitre précédent et illustré dans la figure *@ApplicationArchitectureAdminHeader@*. @@ -43,8 +43,8 @@ TBAdminComponent >> renderContentOn: html ### Ajout d'un bouton 'admin' -Ajoutons maintenant un bouton dans l'en-tête du site \(composant `TBHeaderComponent`\) afin d'accéder à la partie administration du site comme sur la figure *@SimpleAdminLink@*. -Pour cela, modifions les composants existants: `TBHeaderComponent` \(en-tête\) et `TBPostsListComponent` \(partie publique\). +Ajoutons maintenant un bouton dans l'en-tête du site (composant `TBHeaderComponent`) afin d'accéder à la partie administration du site comme sur la figure *@SimpleAdminLink@*. +Pour cela, modifions les composants existants: `TBHeaderComponent` (en-tête) et `TBPostsListComponent` (partie publique). ![Lien simple vers la partie administration.](figures/SimpleAdminLink.png width=100&label=SimpleAdminLink) @@ -77,15 +77,15 @@ TBHeaderComponent >> renderSimpleAdminButtonOn: html ``` -Si vous rafraichissez votre navigateur, le bouton admin est bien présent mais il n'a aucun effet pour l'instant \(voir la figure *@withAdminView1@*\). -Il faut définir un `callback:` sur ce bouton \(un bloc\) qui remplace le composant courant \(`TBPostsListComponent`\) par le composant d'administration \(`TBAdminComponent`\). +Si vous rafraichissez votre navigateur, le bouton admin est bien présent mais il n'a aucun effet pour l'instant (voir la figure *@withAdminView1@*). +Il faut définir un `callback:` sur ce bouton (un bloc) qui remplace le composant courant (`TBPostsListComponent`) par le composant d'administration (`TBAdminComponent`). ![Barre de navigation avec un button admin.](figures/withAdminView1.png width=80&label=withAdminView1) ### Revisons la barre de navigation -Commençons par réviser la définition de `TBHeaderComponent` en lui ajoutant une variable d'instance `component` pour stocker et accéder au composant courant \(qui sera soit la liste de bulletins, soit le composant d'administration\). Ceci va nous permettre de pouvoir accéder au composant depuis la barre de navigation : +Commençons par réviser la définition de `TBHeaderComponent` en lui ajoutant une variable d'instance `component` pour stocker et accéder au composant courant (qui sera soit la liste de bulletins, soit le composant d'administration). Ceci va nous permettre de pouvoir accéder au composant depuis la barre de navigation : ``` WAComponent subclass: #TBHeaderComponent @@ -127,7 +127,7 @@ TBScreenComponent >> createHeaderComponent Notez que la méthode `createHeaderComponent` est bien définie dans la superclasse `TBScreenComponent` car elle est applicable pour toutes ses sous-classes. -Nous pouvons maintenant ajouter le callback \(message `callback:`\) sur le bouton : +Nous pouvons maintenant ajouter le callback (message `callback:`) sur le bouton : ``` TBHeaderComponent >> renderSimpleAdminButtonOn: html @@ -216,7 +216,7 @@ Cliquez sur 'New Session' en bas à gauche de votre navigateur et ensuite sur le Si vous étudiez le code précédent, vous verrez que nous avons utilisé le mécanisme `call:`/`answer:` de Seaside pour mettre en place la navigation entre les composants `TBPostsListComponent` et `TBAdminComponent`. Le message `call:` remplace le composant courant par le composant passé en argument et lui donne le flot de calcul. Le message `answer:` retourne une valeur à cet appel et redonne le contrôle au composant appelant. -Ce mécanisme puissant et élégant est expliqué dans la vidéo 1 de la semaine 5 du Mooc \([http://rmod-pharo-mooc.lille.inria.fr/MOOC/WebPortal/co/content\_5.html](http://rmod-pharo-mooc.lille.inria.fr/MOOC/WebPortal/co/content_5.html)\). +Ce mécanisme puissant et élégant est expliqué dans la vidéo 1 de la semaine 5 du Mooc ([http://rmod-pharo-mooc.lille.inria.fr/MOOC/WebPortal/co/content\_5.html](http://rmod-pharo-mooc.lille.inria.fr/MOOC/WebPortal/co/content_5.html)). ### Composant fenêtre modale d'identification @@ -368,7 +368,7 @@ TBAuthentificationComponent >> renderPasswordFieldOn: html Deux boutons sont ajoutés en bas de la fenêtre modale. Le bouton `'Cancel'` qui permet de fermer la fenêtre modale grâce à son attribut 'data-dismiss' et le bouton `'SignIn'` associé à un bloc de callback qui envoie le message `validate`. -La touche `enter` du clavier permet également d'activer le bouton `'SignIn'` car c'est le seul dont l'attribut 'type' a la valeur 'submit' \(ceci est réalisé par la méthode `tbsSubmitButton`\). +La touche `enter` du clavier permet également d'activer le bouton `'SignIn'` car c'est le seul dont l'attribut 'type' a la valeur 'submit' (ceci est réalisé par la méthode `tbsSubmitButton`). ``` @@ -404,7 +404,7 @@ TBAuthentificationComponent >> validate ### Intégration du composant d'identification -Pour intégrer notre composant d'identification, modifions le bouton 'Admin' de la barre d'en-tête \(`TBHeaderComponent`\) ainsi: +Pour intégrer notre composant d'identification, modifions le bouton 'Admin' de la barre d'en-tête (`TBHeaderComponent`) ainsi: ``` TBHeaderComponent >> renderButtonsOn: html @@ -425,7 +425,7 @@ TBHeaderComponent >> renderModalLoginButtonOn: html ``` -La méthode `renderModalLoginButtonOn:` commence par intégrer le code du composant `TBAuthentificationComponent` dans la page web \(`render:`\). +La méthode `renderModalLoginButtonOn:` commence par intégrer le code du composant `TBAuthentificationComponent` dans la page web (`render:`). Le composant étant instancié à chaque affichage, il n'a pas besoin d'être retourné par la méthode `children`. On ajoute également un bouton nommé 'Login' avec un pictogramme clé. Lorsque l'utilisateur clique sur ce bouton, la boîte modale ayant l'identifiant `myAuthDialog` est affichée. @@ -778,7 +778,7 @@ TBHeaderComponent >> renderButtonsOn: html ``` -Vous pouvez tester dans votre navigateur en commençant une nouvelle session \(bouton 'New Session' en bas à gauche\). +Vous pouvez tester dans votre navigateur en commençant une nouvelle session (bouton 'New Session' en bas à gauche). Une fois connecté, l'administrateur est ajouté en session. Remarquez que le bouton déconnexion ne fonctionne plus correctement car il n'invalide pas la session. diff --git a/Chapters/Chap08-TinyBlog-Admin-FR.md b/Chapters/Chap08-TinyBlog-Admin-FR.md index 44ee738..8caae52 100644 --- a/Chapters/Chap08-TinyBlog-Admin-FR.md +++ b/Chapters/Chap08-TinyBlog-Admin-FR.md @@ -18,13 +18,13 @@ La figure *@ApplicationAdmin@* montre un aperçu de l'architecture visée dans c ### Décrire les données métiers avec Magritte -Magritte est une bibliothèque qui permet une fois les données décrites de générer diverses représentations ou opérations \(telles des requêtes\). +Magritte est une bibliothèque qui permet une fois les données décrites de générer diverses représentations ou opérations (telles des requêtes). Couplé avec Seaside, Magritte permet de générer des formulaires et des rapports. -Le logiciel Quuve de la société Debris Publishing est un brillant exemple de la puissance de Magritte: tous les tableaux sont automatiquement générés \(voir [http://www.pharo.org/success](http://www.pharo.org/success)\). +Le logiciel Quuve de la société Debris Publishing est un brillant exemple de la puissance de Magritte: tous les tableaux sont automatiquement générés (voir [http://www.pharo.org/success](http://www.pharo.org/success)). La validation des données est aussi définie au niveau de Magritte au lieu d'être dispersée dans le code de l'interface graphique. Ce chapitre ne montre pas cet aspect. -Un chapitre dans le livre sur Seaside \([http://book.seaside.st](http://book.seaside.st)\) est disponible sur Magritte ainsi qu'un tutoriel en cours d'écriture sur [https://github.com/SquareBracketAssociates/Magritte](https://github.com/SquareBracketAssociates/Magritte). +Un chapitre dans le livre sur Seaside ([http://book.seaside.st](http://book.seaside.st)) est disponible sur Magritte ainsi qu'un tutoriel en cours d'écriture sur [https://github.com/SquareBracketAssociates/Magritte](https://github.com/SquareBracketAssociates/Magritte). Une description est un objet qui spécifie des informations sur des données de notre modèle comme son type, si une donnée est obligatoire, si elle doit être triée, ou quelle est sa valeur par défaut. @@ -130,7 +130,7 @@ Toutefois, nous pensons que distinguer le composant d'administration du rapport La liste des posts est affichée à l'aide d'un rapport généré dynamiquement par le framework Magritte. - Nous utilisons ce framework pour réaliser les différentes fonctionnalités de la partie administration de TinyBlog \(liste des posts, création, édition et suppression d'un post\). + Nous utilisons ce framework pour réaliser les différentes fonctionnalités de la partie administration de TinyBlog (liste des posts, création, édition et suppression d'un post). Pour rester modulaire, nous allons créer un composant Seaside pour cette tâche. Le composant `TBPostsReport` étend la classe `TBSMagritteReport` qui gére les rapports avec Bootstrap. @@ -180,7 +180,7 @@ TBAdminComponent >> report: aReport Comme le rapport est un composant fils du composant admin nous n'oublions pas de redéfinir la méthode `children` comme suit. -Notez que la collection contient à la fois les sous-composants définis dans la super-classe \(le composant en-tête\) et ceux dans la classe courante \(le composant rapport\). +Notez que la collection contient à la fois les sous-composants définis dans la super-classe (le composant en-tête) et ceux dans la classe courante (le composant rapport). ``` TBAdminComponent >> children @@ -250,7 +250,7 @@ La figure *@RapportV1@* montre ce que vous devez obtenir dans votre navigateur. Le rapport généré est brut. Il n'y a pas de titres sur les colonnes et l'ordre d'affichage des colonnes n'est pas fixé. Celui-ci peut varier d'une instance à une autre. Pour gérer cela, il suffit de modifier les descriptions Magritte pour chaque variable d'instance. -Nous spécifions une priorité et un titre \(message `label:`\) comme suit : +Nous spécifions une priorité et un titre (message `label:`) comme suit : ``` TBPost >> descriptionTitle @@ -315,8 +315,8 @@ Vous devez obtenir la situation telle que représentée par la figure *@adminRep ### Administration des bulletins -Nous pouvons maintenant mettre en place un CRUD \(Create Read Update Delete\) permettant de gérer les bulletins. -Pour cela, nous allons ajouter une colonne \(instance `MACommandColumn`\) au rapport qui regroupera les différentes opérations en utilisant `addCommandOn:`. +Nous pouvons maintenant mettre en place un CRUD (Create Read Update Delete) permettant de gérer les bulletins. +Pour cela, nous allons ajouter une colonne (instance `MACommandColumn`) au rapport qui regroupera les différentes opérations en utilisant `addCommandOn:`. Cette méthode permet de définir un lien qui déclenchera l'exécution d'une méthode de l'objet courant lorsqu'il sera cliqué grâce à un callback. Ceci se fait lors de la création du rapport. @@ -369,7 +369,7 @@ Par ailleurs, cette méthode est un peu longue et elle ne permet pas de separer ### Gérer l'ajout d'un bulletin -L'ajout \(add\) est dissocié des bulletins et se trouvera donc juste avant le rapport. +L'ajout (add) est dissocié des bulletins et se trouvera donc juste avant le rapport. Etant donné qu'il fait partie du composant `TBPostsReport`, nous devons redéfinir la méthode `renderContentOn:` du composant `TBPostsReport` pour insérer le lien `add`. @@ -390,9 +390,9 @@ Identifiez-vous à nouveau et vous devez obtenir la situation telle que représe ### Implémentation des actions CRUD -A chaque action \(Create/Read/Update/Delete\) correspond une méthode de l'objet `TBPostsReport`. +A chaque action (Create/Read/Update/Delete) correspond une méthode de l'objet `TBPostsReport`. Nous allons maintenant les implémenter. -Un formulaire personnalisé est construit en fonction de l'opération demandée \(il n'est pas utile par exemple d'avoir un bouton "Sauver" alors que l'utilisateur veut simplement lire le post\). +Un formulaire personnalisé est construit en fonction de l'opération demandée (il n'est pas utile par exemple d'avoir un bouton "Sauver" alors que l'utilisateur veut simplement lire le post). ### Ajouter un bulletin @@ -421,7 +421,7 @@ TBPostsReport >> addPost On voit une fois encore l'utilisation du message `call:` pour donner la main à un composant. -Le lien pour ajouter un bulletin permet maintenant d'afficher un formulaire de création que nous rendrons plus présentable \(Voir figure *@AffichePostRaw@*\). +Le lien pour ajouter un bulletin permet maintenant d'afficher un formulaire de création que nous rendrons plus présentable (Voir figure *@AffichePostRaw@*). ![Affichage rudimentaire d'un bulletin.](figures/AffichePostRaw.png width=75&label=AffichePostRaw) @@ -628,4 +628,4 @@ Par exemple, le formulaire d'édition d'un post doit maintenant ressembler à ce Nous avons mis en place la partie administration de TinyBlog sous la forme d'un rapport des bulletins contenus dans le blog courant. Nous avons également ajouté des liens permettant une gestion CRUD de chaque bulletin. Nous avons réalisé tout cela en utilisant Magritte. -En effet, nous avons ajouté des descriptions sur les bulletins et généré des composants Seaside \(des formulaires\) à partir de ces descriptions. +En effet, nous avons ajouté des descriptions sur les bulletins et généré des composants Seaside (des formulaires) à partir de ces descriptions. diff --git a/Chapters/Chap09-TinyBlog-SeasideREST-FR.md b/Chapters/Chap09-TinyBlog-SeasideREST-FR.md index 5833e14..6e326d4 100644 --- a/Chapters/Chap09-TinyBlog-SeasideREST-FR.md +++ b/Chapters/Chap09-TinyBlog-SeasideREST-FR.md @@ -1,14 +1,14 @@ ## Une interface REST pour TinyBlog -Ce chapitre décrit comment doter notre application TinyBlog d'une interface REST \(REpresentational State Transfer\). +Ce chapitre décrit comment doter notre application TinyBlog d'une interface REST (REpresentational State Transfer). Le code est placé dans un package `'TinyBlog-Rest'` car l'utilisation de REST est optionnelle. Les tests seront dans le package `'TinyBlog-Rest-Tests'`. ### Notions de base sur REST -REST se base sur les verbes HTTP pour décrire l'accès aux ressources HTTP \(https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html\). Les principaux verbes ont la signification suivante: +REST se base sur les verbes HTTP pour décrire l'accès aux ressources HTTP (https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html). Les principaux verbes ont la signification suivante: - GET pour lire une ressource, - POST pour créer une nouvelle ressource, @@ -20,7 +20,7 @@ Les ressources sont définies à l'aide des URL qui pointent sur une entité. Le Une autre notion importante est le respect des formats de données acceptés par le client et par le serveur. Lorsqu'un client REST émet une requête vers un serveur REST, il précise dans l'en-tête de la requête HTTP la liste des types de données qu'il est capable de gérer. Le serveur REST se doit de répondre dans un format compréhensible par le client et si cela n'est pas possible, de préciser au client qu'il n'est pas capable de lui répondre. -La réussite ou l'échec d'une opération est basée sur les codes de statut du protocole HTTP \(https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html\). Par exemple, si une opération réussit, le serveur doit répondre un code 200 \(OK\). De même, si une ressource demandée par le client n'existe pas, il doit retourner un code 404 \(Not Found\). Il est très important de respecter la signification de ces codes de statut afin de mettre en place un dialogue compréhensible et normalisé entre le client et le serveur. +La réussite ou l'échec d'une opération est basée sur les codes de statut du protocole HTTP (https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html). Par exemple, si une opération réussit, le serveur doit répondre un code 200 (OK). De même, si une ressource demandée par le client n'existe pas, il doit retourner un code 404 (Not Found). Il est très important de respecter la signification de ces codes de statut afin de mettre en place un dialogue compréhensible et normalisé entre le client et le serveur. ### Définir un filtre REST @@ -74,7 +74,7 @@ A partir de maintenant, nous pouvons commencer à implémenter les différents s Le premier service proposé sera destiné à récupérer la liste des posts. Il s'agit d'une opération de lecture et elle utilisera donc le verbe GET du protocole HTTP. La réponse sera produite au format JSON. La méthode `listAll` est marquée comme étant un point d'entrée REST à l'aide des annotations `` et ``. -Si le client interroge le serveur à l'aide de l'URL `http://localhost:8080/TinyBlog/listAll`, la méthode `listAll` est appelée. Celle-ci retourne les données selon le type MIME \(Multipurpose Internet Mail Extensions\) spécifié par l'annotation ``. +Si le client interroge le serveur à l'aide de l'URL `http://localhost:8080/TinyBlog/listAll`, la méthode `listAll` est appelée. Celle-ci retourne les données selon le type MIME (Multipurpose Internet Mail Extensions) spécifié par l'annotation ``. ``` TBRestfulFilter >> listAll @@ -102,7 +102,7 @@ TBRestfulFilter >> listAll Maintenant que nous avons défini le point d'entrée, nous pouvons implémenter la partie métier du service `listAll`. C'est à dire le code chargé de construire la liste des posts contenus dans la base. Une représentation astucieuse d'un service peut être réalisée à l'aide des objets. Chaque service REST sera contenu dans un object distinct. Ceci facilitera grandement la maintenance et la compréhension du code. -La méthode `listAll` ci-dessous fait maintenant appel au service adéquat, nommé TBRestServiceListAll. Il est nécessaire de transmettre le contexte d'exécution de Seaside à l'instance de cet objet. Ce contexte est l'ensemble des informations transmises par le client REST \(variables d'environnement HTTP ainsi que les flux d'entrée/sortie de Seaside\). +La méthode `listAll` ci-dessous fait maintenant appel au service adéquat, nommé TBRestServiceListAll. Il est nécessaire de transmettre le contexte d'exécution de Seaside à l'instance de cet objet. Ce contexte est l'ensemble des informations transmises par le client REST (variables d'environnement HTTP ainsi que les flux d'entrée/sortie de Seaside). ``` TBRestfulFilter >> listAll @@ -162,7 +162,7 @@ TBRestService >> execute Tous les services REST de TinyBlog doivent être capables de retourner une réponse au client et de lui préciser le format des données utilisé. Vous devez donc ajouter une méthode pour faire cela. Il s'agit de la méthode `dataType:with:`. Le premier paramètre sera le type MIME utilisé et le second, contiendra les données transmises au client. La méthode insère ces informations dans le flux de réponses fournit par Seaside. -La méthode `greaseString` appliquée sur le type de données permet d'obtenir une représentation du type MIME sous la forme d'une chaine de caractères \(par exemple: "application/json"\). +La méthode `greaseString` appliquée sur le type de données permet d'obtenir une représentation du type MIME sous la forme d'une chaine de caractères (par exemple: "application/json"). ``` TBRestService >> dataType: aDataType with: aResultSet @@ -338,7 +338,7 @@ Cette méthode permet la gestion des caractères spéciaux tels que l'espace ou Si vous cherchez un post ayant pour titre "La reproduction des hippocampes", le service REST recevra en fait la chaîne de caractères "La%20reproduction%20des%20hippocampes" et une recherche avec celle ci ne fonctionnera pas car aucun titre de post ne coïncidera. Il faut donc nettoyer la chaîne de caractères en remplaçant les caractères spéciaux avant de lancer la recherche. -Un autre point important est la gestion des codes d'erreur HTTP. Lorsqu'un serveur HTTP répond à son client, il glisse dans l'en-tête de la réponse une valeur numérique qui fournit au client de précieuses informations sur le résultat attendu. Si la réponse contient le code 200, c'est que tout s'est correctement passé et qu'un résultat est fourni au client \(c'est d'ailleurs la valeur par défaut dans Seaside/Rest\). Mais parfois, un problème survient. Par exemple, la requête demande à accéder à une ressource qui n'existe pas. Dans ce cas, il est nécessaire de retourner un code 404 \(Not Found\) pour l'indiquer au client. Un code 500 va indiquer qu'une erreur d'exécution a été rencontrée par le service. Vous trouverez la liste exhaustive des codes d'erreur sur la page décrivant le protocole HTTP \(https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html\). Il est très important de les gérer correctement tant au niveau de votre service REST qu'au sein de votre client REST car c'est ce qui va permettre à la couche cliente de réagir à bon escient en fonction du résultat du traitement exécuté par le serveur. +Un autre point important est la gestion des codes d'erreur HTTP. Lorsqu'un serveur HTTP répond à son client, il glisse dans l'en-tête de la réponse une valeur numérique qui fournit au client de précieuses informations sur le résultat attendu. Si la réponse contient le code 200, c'est que tout s'est correctement passé et qu'un résultat est fourni au client (c'est d'ailleurs la valeur par défaut dans Seaside/Rest). Mais parfois, un problème survient. Par exemple, la requête demande à accéder à une ressource qui n'existe pas. Dans ce cas, il est nécessaire de retourner un code 404 (Not Found) pour l'indiquer au client. Un code 500 va indiquer qu'une erreur d'exécution a été rencontrée par le service. Vous trouverez la liste exhaustive des codes d'erreur sur la page décrivant le protocole HTTP (https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html). Il est très important de les gérer correctement tant au niveau de votre service REST qu'au sein de votre client REST car c'est ce qui va permettre à la couche cliente de réagir à bon escient en fonction du résultat du traitement exécuté par le serveur. Notre serveur web de recherche par titre est pratiquement terminé. Il nous reste maintenant à modifier le point d'entrée du service pour qu'il soit capable d'appeler le code métier associé. @@ -435,7 +435,7 @@ TBRestfulFilter >> searchDateFrom: beginString to: endString ``` -A l'aide d'une URL telle que http://localhost:8080/TinyBlog/posts/search?begin=2017/1/1&end=2017/3/30, vous pouvez tester votre nouveau service REST \(bien évidemment, les dates doivent être adaptées en fonction du contenu de votre base de test\). +A l'aide d'une URL telle que http://localhost:8080/TinyBlog/posts/search?begin=2017/1/1&end=2017/3/30, vous pouvez tester votre nouveau service REST (bien évidemment, les dates doivent être adaptées en fonction du contenu de votre base de test). ### Ajouter un post @@ -462,7 +462,7 @@ TBRestService subclass: #TBRestServiceAddPost ``` -Seule la méthode `execute` doit être implémentée. Elle lit le flux de données et le parse à l'aide de la méthode de classe `fromString:` de l'objet `NeoJSONReader`. Les données sont stockées dans un dictionnaire contenu dans la variable local `post`. Il suffit ensuite d'instancier un `TBPost` et de le sauver dans la base de données. Par sécurité, l'ensemble de ce processus est réalisé au sein d'une exception afin d'intercepter un problème d'exécution qui pourrait rendre instable le serveur. La dernière opération consiste à renvoyer au client un résultat vide mais aussi et surtout un code HTTP 200 \(OK\) signalant que le post a bien été créé. En cas d'erreur, c'est le message d'erreur 400 \(BAD REQUEST\) qui est retourné. +Seule la méthode `execute` doit être implémentée. Elle lit le flux de données et le parse à l'aide de la méthode de classe `fromString:` de l'objet `NeoJSONReader`. Les données sont stockées dans un dictionnaire contenu dans la variable local `post`. Il suffit ensuite d'instancier un `TBPost` et de le sauver dans la base de données. Par sécurité, l'ensemble de ce processus est réalisé au sein d'une exception afin d'intercepter un problème d'exécution qui pourrait rendre instable le serveur. La dernière opération consiste à renvoyer au client un résultat vide mais aussi et surtout un code HTTP 200 (OK) signalant que le post a bien été créé. En cas d'erreur, c'est le message d'erreur 400 (BAD REQUEST) qui est retourné. ``` TBRestServiceAddPost >> execute @@ -500,14 +500,14 @@ Au fil de ce chapitre, vous avez implémenté les principales briques d'une API #### Modifier un post existant -La modification d'un post existant peut facilement être réalisée. Il vous suffit d'implémenter un service REST utilisant le verbe HTTP `PUT` et d'encoder votre post avec la même structure que celle utilisée pour la création d'un post \(service `addPost`\). L'exercice consiste ici à implémenter correctement la gestion des codes d'erreurs HTTP. De nombreux cas sont possibles. +La modification d'un post existant peut facilement être réalisée. Il vous suffit d'implémenter un service REST utilisant le verbe HTTP `PUT` et d'encoder votre post avec la même structure que celle utilisée pour la création d'un post (service `addPost`). L'exercice consiste ici à implémenter correctement la gestion des codes d'erreurs HTTP. De nombreux cas sont possibles. -- 200 \(OK\) ou 201 \(CREATED\) si l'opération a réussi, -- 204 \(NO CONTENT\) si la requête ne contient pas de données, -- 304 \(NOT MODIFIED\) si aucun changement ne doit être appliqué \(le contenu du post est identique\), -- 400 \(BAD REQUEST\) si les données transmises par le client sont incorrectes, -- 404 \(NOT FOUND\) si le post devant être modifié n'existe pas, -- 500 \(INTERNAL SERVER ERROR\) si un problème survient lors de la création du post dans la base de données. +- 200 (OK) ou 201 (CREATED) si l'opération a réussi, +- 204 (NO CONTENT) si la requête ne contient pas de données, +- 304 (NOT MODIFIED) si aucun changement ne doit être appliqué (le contenu du post est identique), +- 400 (BAD REQUEST) si les données transmises par le client sont incorrectes, +- 404 (NOT FOUND) si le post devant être modifié n'existe pas, +- 500 (INTERNAL SERVER ERROR) si un problème survient lors de la création du post dans la base de données. #### Supprimer un post diff --git a/Chapters/Chap11-TinyBlog-Mustache-FR.md b/Chapters/Chap11-TinyBlog-Mustache-FR.md index dc75f2d..5364ceb 100644 --- a/Chapters/Chap11-TinyBlog-Mustache-FR.md +++ b/Chapters/Chap11-TinyBlog-Mustache-FR.md @@ -88,7 +88,7 @@ Pour ajouter des élément dans le bas de page, vous allez utiliser certaines fo Le premier modèle doit afficher les principales technologies utilisées dans TinyBlog. Pour cela, définissez une méthode `renderPoweredByOn:` dans la classe `TBPostListComponent`. Un dictionaire contient les données qui sont insérées au sein du modèle. Celui-ci est défini par une chaîne de caractères dans laquelle les éléments devant être substitués sont encadrés par les caractères "\{{" et "\}}". -Par défaut, Mustache utilise les caractères spéciaux d'HTML pour assurer un rendu web optimal \(par exemple `Pharo` est transformé en `<b>Pharo</b>`. Si vous ne voulez pas les utiliser, vous devez encadrer les éléments par les caractères `{{{` et `}}}`. +Par défaut, Mustache utilise les caractères spéciaux d'HTML pour assurer un rendu web optimal (par exemple `Pharo` est transformé en `<b>Pharo</b>`. Si vous ne voulez pas les utiliser, vous devez encadrer les éléments par les caractères `{{{` et `}}}`. ``` TBPostListComponent >> renderPoweredByOn: html diff --git a/Chapters/Chap12-TinyBlog-Export-FR.md b/Chapters/Chap12-TinyBlog-Export-FR.md index e56345e..0c99a22 100644 --- a/Chapters/Chap12-TinyBlog-Export-FR.md +++ b/Chapters/Chap12-TinyBlog-Export-FR.md @@ -7,12 +7,12 @@ Pour l'administrateur du blog, il est utile de proposer des fonctionnalités d'e ### Exporter un article en PDF -Le format PDF \(Portable Document Format\) a été créé par la société Adobe en 1992. C'est un langage de description de pages permettant de spécifier la mise en forme d'un document ainsi que son contenu. Il est particulièrement utile pour concevoir des documents électroniques, des eBooks et dans le cadre de l'impression puisqu'un document PDF conserve sa mise en forme lorsqu'il est imprimé. Vous allez justement mettre à profit cette propriété en ajoutant à TinyBlog la possibilité d'exporter un post sous la forme d'un fichier PDF. +Le format PDF (Portable Document Format) a été créé par la société Adobe en 1992. C'est un langage de description de pages permettant de spécifier la mise en forme d'un document ainsi que son contenu. Il est particulièrement utile pour concevoir des documents électroniques, des eBooks et dans le cadre de l'impression puisqu'un document PDF conserve sa mise en forme lorsqu'il est imprimé. Vous allez justement mettre à profit cette propriété en ajoutant à TinyBlog la possibilité d'exporter un post sous la forme d'un fichier PDF. #### Artefact -La construction d'un document PDF avec Pharo est grandement simplifiée à l'aide d'un framework nommé Artefact \([https://sites.google.com/site/artefactpdf/](https://sites.google.com/site/artefactpdf/)\). Pour l'installer, il vous suffit de le sélectionner dans le catalogue Pharo. +La construction d'un document PDF avec Pharo est grandement simplifiée à l'aide d'un framework nommé Artefact ([https://sites.google.com/site/artefactpdf/](https://sites.google.com/site/artefactpdf/)). Pour l'installer, il vous suffit de le sélectionner dans le catalogue Pharo. #### Intégrer l'exportation dans la liste des posts @@ -154,7 +154,7 @@ La figure *@pdfResult@* montre le résultat d'un export en PDF d'un bulletin. ### Exportation des posts au format CSV -Vous allez poursuivre l'amélioration de TinyBlog en ajoutant une option dans la partie "Administration" de l'application. Celle ci doit permettre l'exportation de l'ensemble des billets du blog dans un fichier CSV. Ce format \(Comma-separated values\) est un format bien connu des utilisateurs de tableurs qui l'exploitent souvent pour importer ou exporter des données. Il s'agit d'un fichier texte dans lequel les données sont formatés et distinctes les unes des autres à l'aide d'un caractère séparateur qui est le plus souvent une virgule. Le fichier est donc composé de lignes et chacune d'entre elles contient un nombre identique de colonnes. Une ligne se termine par un caractère de fin de ligne \(CRLF\). +Vous allez poursuivre l'amélioration de TinyBlog en ajoutant une option dans la partie "Administration" de l'application. Celle ci doit permettre l'exportation de l'ensemble des billets du blog dans un fichier CSV. Ce format (Comma-separated values) est un format bien connu des utilisateurs de tableurs qui l'exploitent souvent pour importer ou exporter des données. Il s'agit d'un fichier texte dans lequel les données sont formatés et distinctes les unes des autres à l'aide d'un caractère séparateur qui est le plus souvent une virgule. Le fichier est donc composé de lignes et chacune d'entre elles contient un nombre identique de colonnes. Une ligne se termine par un caractère de fin de ligne (CRLF). Pour gérer le format CSV dans Pharo, vous disposez du framework NeoCSV installable à l'aide du catalogue. @@ -237,7 +237,7 @@ TBPostsCSVExport >> sendPostsToCSVFrom: aBlog to: anHTTPContext ``` -La partie importante de la méthode utilise NeoCSV pour insérer dans le flux de sortie chaque billet converti au format CSV. Le titre, la date de publication et le contenu du billet sont séparés par une virgule. Lorsque cela est necessaire \(titre et contenu\), NeoCSV utilise des guillemets pour indiquer que la donnée est une chaine de caractères. La méthode `nextPut:` permet d'insérer au début du fichier les noms des colonnes. La méthode `addObjectFields:` sélectionne les données ajoutées au fichier et récoltées à l'aide de la méthode `allBlogPosts`. +La partie importante de la méthode utilise NeoCSV pour insérer dans le flux de sortie chaque billet converti au format CSV. Le titre, la date de publication et le contenu du billet sont séparés par une virgule. Lorsque cela est necessaire (titre et contenu), NeoCSV utilise des guillemets pour indiquer que la donnée est une chaine de caractères. La méthode `nextPut:` permet d'insérer au début du fichier les noms des colonnes. La méthode `addObjectFields:` sélectionne les données ajoutées au fichier et récoltées à l'aide de la méthode `allBlogPosts`. ``` outputStream nextPutAll: (String streamContents: [ :stream | @@ -252,7 +252,7 @@ La partie importante de la méthode utilise NeoCSV pour insérer dans le flux de ``` -Il ne vous reste plus qu'à transmettre les données au navigateur du poste client. Pour cela, il vous faut produire une réponse dans le contexte HTTP de la requête. Le type MIME \(text/csv\) et l'encodage \(UTF-8\) sont déclarés au navigateur. La méthode `attachmentWithFileName:` permet de spécifier un nom de fichier au navigateur. +Il ne vous reste plus qu'à transmettre les données au navigateur du poste client. Pour cela, il vous faut produire une réponse dans le contexte HTTP de la requête. Le type MIME (text/csv) et l'encodage (UTF-8) sont déclarés au navigateur. La méthode `attachmentWithFileName:` permet de spécifier un nom de fichier au navigateur. ``` anHTTPContext respond: [:response | @@ -345,7 +345,7 @@ La message `enabledPrettyPrinting` modifie le comportement du générateur XML e Ceci facilite la lecture d'un fichier XML par un être humain. Si le document généré est volumineux, ne pas utiliser cette option permet de réduire la taille des données. -Vous pouvez maintenant formater les données en XML. La message `xml` permet d'insérer une en-tête au tout début des données. Chaque billet est placé au sein d'une balise `post` et l'ensemble des billets est stocké au sein de la balise `posts`. Pour celle ci, un espace de nommage `TinyBlog` est défini et pointe sur le domaine `pharo.org`. Chaque balise `post` est définie au sein du parcours de la collection retournée par la méthode `allBlogPosts`. Le titre est conservé tel quel, par contre la date est convertie au format anglosaxon \(year-month-day\). Notez le traitement particulier appliqué sur le texte du billet. Celui ci est encadré par une section `CDATA` afin de gérer correctement les caractères spéciaux pouvant s'y trouver \(retour à la ligne, lettres accentuées, etc.\). +Vous pouvez maintenant formater les données en XML. La message `xml` permet d'insérer une en-tête au tout début des données. Chaque billet est placé au sein d'une balise `post` et l'ensemble des billets est stocké au sein de la balise `posts`. Pour celle ci, un espace de nommage `TinyBlog` est défini et pointe sur le domaine `pharo.org`. Chaque balise `post` est définie au sein du parcours de la collection retournée par la méthode `allBlogPosts`. Le titre est conservé tel quel, par contre la date est convertie au format anglosaxon (year-month-day). Notez le traitement particulier appliqué sur le texte du billet. Celui ci est encadré par une section `CDATA` afin de gérer correctement les caractères spéciaux pouvant s'y trouver (retour à la ligne, lettres accentuées, etc.). ``` xml writeWith: [ :writer | diff --git a/Chapters/Chap14-TinyBlog-Loading-FR.md b/Chapters/Chap14-TinyBlog-Loading-FR.md index 05b0c27..5017b57 100644 --- a/Chapters/Chap14-TinyBlog-Loading-FR.md +++ b/Chapters/Chap14-TinyBlog-Loading-FR.md @@ -2,10 +2,10 @@ @cha:loading -Ce chapitre contient les expressions permettant de charger le code décrit dans chacun des chapitres. Ces expressions peuvent être exécutées dans n'importe quelle image Pharo 8.0 \(ou supérieure\). -Néanmoins, utiliser l'image Pharo du MOOC \(cf. Pharo Launcher\) est généralement plus rapide car elle contient déjà de nombreuses dépendances comme : Seaside, Voyage, ... +Ce chapitre contient les expressions permettant de charger le code décrit dans chacun des chapitres. Ces expressions peuvent être exécutées dans n'importe quelle image Pharo 8.0 (ou supérieure). +Néanmoins, utiliser l'image Pharo du MOOC (cf. Pharo Launcher) est généralement plus rapide car elle contient déjà de nombreuses dépendances comme : Seaside, Voyage, ... -Si vous commencez par le chapitre 4 par exemple, vous pouvez charger tout le code des chapitres précédents \(1, 2 et 3\) en suivant la procédure décrite dans la section 'Chapitre 4' ci-après. +Si vous commencez par le chapitre 4 par exemple, vous pouvez charger tout le code des chapitres précédents (1, 2 et 3) en suivant la procédure décrite dans la section 'Chapitre 4' ci-après. Bien évidemment, nous vous conseillons de faire votre propre code mais cela vous permettra de ne pas rester bloqué le cas échéant. @@ -24,7 +24,7 @@ Metacello new Après le chargement d'un package, il est recommandé d'exécuter les tests unitaires qu'il contient afin de vérifier le bon fonctionnement du code chargé. -Pour cela, vous pouvez lancer l'outil TestRunner \(Tools menu > Test Runner\), chercher le package TinyBlog-Tests et lancer tous les tests unitaires de la classe `TBBlogTest` en cliquant sur le bouton "Run Selected". Tous les tests doivent être verts. Une alternative est de presser l'icone verte qui se situe à coté de la class `TBBlogTest`. +Pour cela, vous pouvez lancer l'outil TestRunner (Tools menu > Test Runner), chercher le package TinyBlog-Tests et lancer tous les tests unitaires de la classe `TBBlogTest` en cliquant sur le bouton "Run Selected". Tous les tests doivent être verts. Une alternative est de presser l'icone verte qui se situe à coté de la class `TBBlogTest`. ### Chapitre 4 : Persistance des données de TinyBlog avec Voyage et Mongo diff --git a/Chapters/Chap15-TinyBlog-SavingCode-FR.md b/Chapters/Chap15-TinyBlog-SavingCode-FR.md index cd67cf5..f7ef4c4 100644 --- a/Chapters/Chap15-TinyBlog-SavingCode-FR.md +++ b/Chapters/Chap15-TinyBlog-SavingCode-FR.md @@ -1 +1 @@ -## Sauver votre code Lorsque vous sauvez l'image Pharo avec le menu 'Save', celle-ci contient tous les objets du système et donc les classes elles-mêmes. Cette solution est pratique mais peu pérenne. A partir de Pharo 70, vous pouvez sauver votre code sur github, bitbucket, ou gitlab avec un nouvel outil dédié: Iceberg. Nous vous suggérons de lire le chapitre dédié à la gestion de code dans le livre "Managing Your Code with Iceberg" \(disponible à [http://books.pharo.org](http://books.pharo.org)\). Nous rappellons ici les points clefs : - Créer un compte sur [http://www.github.com](http://www.github.com) ou autre. - Créer un projet sur [http://www.github.com](http://www.github.com) ou autre. - Utiliser Iceberg pour ajouter un projet, choisir clone from github par exemple. - Créer un dossier `'src'` avec le FileList ou la ligne de commande dans le dossier que vous avez choisi sur votre système de fichier local. - Ouvrir votre projet et ajouter vos packages \(Il est conseillé de definir une baseline pour être facilement rechargeable - voir [https://github.com/pharo-open-documentation/pharo-wiki/blob/master/General/Baselines.md](https://github.com/pharo-open-documentation/pharo-wiki/blob/master/General/Baselines.md)\) - Sauver votre code \(Commit\). - Publier votre code sur github \(Push\). \ No newline at end of file +## Sauver votre code Lorsque vous sauvez l'image Pharo avec le menu 'Save', celle-ci contient tous les objets du système et donc les classes elles-mêmes. Cette solution est pratique mais peu pérenne. A partir de Pharo 70, vous pouvez sauver votre code sur github, bitbucket, ou gitlab avec un nouvel outil dédié: Iceberg. Nous vous suggérons de lire le chapitre dédié à la gestion de code dans le livre "Managing Your Code with Iceberg" \(disponible à [http://books.pharo.org](http://books.pharo.org)\). Nous rappellons ici les points clefs : - Créer un compte sur [http://www.github.com](http://www.github.com) ou autre. - Créer un projet sur [http://www.github.com](http://www.github.com) ou autre. - Utiliser Iceberg pour ajouter un projet, choisir clone from github par exemple. - Créer un dossier `'src'` avec le FileList ou la ligne de commande dans le dossier que vous avez choisi sur votre système de fichier local. - Ouvrir votre projet et ajouter vos packages (Il est conseillé de definir une baseline pour être facilement rechargeable - voir [https://github.com/pharo-open-documentation/pharo-wiki/blob/master/General/Baselines.md](https://github.com/pharo-open-documentation/pharo-wiki/blob/master/General/Baselines.md)) - Sauver votre code (Commit). - Publier votre code sur github (Push). \ No newline at end of file diff --git a/_support/templates/latex/main.mustache b/_support/templates/latex/main.mustache index 168c1bb..c0cebb0 100644 --- a/_support/templates/latex/main.mustache +++ b/_support/templates/latex/main.mustache @@ -99,6 +99,6 @@ \backmatter % Index would go here -\bibliographystyle{abbrv} -\bibliography{«& bibFile»} +%\bibliographystyle{abbrv} +%\bibliography{«& bibFile»} \end{document}