URL: https://linuxfr.org/news/developper-une-interface-web-avec-le-toolkit-atlas-1-2
Title: Développer une interface web avec le toolkit Atlas (1/2)
Authors: Claude SIMON
Ysabeau đ§¶
Date: 2020ćčŽ12æ21æ„T17:19:56+01:00
License: CC By-SA
Tags: web, spa, python et atlas_toolkit
Score: 23
Le *toolkit* *Atlas* permet de programmer des interfaces dâapplications web monopages ([SPA](https://en.wikipedia.org/wiki/Single-page_application)). Il est lĂ©ger (quelques dizaines de Ko), sans dĂ©pendances, ne nĂ©cessite pas de savoir programmer en *JavaScript*, et nâimpose pas dâarchitecture logicielle de type [*MVC*](https://fr.wikipedia.org/wiki/Mod%C3%A8le-vue-contr%C3%B4leur).
En outre, toute application dĂ©veloppĂ©e avec le *toolkit* *Atlas* est, dĂšs son lancement, instantanĂ©ment et automatiquement accessible de nâimporte quel dispositif (smartphone, tablette...) Ă©quipĂ© dâun navigateur web moderne connectĂ© Ă Internet. Cet accĂšs est facilitĂ© par un [code QR](https://fr.wikipedia.org/wiki/Code_QR) qui sâaffiche dans lâapplication.
Le *toolkit* *Atlas* a dĂ©jĂ fait lâobjet de [quelques publications](https://linuxfr.org/tags/atlas_toolkit/public) ici mĂȘme. Pour varier un peu les plaisirs durant ces longues soirĂ©es ~~dâhiver~~ de couvre-feu, voici la premiĂšre partie dâun document qui devrait faciliter lâutilisation du *toolkit* *Atlas*. Il dĂ©taille le dĂ©veloppement dâune application (trĂšs) basique de gestion de contacts, dont lâapparence est la suivante :

Le *toolkit* *Atlas* est disponible pour *Java*, *Node.js*, *Perl*, *Python* et *Ruby*. Câest la version la plus populaire, Ă savoir *Python*, qui est utilisĂ©e pour ce document. Cependant, lâAPI Ă©tant la mĂȘme pour toutes les versions, on peut facilement le transposer aux autres langages disponibles.
----
[Homepage](https://atlastk.org)
[Sur GitHub](https://github.com/epeios-q37/atlas-python)
[Sur Repl.it](https://repl.it/@AtlasTK/atlas-python)
[API](https://atlastk.org/api/fr)
[Seconde partie](https://linuxfr.org/news/developper-une-interface-web-avec-le-toolkit-atlas-2-2)
----
# Ă propos de ce document
Lâaccent Ă©tant mis sur la mise en Ćuvre de l'*API* du *toolkit* *Atlas*, le lecteur est supposĂ© possĂ©der les connaissances (basiques) nĂ©cessaires Ă la comprĂ©hension du code *HTML*/*CSS* et *Python* prĂ©sent dans ce document.
Les fichiers sources associĂ©s Ă ce document sont disponibles dans un [dĂ©pĂŽt *GitHub*](https://github.com/epeios-q37/atlas-python/tree/master/tutorials/Contacts), lui-mĂȘme clonĂ© [sur *Repl.it*](https://repl.it/@AtlasTK/atlas-python), un *IDE* en ligne.
Si *Python* 3 est installé sur votre ordinateur, vous pouvez récupérer le dépÎt *GitHub* et visualiser/exécuter directement sur votre machine le code associé aux différentes sections de ce document.
Vous pouvez Ă©galement, notamment si vous nâavez pas installĂ© *Python* 3, visualiser/exĂ©cuter, Ă©ventuellement aprĂšs modification, ce code directement dans votre navigateur en utilisant le lien *Repl.it* ci-dessus.
Pour ne pas allonger outre mesure ce document, chaque section ne contiendra que les dĂ©tails du code sur lequel elle porte. NĂ©anmoins, au dĂ©but de chaque section, il y aura un lien vers le code source complet tel que dĂ©crit dans cette section, ainsi que les instructions Ă lancer pour lâexĂ©cuter sur *Repl.it* et en local.
Les lignes, dans les fichiers source, prĂ©cĂ©dant la ligne `import atlastk` ne sont lĂ que pour faciliter lâutilisation de ces fichiers dans le cadre de ce document et ne sont pas nĂ©cessaires Ă une utilisation courante du *toolkit* *Atlas*.
# Le ficher *HTML* principal (`Main.html`)> Code source : [lien sur GitHub](https://github.com/epeios-q37/atlas-python/blob/master/tutorials/Contacts/Main.html).
Le fichier `Main.html` est un fichier au format *HTML* dĂ©crivant lâinterface.
Ce fichier va prendre place dans la section *body* de la page *HTML* constituant lâinterface de lâapplication.
## Structure générale
Voici un aperçu partiel du contenu de ce fichier, mettant en évidence sa structure générale :
```html
```
Il est aisément compréhensible de celles et ceux qui sont familiers avec *HTML*.
Ses diffĂ©rentes sous-parties, qui prennent la place de commentaires ci-dessus, vont ĂȘtre dĂ©taillĂ©es ci-dessous.
## DĂ©tail dâun contact
Voici le code dĂ©diĂ© Ă lâaffichage du dĂ©tail dâun contact :
```html
```
On y trouve un tableau, avec, pour chacun des champs constituant un contact, une ligne (chacune délimitée par `` et `
`) accompagnĂ©e dâun libellĂ© et dâun identifiant explicite.
## Boutons généraux
Ces boutons vont servir à créer/éditer/supprimer un contact.
En voici le code :
```html
```
Ă part lâattribut `data-xdh-onevent`, on nâa lĂ que du *HTML* des plus classiques.
Les différentes classes (valeurs `Display` et `DisplayAndSelect` des attributs `class`) ont cependant un rÎle bien particulier, qui sera révélé dans les sections qui suivent.
Lâattribut `data-xdh-onevent` prend ici la place de lâhabituel attribut `onclick`. Lâattribut `onclick` prend habituellement pour valeur le code *JavaScript* Ă lancer lorsque lâon clique sur le bouton auquel il est affectĂ©.
Ici, Ă la place, on utilise lâattribut `data-xdh-onevent`, qui va prendre pour valeur un libellĂ© dâaction, libellĂ© que lâon retrouvera dans le code *Python*. On va pouvoir ainsi coder les actions Ă rĂ©aliser lors dâun clic sur le bouton non plus en *JavaScript*, mais en *Python*.
## Boutons de saisie
Ces boutons sont affichĂ©s lors de la saisie dâun contact, et permettent de valider ou dâannuler cette saisie.
Voici le code correspondant :
```html
```
LĂ encore, rien de particulier, mis Ă part lâattribut `data-xdh-onevent`, que lâon a dĂ©jĂ rencontrĂ© ci-dessus.
Le contenu des attributs `data-xdh-onevent`, Ă savoir `Cancel` et `Submit`, va ĂȘtre utilisĂ© dans le code *Python* de lâapplication.
Notez quâici le nom du bouton (la valeur de lâĂ©lĂ©ment `button`) est identique Ă la valeur de son attribut `data-xdh-onevent`. Câest uniquement par commoditĂ© ; ce nâest en rien obligatoire.
## Liste de contacts
Cette partie affiche le tableau qui va accueillir la liste des contacts au sein de son Ă©lĂ©ment `tbody`, dont le contenu va ĂȘtre gĂ©nĂ©rĂ© par lâapplication.
En voici le contenu :
```html
```
Notez lâidentifiant `Content`, que lâon va retrouver dans le code *Python*. Lâidentifiant `Contacts` nâest, lui, utilisĂ© que dans le fichier `Head.html` dĂ©crit ci-dessous.
# Le fichier *HTML* des métadonnées (`Head.html`)> Code source : [lien sur GitHub](https://github.com/epeios-q37/atlas-python/blob/master/tutorials/Contacts/Head.html).
Ce fichier, Ă©galement au format *HTML*, prendra place dans la section *head* de la page *HTML* constituant lâinterface de lâapplication.
## Apparence de lâapplication
La premiĂšre partie de ce fichier dĂ©finit le titre, lâicĂŽne, et, Ă lâaide de quelques rĂšgles *CSS*, diverses retouches au niveau de lâapparence de lâinterface.
En voici le contenu :
```html
Address book
```
## Visibilité des boutons
La seconde partie du fichier permet de gérer la visibilité des boutons.
En voici le contenu :
```html
```
On y voit des Ă©lĂ©ments `style` accompagnĂ©s dâun identifiant. Ces Ă©lĂ©ments vont permettre de cacher/afficher certains boutons.
En effet, chaque Ă©lĂ©ment `style` dĂ©finit une rĂšgle pour une certaine classe. En activant/dĂ©sactivant un de ces Ă©lĂ©ments, on ajoute/retire Ă cette classe la rĂšgle *CSS* contenu dans lâĂ©lĂ©ment. Par consĂ©quent, on agit ainsi sur les Ă©lĂ©ments, en lâoccurrence des boutons, auxquels cette classe est affectĂ©e.
On retrouvera les différents identifiants de ces éléments `style` dans le code *Python* détaillé dans les sections qui suivent.
# Rendu de lâinterface (`part1.py`)> * Code source : [lien sur GitHub](https://github.com/epeios-q37/atlas-python/blob/master/tutorials/Contacts/part1.py) ;> * exĂ©cution :> * sur [*Repl.it*](https://repl.it/@AtlasTK/atlas-python#tutorials/Contacts/part1.py) : bouton *Run*, `n1` + *entrĂ©e*, clic sur URL,> * en local : `python3 atlas-python/tutorials/Contacts/part1.py`
On va ici afficher lâinterface de lâapplication, dont, suite Ă une action de lâutilisateur, seules les parties qui le nĂ©cessitent seront modifiĂ©es.
## Affichage de la page *HTML*
En premier lieu, on va définir la fonction qui sera appelée à chaque ouverture de session :
```python
def ac_connect(dom):
dom.inner("",open("Main.html").read())
```
`dom` est un objet fournit par le *toolkit* *Atlas* ; chaque session a sa propre instance de cet objet.
Dans cette fonction, la méthode `inner(...)`va remplacer la totalité de la page web par le contenu du fichier `Main.html` précédemment décrit.
Le premier paramĂštre de cette mĂ©thode est lâidentifiant de lâĂ©lĂ©ment dont on va remplacer le contenu. La chaĂźne vide est une valeur spĂ©ciale qui fait rĂ©fĂ©rence Ă lâĂ©lĂ©ment racine de la page.
Ă titre indicatif, il existe Ă©galement les mĂ©thodes `before(...)`, `begin(...)`, `end(...)` et `after(...)` pour insĂ©rer le contenu respectivement juste avant, au dĂ©but, Ă la fin ou juste aprĂšs lâĂ©lĂ©ment dont lâidentifiant est passĂ© en paramĂštre.
On va ensuite affecter cette fonction Ă une action, Ă lâaide dâun dictionnaire nommĂ©, par convention, `CALLBACKS` :
```python
CALLBACKS = {
"": ac_connect
}
```
Ici, `ac_connect` est affectĂ© Ă une action dont le libellĂ© est une chaĂźne vide. Cette valeur correspond Ă lâaction qui est lancĂ©e Ă chaque nouvelle session.
## La boucle évÚnementielle
On va ensuite lancer la boucle Ă©vĂšnementielle de lâapplication, en lui passant le dictionnaire des actions, ainsi que le contenu du fichier `Head.html` dĂ©crit prĂ©cĂ©demment :
```python
atlastk.launch(CALLBACKS,None,open("Head.html").read())
```
Le paramÚtre dont la valeur est `None` sera abordé plus tard.
# Liste des contacts (`part2.py`)> * Code source : [lien sur GitHub](https://github.com/epeios-q37/atlas-python/blob/master/tutorials/Contacts/part2.py) ;> * exécution :> * sur [*Repl.it*](https://repl.it/@AtlasTK/atlas-python#tutorials/Contacts/part2.py) : bouton *Run*, `n2` + *entrée*, clic sur URL,> * en local : `python3 atlas-python/tutorials/Contacts/part2.py`
Dans cette section, nous allons programmer lâaffichage de la liste des contacts.
## Liste fictive
On va dâabord crĂ©er une liste de contacts fictive, histoire dâavoir quelque chose Ă afficher :
```python
EXAMPLE = [
{
"Name": "Holmes, Sherlock",
"Address": "221B Baker Street, Londres",
"Phone": "(use telegraph)",
"Note": "Great detective!"
},
{
"Name": "Holmes, Mycroft",
"Address": "Diogenes Club, Pall Mall, Londres",
"Phone": "(use telegraph)",
"Note": "Works for the British government.\nBrother of Holmes, Sherlock."
},
{
"Name": "Tintin",
"Address": "ChĂąteau de Moulinsart",
"Phone": "421",
"Note": "Has a dog named Snowy."
},
{
"Name": "Tournesol, Tryphon (prof.)",
"Address": "ChĂąteau de Moulinsart",
"Phone": "421",
"Note": "Creator of the Bianca rose."
}
]
```
On va affecter cette liste à une variable qui fera office de base de données :
```python
contacts = EXAMPLE
```
## Affichage
CrĂ©ons une fonction dĂ©diĂ©e Ă lâaffichage de cette liste :
```python
def display_contacts(dom):
html = ""
for contactId in range(len(contacts)):
contact = contacts[contactId]
html += f''
for key in contact:
html += f'| {contact[key]} | '
html += ''
dom.inner("Content", html)
```
Dans cette fonction, on rĂ©cupĂšre chaque contact de la liste, et, pour chacun de ces contacts, le contenu de chacun de ses champs. On va sâen servir pour crĂ©er le contenu du corps du tableau dĂ©diĂ© Ă lâaffichage de la liste, contenu qui sera stockĂ© dans la variable `html`.
Le contenu de cette variable est ensuite injectĂ© dans le corps de la table, plus prĂ©cisĂ©ment dans lâĂ©lĂ©ment `tbody` dâidentifiant `Content` (voir le fichier `Main.html`), grĂące Ă la mĂ©thode `inner(...)`, que lâon a dĂ©jĂ rencontrĂ©e. Notez que le premier paramĂštre nâest plus, comme auparavant, une chaĂźne de caractĂšres vide, mais bien lâidentifiant de lâĂ©lĂ©ment concernĂ©, Ă savoir `Content`.
Chaque ligne du tableau a son propre identifiant, et un attribut `data-xdh-onevent="Select"` qui fera lâobjet de la prochaine section.
Enfin, on ajoute lâappel Ă cette fonction dans la fonction `ac_connect(...)`, :
```python
def ac_connect(dom):
dom.inner("",open("Main.html").read())
display_contacts(dom)
```
# DĂ©tail dâun contact (`part3.py`)> * Code source : [lien sur GitHub](https://github.com/epeios-q37/atlas-python/blob/master/tutorials/Contacts/part3.py) ;> * exĂ©cution :> * sur [*Repl.it*](https://repl.it/@AtlasTK/atlas-python#tutorials/Contacts/part3.py) : bouton *Run*, `n3` + *entrĂ©e*, clic sur URL,> * en local : `python3 atlas-python/tutorials/Contacts/part3.py`
ProcĂ©dons maintenant Ă lâaffichage des dĂ©tails dâun contact sĂ©lectionnĂ© par lâutilisateur.
## Affichage
On va commencer par le remplissage des champs au sommet de lâinterface avec les valeurs du contact sĂ©lectionnĂ© dans la liste.
Voici la fonction correspondante :
```python
def display_contact(contactId,dom):
dom.set_values(contacts[contactId])
```
La mĂ©thode `set_values(...)` prend un dictionnaire avec, pour clefs, des identifiants dâĂ©lĂ©ments, et, pour valeurs, le contenu que doivent prendre ces Ă©lĂ©ments.
Comme, dans la page *HTML*, les identifiants des Ă©lĂ©ments sont identiques aux clefs correspondant aux champs dâun contact, le dictionnaire est dĂ©jĂ constituĂ© et nâest plus Ă construire. On lâutilise donc tel quel dans lâappel de la mĂ©thode `set_values(...)`.
`contactId` est lâindex, dans la liste `contacts`, du contact Ă afficher.
## Sélection
On va maintenant dĂ©finir la fonction que lâon va affecter Ă lâaction `Select` dĂ©finit dans lâattribut `data-xdh-onevent` du code *HTML* qui est crĂ©e dans la prĂ©cĂ©dente section :
```python
def ac_select(dom,id):
display_contact(int(id),dom)
```
Le paramĂštre `id` contient lâidentifiant de lâĂ©lĂ©ment recevant lâĂ©vĂšnement Ă lâorigine de lâaction Ă laquelle cette fonction a Ă©tĂ© affectĂ©e. Ici, lâĂ©vĂšnement est un clic sur une ligne du tableau contenant la liste des contacts, Ă©vĂšnement auquel a Ă©tĂ© associĂ©e lâaction `Select` via lâattribut `data-xdh-onevent`. ConformĂ©ment Ă ce qui va ĂȘtre dĂ©fini ci-dessous dans la variable `CALLBACKS`, cette action va lancer la fonction `ac_select`.
Dans la section prĂ©cĂ©dente, on a vu que, pour le tableau *HTML* contenant la liste des contacts, chaque ligne a pour identifiant lâindex, dans la table `contacts`, du contact correspondant. On peut donc utiliser directement `id`, aprĂšs lâavoir converti en entier (`id` est fourni sous forme dâune chaĂźne de caractĂšres), pour le passer Ă la fonction `display_contact(...)`
On met Ă jour la table `CALLBACKS`, en affectant cette fonction Ă lâaction `Select` (dĂ©finie comme valeur de lâattribut `data-xdh-onevent` dans le code *HTML* gĂ©nĂ©rĂ© dans la prĂ©cĂ©dente section) :
```python
CALLBACKS = {
...
"Select": ac_select
}
```
# *Ă suivre...*
Sur les recommandations de lâĂ©quipe de modĂ©ration, ce document a Ă©tĂ© dĂ©coupĂ© en deux dĂ©pĂȘches.
Celle-ci prĂ©sentait le fichier *HTML* principal, celui des mĂ©tadonnĂ©es, ainsi que les principales fonctions relatives Ă lâaffichage. La [seconde dĂ©pĂȘche](https://q37.info/s/jz9ttdjb) portera sur la gestion des Ă©vĂšnements.