Files
f3-simple-blog/README.md
julien b4a80013d5 Doc
2026-03-30 00:23:34 +02:00

5.2 KiB
Raw Blame History

F3 Simple Blog

Blog simple construit avec Fat-Free Framework et SQLite.

Le projet vise un blog léger, lisible et facile à déployer, avec un petit back-office dadministration, une médiathèque locale et un rendu Markdown sécurisé.

Fonctionnalités

  • listing public des articles avec pagination ;
  • page article ;
  • authentification admin ;
  • création, modification et suppression darticles ;
  • médiathèque locale avec upload, texte alternatif, copie de la syntaxe Markdown et suppression ;
  • vignette de carte dérivée de la première image du contenu ;
  • rendu Markdown avec images locales media:... ;
  • stockage des images en JPG/PNG bruts sans transformation.

Structure

project/
├── app/
│   ├── bootstrap.php
│   ├── config.ini
│   ├── helpers.php
│   ├── Controllers/
│   ├── Models/
│   ├── Services/
│   └── Views/
├── db/
├── logs/
├── public/
│   ├── assets/
│   └── uploads/media/
├── docker/
├── scripts/
│   ├── bootstrap.php
│   ├── install.php
│   └── create-admin.php
└── tmp/uploads/

Architecture

Le backend sappuie sur un petit noyau :

  • SiteController : pages publiques ;
  • AuthController : connexion / déconnexion ;
  • AdminController : back-office articles et médiathèque ;
  • Controller : rendu, session courante, flash, CSRF ;
  • Post, Media, User : modèles DB\SQL\Mapper ;
  • MarkdownService : compilation et sanitation du contenu Markdown.

Intégration F3

Le projet utilise directement les briques natives du framework :

  • routes et aliases dans app/config.ini ;
  • DB\SQL\Mapper pour les tables principales ;
  • Auth pour la connexion ;
  • Session pour la session ;
  • Template pour le rendu ;
  • Web::receive() pour la réception des uploads ;
  • Markdown pour le parsing Markdown ;
  • Web::slug() pour les slugs.

Contenu et médiathèque

Les articles contiennent leur texte en Markdown. Les images sont insérées dans le corps du contenu, et la première image rendue dans body_html sert de vignette dans les cartes darticle.

Les images du contenu utilisent la syntaxe :

![Texte alternatif](media:nom-de-fichier.jpg)

La médiathèque :

  • accepte uniquement JPG et PNG ;
  • vérifie que le fichier reçu est bien une image ;
  • conserve le fichier tel quel, sans réencodage ;
  • stocke en base le nom du fichier, le texte alternatif, la largeur, la hauteur et la date de création.

Contrat Markdown

Le rendu Markdown suit les règles suivantes :

  • le HTML brut saisi par lauteur nest pas rendu ;
  • les liens sont filtrés avant rendu ;
  • seules les images locales en media:... sont rendues ;
  • les images externes ne sont pas affichées ;
  • avec le parseur Markdown de F3, il faut laisser une ligne vide entre deux blocs (titre, liste, citation, image, code) pour un rendu fiable.

Sécurité

Le projet inclut :

  • session dadministration ;
  • jeton CSRF sur les formulaires ;
  • rotation du jeton CSRF après connexion et déconnexion ;
  • sanitation du HTML produit à partir du Markdown ;
  • validation des uploads image ;
  • cookies httponly et samesite=Lax.

Pré-requis

Développement local

  • PHP 8.3+
  • Composer
  • extensions PHP : pdo_sqlite, mbstring, intl, dom

Déploiement Docker

  • Docker
  • Docker Compose

Démarrage local

composer install
cp config.local.ini.example config.local.ini
php scripts/install.php
php -S 127.0.0.1:8080 -t public

Puis ouvrir http://127.0.0.1:8080.

Créer un compte admin :

php scripts/create-admin.php admin

Configuration

Le fichier app/config.ini contient les valeurs par défaut. Tu peux les surcharger dans config.local.ini.

Exemple minimal en production :

[globals]
app.env=prod
app.timezone=Europe/Paris

Le paramètre app.env doit être défini à prod sur un déploiement réel.

Déploiement Docker derrière Caddy

Déploiement Docker recommandé :

  • Apache sert public/ dans le conteneur ;
  • compose.yaml expose lapplication sur 127.0.0.1:8888 par défaut ;
  • Caddy termine TLS et reverse-proxy vers cette cible ;
  • SQLite, les logs et les uploads sont montés sur des volumes persistants.

Exemple :

cp config.local.ini.example config.local.ini
# édite config.local.ini : app.env=prod
docker compose up -d --build

Créer un compte admin dans le conteneur :

docker compose exec app php scripts/create-admin.php admin

La commande demande ensuite le mot de passe du compte.

Le Caddyfile.example fournit une base de reverse proxy. En production, il faut exposer publiquement Caddy uniquement. Lapplication Apache/PHP ne doit pas être accessible directement depuis Internet.

Sauvegarde

Pour sauvegarder le blog, il faut au minimum conserver :

  • db/app.sqlite
  • public/uploads/media/

Les logs peuvent aussi être conservés si tu veux garder lhistorique derreurs.

Limites assumées

  • base SQLite ;
  • instance applicative unique ;
  • pas de système de migrations automatique ;
  • en cas de changement de schéma, une migration manuelle ou une base recréée sera nécessaire.