Faire un site one page avec un pad

Voyons ce que cela coûte de générer un très simple site depuis un pad

Article pas relu

Le besoin

Imaginons un festival artistico-militanto-écolo en Moselle. Il a pour habitude de communiquer sur facebook et instagram (bouuuh). Il a tout de même un linktree avec le programme et quelques infos (mieux). A la fin du festival une personne fait la remarque que ce serait tout de même chouette d’avoir un vrai site avec les infos de bases. Sauf que c’est un peu ennuyant à faire, difficile à éditer etc.

De manière générale les personnes sont à l’aise avec l’édition d’un pad. C’est un bel outil dont il n’existe pas d’alternative dans le monde termino-unixien. En terme d’appli web y’a vraiment pire qu’etherpad.

Et si l’on faisait tenir tout le site sur une page, générée depuis le markdown d’un pad édité par tout le monde ?

Pour faire des tests j’ai hébergé le site ici : http://ire.bebou.netlib.re
Et le pad ici : http://pad.unistra.fr/p/ire
Ca peut casser n’importe quand. SVP spammer pas les modifs.

La proposition

Récupérer le contenu et en faire de l’HTML

On peut récupérer le contenu d’un pad en le réquêtant avec /export/txt ajouté à la fin :

$ curl -Ls https://pad.unistra.fr/p/ire/export/txt
## Blablabla

machin

On peut mettre ça dans lowdown pour générer de l’html :

$ curl -Ls https://pad.unistra.fr/p/ire/export/txt | lowdown
<h2 id="blablabla">Blablabla</h2>

<p>machin</p>

Si on met ça dans une petite boucle while on peut vérifier s’il s’est passé quelque chose toutes les N secondes :

while :;do
    curl -Ls https://pad.unistra.fr/p/ire/export/txt | lowdown > index.html
    sleep N
done

Ne pas spammer le pauvre pad de l’unistra

Sauf que c’est bof de spammer le pad donc imaginons autre chose. En se basant sur le système de qcm on peut ajouter un lien dans le pad qui, lorsque l’on clique dessus, déclenchera la mise à jour du site via la détection du chemin dans les logs du serveur web. Il faudra mettre en place le nécessaire pour filtrer les logs et le lien dans le pad :

[ -p "notif" ] || mkfifo "notif"
tail -Fn0 "/var/log/nginx/access.log" |
    grep --line-buffered -E "/mise-a-jour" > "notif" &
notifpid=$!

cat "notif" | while read maj; do
    curl -Ls https://pad.unistra.fr/p/ire/export/txt |
        grep -v 'http://ire.bebou.netlib.re/mise-a-jour' |
        lowdown > index.html
done

Pour éviter de refaire des calculs s’il n’y a pas eu de modif on peut enregistrer le markdown et tester s’il est identique à l’ancien avec un diff :

cat "notif" | while read maj; do
    curl -Ls https://pad.unistra.fr/p/ire/export/txt |
        grep -v 'http://ire.bebou.netlib.re/mise-a-jour' > index-new.md
    if ! diff index.md index-new.md 2> /dev/null;then
            mv index-new.md index.md
            < index.md lowdown > index.html
    fi
done

Le versionnage automatique

Finalement pour éviter de perdre quoi que ce soit on pourra giter le tout :

cat "notif" | while read maj; do
    curl -Ls https://pad.unistra.fr/p/ire/export/txt |
        grep -v 'http://ire.bebou.netlib.re/mise-a-jour' > index-new.md
    if ! diff index.md index-new.md 2> /dev/null;then
            mv index-new.md index.md
            < index.md lowdown > index.html
    fi
    git add index.html index.md
    git commit -m "Modification"
    git push
done

Évidemment on pourra mettre une quantité arbitraire de code dans le while pour avoir un squelette html décent, un nav dynamique ou autre.

La version minimale finale

Au final la version “minimale” du concept pour un serveur nginx pourrait être :

[ -p "notif" ] || mkfifo "notif"
tail -Fn0 "/var/log/nginx/access.log" |
    grep --line-buffered -E "/mise-a-jour" > "notif" &
notifpid=$!

cat "notif" | while read maj; do
    curl -Ls https://pad.unistra.fr/p/ire/export/txt |
        grep -v 'http://ire.bebou.netlib.re/mise-a-jour' > index-new.md
    if ! diff index.md index-new.md 2> /dev/null;then
            mv index-new.md index.md
            < index.md lowdown > index.html
    fi
    git add index.html index.md
    git commit -m "Modification"
    git push
done

kill $notifpid

Les limites

A priori ça fonctionne pas mal pour une page mais ça devient compliqué pour plus. C’est possible d’avoir un séparateur dans le pad qui délimite plusieurs pages différentes puis de les séparer côté serveur mais ça risque de devenir assez rapidement fastidieux à éditer.

On peut intégrer des images déjà en ligne avec ![]() mais comment fait-on pour uploader de nouvelles images, pdf etc ?

Il n’est pas possible d’éditer le css et l’html depuis le pad, que le contenu. Ça peut éventuellement être un avantage selon le contexte. Avec plus de code côté serveur c’est possible mais possiblement trop compliqué pour ce que l’on voulait faire.

Si le pad est public il faut bien le cacher sinon n’importe qui pourra faire des modifications. Au pire des cas git devrait pouvoir nous permettre de revenir à un état antérieur.

Il n’est, je crois, pas possible d’utiliser ce système via un éditeur de texte classique + git. Dans tous les cas à la prochaine modif du pad le contenu du site sera écrasé. On a donc pas une accessibilité chouette à la fois pour les personnes voulant y accéder via un navigateur web et des cli 😔.

Le script ne redirige pas les erreurs potentielles du script à un endroit où les personnes peuvent les lire et les communiquer à l’admin. Ça devrait pouvoir se modifier assez facilement.

Les instances d’etherpad peuvent trouver que vous les curlez un peu trop rapidement et vous blacklister pendant un moment. Il vaut donc mieux ne pas trop fréquemment chercher à voir les résultats des modifications.