Tu deviendras web designer, mon fils

Magazine
Marque
GNU/Linux Magazine
Numéro
167
Mois de parution
janvier 2014
Spécialité(s)


Résumé
Nous avons récemment [GLMF 166] vu comment créer facilement une application Web avec Flask. S'il s'avère relativement simple, muni de quelques connaissances python, de produire un Web Service fonctionnel, réaliser une application moderne, responsive, mais surtout jolie, peut se transformer en véritable cauchemar pour le quidam dont les connaissances en web design se limitent au strict minimum .

Body

Fort heureusement, il existe de nos jours de nombreuses béquilles qui aident les déficients de l'ergonomie que nous sommes et, parmi elles, le module python WTForms et le framework Bootstrap qui nous permettrons respectivement de générer des formulaires propres et de produire une interface de belle facture.

1. Au début était le moche

Nous démarrerons notre expérience par la création d'une application Flask basique: Un formulaire de trois champs dont le résultat sera inscrit dans un fichier plat après validation.

Le code Flask est le suivant :

$ cat basic.py
from flask import Flask, request, render_template
app = Flask(__name__)
@app.route(‘/’, methods=[‘GET’, ‘POST’])
def basicform():
if request.method == ‘POST’:
with open(‘/tmp/test.txt’, ‘w’) as f:
for k in request.form:
f.write(‘{0}: {1}\n’.format(k, request.form[k]))
return render_template(‘basic.html’)
if __name__ == ‘__main__’:
app.run(debug=True)

Et le template associé :

$ cat templates/basic.html
<!doctype html>
<title>Bienvenue, visiteur du futur !</title>
<div class="content">
<h2>Identification</h2>
<hr>

<form method="POST" action="/">
<label>Utilisateur</label><br />
<input type="text" name="user" id="user"><br />
<label>Mot de passe</label><br />
<input type="password" name="passwd" id="passwd"><br />
<select name="active" id="active">
<option value="no">Non</option>
<option value="yes">Oui</option>
</select><br />
<input type="submit" name="action" value="register">
</form>
</div>

Sans surprise, ce duo produit l'interface suivante :

moche

Fig. 1 : Moche

C'est laid, c'est sur, mais surtout, que de caractères tapés pour un résultat aussi sommaire… Alors que nous utilisons un framework pour générer notre GUI, n'y a-t-il pas de moyen plus efficace pour produire ces sempiternels formulaires ?

2. C'est quoi ce !@#!@#

WTForms est un module python permettant de grandement factoriser la création de formulaires. En couplant la puissance du moteur de template Jinja2, nativement intégré à Flask et la souplesse de WTForms, il devient simplissime de générer des formulaires avec un minimum d'efforts.

Il suffit pour cela d'importer le type de champs souhaité, puis de faire hériter son formulaire de l'objet Form et d'y lister les différents types de données. Plus fort, WTForms permet sans beaucoup plus de travail d'intégrer des validateurs, afin de vérifier que le contenu des champs correspond bien à l'entrée souhaitée; par exemple, en vérifiant le nombre de caractères ou encore la valeur maximale d'une valeur.

Après avoir préalablement installé le module WTForms, par exemple via pip, nous créons un fichier forms.py contenant les champs du formulaire précédemment créé à la main :

from wtforms import Form, TextField, SelectField, SubmitField, PasswordField,
validators
class BasicForm(Form):
user = TextField(u’Utilisateur’, [validators.Length(min=4, max=20)])
passwd = PasswordField(u’Mot de passe’, [validators.Length(min=8, max=32)])
active = SelectField(u’Actif’, choices = [(‘yes’, ‘Yes’), (‘no’, ‘No’)])
action = SubmitField(u’Register’)

On importe cette classe dans notre fichier basic.py et instancions un objet form que l'on passera en paramètre à notre template, capable de l'utiliser via Jinja :

