Créer un site statique minimaliste avec Flask et Frozen Flask

David Dahan
Jan 2017 5 min
tech
web
python
flask
static

J’étais récemment à la recherche d’une solution simple et élégante pour refaire mon site perso. Je voulais un site simplissime qui ne contienne que 3 pages, et soit simple à créer ou maintenir. Plein de possibilités techniques se sont alors présentées à moi. Eliminons-les une par une pour choisir la plus élégante. Je vous montrerai ensuite la réalisation, un jeu d’enfant.

Possibilité A → réaliser un site “classique” ?

Un site classique, nécessite un serveur (et la config / maintenance associée) et donc un hébergement payant. Et en plus, plus lent à servir qu’un site statique. Et surtout, je n’en ai pas besoin, puisque le site n’a pas vocation à être dynamique. Abandon de cette idée !

Possibilité B → 3 pages HTML seules ?

A dire vrai, c’est comme ça que j’ai commencé. Sauf que, sur mon site, il y a un menu qui s’affiche sur chacune des pages. J’ai donc dû copier-coller ce menu 3 fois. C’est pas DRY, et même si pour un site de cette taille, ça reste acceptable, c’est tout de même assez dégueulasse, surtout si le site est amené à grossir. Le risque d’erreur en faisant des mises à jour est fort. Abandon de cette idée !

Possibilité C → un générateur de sites statiques ? (Jekyll and co.)

Ces outils sont sûrement géniaux, mais ils ont tendance à être un peu usine à gaz en terme de features. Je dis pas, si vous voulez faire un blog statique, c’est sûrement une excellente solution, mais ça demandera un peu de boulot derrière. Il existe des templates réutilisables, mais malgré tout, ça nécessite un peu de pratique.

En attendant, pour faire 3 pages HTMLs simples, ça me frustre de devoir lire une doc dans le détail pour des features qui me servent pas, de faire de la config, de faire attention au versionning, etc. Après tout, j’ai juste besoin d’un tag {% extend %} pour être capable d’être DRY. Abandon de cette idée !

D, la réponse D → un micro-framework + un package de génération statique

La solution ! Vous connaissez Flask ? C’est un micro-framework Python permettant de faire un site dans 1 seul fichier. Pas de boilerplate, prise en main instantannée. Le tutorial se fait en quelques dizaines de minutes, et il n’est même pas nécessaire pour réaliser notre site statique.

Pour vous donner une idée, voilà à quoi ressemble le site :

from flask import Flask, render_template

app = Flask(__name__)  # create the application instance :)
app.config.from_object(__name__)  # load config from this file


# External URLs
ext_urls = dict(
    linked_in="https://www.linkedin.com/in/daviddahanepita",
    medium="https://medium.com/@ddahan/latest",
    mailto="mailto:fake@david-dahan.com",
    magnetiz="http://www.magnetiz.fr",
    padam="http://padambus.com",
    auchan="https://www.auchandirect.fr"
)


# Views
@app.route('/')
def landing():
    return render_template('landing.html', ext_urls=ext_urls)

@app.route('/projects/')
def projects():
    return render_template('projects.html', ext_urls=ext_urls)

@app.route('/consulting/')
def consulting():
    return render_template('consulting.html', ext_urls=ext_urls)

Le code parle de lui-même : 2 lignes pour initialiser le site, un dictionnaire contenant des URLs que je vais réutiliser au sein de mes pages, et 3 routes qui appellent les bons templates. A côté de ce fichier python cohabitent 2 dossiers static/ et templates/ aux noms explicites. On peut difficilement faire plus simple.

Les templates html sont dynamiques car ils utilisent le système de tags de Jinja2 (moteur de templating intégré à Flask), et permettent donc de rester DRY. Par exemple, voici la page d’accueil, qui hérite d’un fichier base.html qui contient mon menu :

{% extends "base.html" %} {% block body %}

<div class="container">
  <div class="text-zone presentation">
    <h1>Hello!</h1>
    <p class="lead">
      I'm David, 28, French <a href="{{ url_for('consulting') }}">Freelancer</a> and
      <a href="{{ ext_urls['magnetiz'] }}" target="_blank">Founder</a>, living in Paris.<br />
      I work as a Back-End Engineer using Python and Django.<br />
      Check my <a href="{{ url_for('projects') }}">Projects</a>,
      <a href="{{ ext_urls['medium'] }}" target="_blank">Blog articles</a> or
      <a href="{{ ext_urls['linked_in'] }}" target="_blank">Resume</a>.
    </p>
  </div>
</div>

{% endblock %}

T’es mignon, mais ceci est un site classique, pas un site statique !?

Tout à fait. C’est là qu’intervient Frozen Flask. Ce package a pour vocation a parcourir un site Flask automatiquement pour générer le site statique correspondant. Et dans les cas les plus simples (comme ici), ça fonctionne instantanément.

On crée un fichier freeze.py simplissime :

from flask_frozen import Freezer
from siteperso import app

freezer = Freezer(app)

if __name__ == '__main__':
    freezer.freeze()

L’exécution de ce fichier génère un dossier build/ contenant l’ensemble du site statique. Fini !

Il ne vous reste plus qu’à uploader le contenu de ce dossier sur votre hébergeur de site statique gratuit (Github ou Firebase pour ne citer qu’eux).


written by
David Dahan
4 likes