Site d’une école de langues
Ce projet a consisté à refaire le site d’une école de langues à l’intérieur de son WordPress existant, puis à lui écrire un module d’inscription avec devis, courriels et PDF, sur un hébergement mutualisé qui n’offre que le FTP.
- Rôle
- Auteur unique, pour le compte de l’école
- Période
- De juin à septembre 2026
- État
- En service. En service
- Technologies
- WordPress, PHP, MariaDB, Docker Compose, GlitchTip
- Dépôts
- Deux
Contexte
L’école enseigne des langues en ligne et en présentiel. Le travail s’est fait en deux temps. Un site statique de quatre pages, accompagné d’une charte, a d’abord fixé le dessin ; ce dessin a ensuite été reconstruit dans le WordPress de l’école, sous la forme d’un thème enfant et de blocs que son équipe peut modifier. Un module d’inscription a été écrit pour finir, avec ses grilles tarifaires, son devis, ses courriels et son PDF.
Le site est en service à l’adresse iforla.com ; les données de l’école ne figurent pas dans cette étude, qui s’en tient à la manière de travailler.

Problème
L’hébergement du site n’accepte que le FTP : ni accès distant par clés, ni environnement de recette. Une livraison y est donc un envoi de fichiers sur un site en service, sans filet. Il fallait par ailleurs pouvoir reproduire sur le poste l’état exact de la production, alors que WordPress conserve ses adresses dans la base sous plusieurs formes.
Réponse apportée
Un envoi encadré
Chaque envoi suit le même ordre : télécharger la version en ligne dans un répertoire de sauvegarde daté, envoyer les fichiers, les télécharger de nouveau, puis comparer leur empreinte à celle des fichiers locaux. Le site porte un numéro de build unique, relevé à chaque livraison, affiché dans l’administration et consigné dans un journal avec le périmètre de la livraison et sa vérification. Les scripts qui suppriment des données ne font rien sans un argument explicite : leur exécution par défaut se borne à lister ce qu’ils feraient.
Une pile locale réalignée sur la production
La pile locale se reconstruit à partir d’une sauvegarde de la production. Le script commence par sauvegarder la base locale, afin de pouvoir revenir en arrière, puis réécrit les adresses en quatre passes, l’éditeur de blocs conservant dans ses contenus des adresses dont les barres obliques sont échappées.
# The block editor stores slash-escaped URLs inside post_content JSON, so the
# plain pass alone leaves half of them behind. WP-CLI's "Replacements" column
# counts ROWS, not occurrences: a low number does not mean a pass was useless.
echo "==> 3/6 rewriting https://$PROD_HOST -> $SITE_URL (4 passes)"
for from in "https://$PROD_HOST" "http://$PROD_HOST"; do
wp search-replace "$from" "$SITE_URL" --all-tables --skip-columns=guid --report-changed-only
done
for from in "https:\\/\\/$PROD_HOST" "http:\\/\\/$PROD_HOST"; do
wp search-replace "$from" "http:\\/\\/localhost:8080" --all-tables --skip-columns=guid --report-changed-only
doneDu code propre là où l’extension ne suffisait pas
L’extension de formulaires en place n’affichait pas de parcours en plusieurs étapes dans sa version gratuite. Le module d’inscription l’a remplacée : il est piloté par un seul fichier de schéma, possède sa propre table, conserve le prix d’une inscription lorsque les grilles changent, et applique une durée de conservation par une tâche quotidienne, en plus de l’export et de l’effacement que WordPress prévoit pour les données personnelles. Deux lacunes de la plateforme ont été comblées de la même façon, à savoir une langue masquée qui restait accessible par son adresse et les redirections d’anciennes adresses que WordPress refuse aux pages.
Limites et perspectives
Le FTP, qui est le seul canal qu’offre l’hébergeur, n’est pas chiffré, et une partie des opérations se saisit encore à la main dans le terminal qu’il propose. Les livraisons se font par des scripts écrits pour chaque changement plutôt que par un outil unique, et aucun environnement de recette ne les précède.
Le thème et les modules ne comportent aucun test automatisé : la vérification repose sur des scripts de contrôle lancés après l’envoi et sur une liste de points à parcourir dans le navigateur. L’ancienne extension de formulaires et son validateur sont enfin restés en place après le remplacement, et la documentation d’intégration n’a pas suivi tous les changements de langues.


