julien 4aa7cc2d15 Doc
2026-03-30 00:12:11 +02:00
2026-03-30 00:00:03 +02:00
2026-03-27 14:43:08 +01:00
2026-03-29 21:01:07 +02:00
2026-03-27 14:43:08 +01:00
2026-03-30 00:00:03 +02:00
2026-03-30 00:00:03 +02:00
2026-03-27 22:30:10 +01:00
2026-03-27 22:50:42 +01:00
2026-03-29 01:49:25 +01:00
2026-03-29 01:49:25 +01:00
2026-03-30 00:00:03 +02:00
2026-03-27 22:56:24 +01:00
Doc
2026-03-30 00:04:18 +02:00
2026-03-30 00:00:03 +02:00
Doc
2026-03-30 00:12:11 +02:00

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 ne possèdent pas de champ “image de couverture”. Les images vivent dans le corps Markdown, 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 forcé à prod sur un déploiement réel.

Déploiement Docker derrière Caddy

Le projet est prévu pour un déploiement simple :

  • 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

Le script te demandera 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.
Description
No description provided
Readme 301 KiB
Languages
PHP 48.4%
HTML 20.6%
CSS 19.7%
JavaScript 7.1%
Dockerfile 2.6%
Other 1.6%