from flask import Flask, request, render_template, url_for
from forms import BasicForm
app = Flask(__name__)
@app.route(‘/’, methods=[‘GET’, ‘POST’])
def basicform():
form = BasicForm(request.form)
if request.method == ‘POST’ and form.validate():
with open(‘/tmp/test.txt’, ‘w’) as f:
for k in request.form:
f.write(‘{0}: {1}\n’.format(k, request.form[k]))
return render_template(‘basic.html’, form=form)
if __name__ == ‘__main__’:
app.run(debug=True)

On notera qu'on passe la requète en paramètre à la classe BasicForm, ceci afin de contrôler la validité des champs postés via notre formulaire.

Apprécions maintenant la puissance du duo Jinja/WTForms. Voici notre précédent template, réduit à un plus simple appareil :

$ cat templates/basic.html
<!doctype html>
<title>Bienvenue, visiteur du futur !</title>
<div class="content">
<h2>Identification</h2>
<hr>
<form method="POST" action="/">
{% for field in form %}
{{ field.label }}
{{ field }}<br />
{% endfor %}
</form>
</div>

Ah oui, ça oui, c'est classe (ah-ah jeu de mots involontaire). Dans ce minuscule template, nous bouclons sur le paramètre form que nous avons passé en paramètre et, pour chaque valeur, on affiche la propriété label, la chaîne de caractères spécifiée en premier paramètre des champs définis dans le fichier forms.py, et le champs lui même. WTForms se charge seul de placer correctement toutes les balises nécessaires et nomme les attributs selon le nom de la variable contenant l'objet à afficher.

moche2

Fig. 2 : Pouah...

3. Et tu nous prends pas pour des jambons des fois ?

Je sais, je sais, c'est toujours moche. Nous y venons.

Bootstrap est un framework libéré en Août 2011 par Twitter simplifiant de façon radicale la stylisation d'un site web. Son utilisation est remarquablement aisée et sa documentation limpide et concrète. Le champs d'action de Bootstrap va des formulaires aux barres de navigation, en passant par les labels et autres tableaux. Une particularité notable de Bootstrap, et l'un des aspects qui en font un projet extrêmement populaire, réside dans sa capacité native à gérer le Responsive Design, ou en termes moins flanbyesques, la capacité d'un site à s'adapter à tout type de périphériques: stations de travail aux écrans sur-dimentionnés, tablettes, smartphones… Cette fonctionnalité repose sur un concept clair et intelligent, Bootstrap découpe la fenêtre du navigateur en une grille de douze colonnes; en ajoutant à vos balises une classe de type col-<type>-<taille>, on sait exactement comment se positionnera l'élément dans la page.

Exemple :

<div class="col-xs-12 col-md-8">.col-xs-12 col-md-8</div>

Ici, pour un périphérique mobile, bénéficiant donc d'une taille réduite (xs pour extra small), on spécifie que l'élément <div> occupera 12 colonnes alors que pour un équipement de taille moyenne (md pour medium), il n'en occupera que 8.

De façon plus générale, la stylisation de tous les éléments d'un site web à l'aide de ce framework s'effectue en ajoutant des classes aux éléments souhaités, on rendra par exemple un bouton beau en lui appliquant les classes btn btn-default pour un design standard ou encore btn btn-primary pour un bouton sur lequel on veut mettre l'emphase.

Dans notre template, on “active” Bootstrap de façon triviale. Après avoir téléchargé l'archive de Bootstrap, on copie les fichiers dist/css/bootstrap.min.css et dist/css/bootstrap-theme.min.css dans le répertoire static de notre projet Flask. Il s'agit ici des versions minifiées, privées des retours à la ligne et espacements inutiles. Nous ne nous occupperons pas, dans cet article, des capacités JavaScript de Bootstrap, aussi nous ne copierons pas le fichier dist/js/bootstrap.min.js.

Voici l'allure de notre template bootstrapé :

<!doctype html>
<html>
<head>
<title>Bienvenue, visiteur du futur !</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel=stylesheet type=text/css href="{{ url_for(‘static’,
filename=’bootstrap.min.css’) }}" media="screen">
<link rel=stylesheet type=text/css href="{{ url_for(‘static’,
filename=’bootstrap-theme.min.css’) }}" media="screen">
</head>
<body>
<div class="content" style="padding: 10px; width: 300px;">
<form method="POST" action="/">
<fieldset>
<legend>Identification</legend>
{% for field in form %}
<div class="form-group">
{% if field.type == ‘SubmitField’ %}
{{ field(class="btn btn-primary") }}
{% else %}
{{ field.label }}
{{ field(class="form-control") }}
{% endif %}
</div>
{% endfor %}
</fieldset>
</form>
</div>
</body>
</html>

L'en-tête de ce template est très largement inspirée de l'exemple proposé sur le site de Bootstrap, que ces derniers recommandent de copier verbatim. La seule modification, outre l'absence de l'inclusion de la section JavaScript, réside dans l'utilisation de la fonction Flask url_for('static'), qui renvoie le répertoire contenant les éléments statiques du projet Flask.

La structure du formulaire est elle aussi dictée par la documentation de Bootstrap, cette simple organisation et l'ajout de la classe form-control aux éléments du formulaire a pour immédiate conséquence le rendu suivant :

beau

Fig. 3 : oooOOOOOoooh

Eh oui, tout ce temps je vous avais caché qu'en fait, je suis un puissant web designer r0x0r.

4. Je vois tes yeux briller

Vous imaginez bien que les possibilités du triptique Flask-WTForms-Bootstrap sont très vastes, pensez qu'en écrivant les macros Jinja adéquates, on peut encore factoriser de façon drastique une application web, si complexe soit-elle. Voici deux exemples de macros que j'utilise dans un projet professionnel articulé autour des composants que nous avons expérimenté :

{% set bs_col = ‘col-sm-8’ %}
{% macro input_text(field) -%}
<div class="form-group {{ bs_col }}">
{{ field.label }}
{% if ‘dsc’ in field.description %}
<small><em>( {{ field.description[‘dsc’] }} )</em></small>
{% endif %}
{{ field(class="form-control", placeholder=field.description[‘ph’]) }}
</div>
{%- endmacro %}
{% macro select(field) -%}
<div class="form-group {{ bs_col }}">
{{ field.label }}
{{ field(class="form-control") }}
</div>
{%- endmacro %}

Il est alors possible d'appeler des macros au sein d'autres templates Jinja grâce à la capacité de ce dernier module à importer des fichiers, tels que son langage originel python.

Pour finir, la courbe d'apprentissage des solutions présentées est relativement courte, essentiellement grâce aux excellentes documentations proposées par ces projets (tous Libres, je le rappelle), profitez donc de ces technologies modernes, pourvues d'un rendu exemplaire, qui ne manqueront certainement pas d'épater la galerie.

Liens

[1]: http://flask.pocoo.org/

[2]: http://fr.wikipedia.org/wiki/Responsive_Web_Design

[3]: http://wtforms.simplecodes.com

[4]: http://getbootstrap.com/

[5]: http://jinja.pocoo.org/




Article rédigé par

Par le(s) même(s) auteur(s)

SmolBSD : un système UNIX de 7 mégaoctets qui démarre en moins d’une seconde

Magazine
Marque
GNU/Linux Magazine
Numéro
265
Mois de parution
septembre 2023
Spécialité(s)
Résumé

Que de racolage en si peu de mots. Et pourtant si, c’est bien la promesse de cet article, comment parvenir à construire un système d’exploitation fonctionnel en moins de… 10 mégabits. Quelle est cette sorcellerie ? En utilisant une fonctionnalité prévue, mais pas utilisée à cet escient par le noyau NetBSD, nous allons lui faire subir un régime drastique !

La grande migration, Épisode II

Magazine
Marque
Linux Pratique
Numéro
138
Mois de parution
juillet 2023
Spécialité(s)
Résumé

Dans l’épisode précédent [1], nous avons posé les premières briques d’une infrastructure d’auto-hébergement : vm-bhyve comme solution de virtualisation, sous FreeBSD donc, Wireguard comme gestionnaire de tunnel, une petite instance t4g.nano, 2 cœurs ARM64 et 512M de RAM chez AWS et un premier succès de déplacement de machine virtuelle hébergeant un simple serveur web d’un serveur dédié vers notre infrastructure personnelle. Nous allons voir maintenant comment migrer en douceur une machine virtuelle concentrant les services de base d’une architecture à l’autre.

La grande migration, Épisode I

Magazine
Marque
Linux Pratique
Numéro
137
Mois de parution
mai 2023
Spécialité(s)
Résumé

Il arrive parfois un jour où, ça y est, vous avez pris votre décision, le courage et l’envie sont là, c’est le moment : on va migrer. D’une ancienne technologie à une plus récente, par impératif professionnel, personnel, parce que c’est plus cohérent dans vos nouvelles coutumes, vous voyez exactement de quoi je parle, on frappe dans ses mains, on regarde le chantier, et on dit à voix haute : c’est parti.

Les derniers articles Premiums

Les derniers articles Premium

Les nouvelles menaces liées à l’intelligence artificielle

Magazine
Marque
Contenu Premium
Spécialité(s)
Résumé

Sommes-nous proches de la singularité technologique ? Peu probable. Même si l’intelligence artificielle a fait un bond ces dernières années (elle est étudiée depuis des dizaines d’années), nous sommes loin d’en perdre le contrôle. Et pourtant, une partie de l’utilisation de l’intelligence artificielle échappe aux analystes. Eh oui ! Comme tout système, elle est utilisée par des acteurs malveillants essayant d’en tirer profit pécuniairement. Cet article met en exergue quelques-unes des applications de l’intelligence artificielle par des acteurs malveillants et décrit succinctement comment parer à leurs attaques.

Migration d’une collection Ansible à l’aide de fqcn_migration

Magazine
Marque
Contenu Premium
Spécialité(s)
Résumé

Distribuer du contenu Ansible réutilisable (rôle, playbooks) par l’intermédiaire d’une collection est devenu le standard dans l’écosystème de l’outil d’automatisation. Pour éviter tout conflit de noms, ces collections sont caractérisées par un nom unique, formé d’une espace de nom, qui peut-être employé par plusieurs collections (tel qu'ansible ou community) et d’un nom plus spécifique à la fonction de la collection en elle-même. Cependant, il arrive parfois qu’il faille migrer une collection d’un espace de noms à un autre, par exemple une collection personnelle ou communautaire qui passe à un espace de noms plus connus ou certifiés. De même, le nom même de la collection peut être amené à changer, si elle dépasse son périmètre d’origine ou que le produit qu’elle concerne est lui-même renommé.

Mise en place d'Overleaf Community pour l’écriture collaborative au sein de votre équipe

Magazine
Marque
Contenu Premium
Spécialité(s)
Résumé

Si vous utilisez LaTeX pour vos documents, vous connaissez vraisemblablement Overleaf qui vous permet de rédiger de manière collaborative depuis n’importe quel poste informatique connecté à Internet. Cependant, la version gratuite en ligne souffre de quelques limitations et le stockage de vos projets est externalisé chez l’éditeur du logiciel. Si vous désirez maîtriser vos données et avoir une installation locale de ce bel outil, cet article est fait pour vous.

Les listes de lecture

9 article(s) - ajoutée le 01/07/2020
Vous désirez apprendre le langage Python, mais ne savez pas trop par où commencer ? Cette liste de lecture vous permettra de faire vos premiers pas en découvrant l'écosystème de Python et en écrivant de petits scripts.
11 article(s) - ajoutée le 01/07/2020
La base de tout programme effectuant une tâche un tant soit peu complexe est un algorithme, une méthode permettant de manipuler des données pour obtenir un résultat attendu. Dans cette liste, vous pourrez découvrir quelques spécimens d'algorithmes.
10 article(s) - ajoutée le 01/07/2020
À quoi bon se targuer de posséder des pétaoctets de données si l'on est incapable d'analyser ces dernières ? Cette liste vous aidera à "faire parler" vos données.
Voir les 63 listes de lecture

Abonnez-vous maintenant

et profitez de tous les contenus en illimité

Je découvre les offres

Déjà abonné ? Connectez-vous