Documentation 🇫🇷
Documentation sansCMS
Bienvenue dans la documentation complète de sansCMS, un système de gestion de contenu simple et léger basé sur les fichiers Markdown.
Présentation
sansCMS est un système de gestion de contenu (CMS) léger, rapide et sans base de données. Il utilise des fichiers Markdown pour stocker le contenu et offre un système de cache performant avec TTL personnalisables.
Caractéristiques principales
- ✅ Sans base de données : Utilise uniquement des fichiers Markdown
- ⚡ Système de cache intelligent avec TTL personnalisables
- 📊 Statistiques de visites avec tracking IP unique
- 🎨 Thèmes multiples avec sélecteur intégré
- 🔒 Pages privées protégées par mot de passe
- 🔍 SEO optimisé (sitemap, RSS, meta tags)
- 📱 Responsive basé sur Pico CSS
- 📧 Formulaire de contact intégré
- 🚀 Haute performance avec compression et minification
Architecture
sansCMS/
├── cache/ # Cache système (protégé)
│ ├── markdown/ # Cache des rendus Markdown
│ ├── pages/ # Cache des pages complètes
│ └── stats/ # Cache des statistiques
├── config/ # Fichiers de configuration
│ └── site.json # Configuration principale
├── libs/ # Bibliothèques tierces
│ └── Parsedown.php # Parser Markdown
├── logs/ # Logs et statistiques
│ └── stats.json # Données de tracking
├── pages/ # Contenu Markdown
│ ├── 1-home.md # Page d'accueil
│ ├── 2-contact.md # Page de contact
│ └── *.md # Autres pages/articles
├── src/ # Code source PHP
│ ├── CacheManager.php # Gestion du cache
│ ├── ConfigLoader.php # Chargement configuration
│ ├── ContactFormHandler.php # Gestion formulaire contact
│ ├── MarkdownParser.php # Parser Markdown avec cache
│ ├── OutputOptimizer.php # Optimisation sortie HTML
│ ├── Page.php # Classe Page
│ ├── Router.php # Routage des requêtes
│ ├── sansCMS.php # Classe principale
│ └── StatsTracker.php # Tracking statistiques
├── themes/ # Thèmes visuels
│ └── pico/ # Thème par défaut
├── index.php # Point d'entrée
└── .htaccess # Configuration ApacheInstallation
- Télécharger le projet sur votre serveur web
- Vérifier que PHP 7.4+ est installé
- Configurer le serveur web (Apache ou Nginx)
- Créer le fichier
config/site.json(généré automatiquement au premier lancement)
Configuration du serveur
Apache
Le fichier .htaccess est créé automatiquement :
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [L]
Options -IndexesNginx
Configuration générée dans nginx-site.conf :
server {
listen 80;
server_name localhost;
root /path/to/sansCMS;
index index.php;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass unix:/var/run/php/php-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
location ~* \.md$ {
deny all;
return 403;
}
}Configuration (site.json)
{
"site": {
"name": "Mon Site",
"description": "Description de mon site",
"contact_email": "email@example.com",
"contact_subjects": {
"general": "Question générale",
"support": "Demande de support",
"business": "Demande commerciale",
"bug": "Signalement de bug",
"suggestion": "Suggestion d'amélioration"
}
},
"blog": {
"url": "blog",
"name": "Blog",
"description": "Découvrez nos articles"
},
"theme": {
"name": "pico",
"posts_per_page": 8
},
"features": {
"cache_enabled": true,
"cache_ttl": {
"markdown": 3600, // 1 heure
"pages": 7200, // 2 heures
"stats": 300, // 5 minutes
"rss": 3600, // 1 heure
"sitemap": 86400 // 24 heures
},
"stats_enabled": true,
"stats_access_enabled": true,
"session_timeout": 1800,
"rate_limit_enabled": true
},
"performance": {
"lazy_load_pages": true,
"compress_output": true,
"minify_html": false
},
"debug": {
"enabled": false,
"level": "INFO",
"log_to_file": true,
"display_errors": false
},
"seo": {
"meta_keywords": "cms, markdown, blog",
"robots": "index, follow",
"rss_enabled": true
}
}Format des fichiers Markdown
Structure de base
---
titre: Titre de la page
description: Description pour le SEO
date: 2024-01-15
auteur: Nom de l'auteur
tags: tag1, tag2, tag3
permalien: mon-article
---
Contenu de votre page en **Markdown**.
## Titre niveau 2
Votre texte avec des [liens](https://example.com).Métadonnées disponibles
| Champ | Type | Description |
|---|---|---|
titre | string | Titre de la page/article |
description | string | Description SEO |
date | date | Date de publication (format: YYYY-MM-DD) |
auteur | string | Nom de l'auteur |
tags | string | Tags séparés par des virgules |
permalien | string | URL personnalisée |
prive | string | Hash du mot de passe (bcrypt) |
brouillon | boolean | Masquer de la publication |
cacher | boolean | Masquer de la navigation mais accessible via URL |
Page privée
Pour créer une page privée :
---
titre: Page Privée
prive: $2y$10$example_bcrypt_hash
---Générer le hash bcrypt en PHP :
echo password_hash('mon_mot_de_passe', PASSWORD_BCRYPT);Table des matières automatique
Insérer [TOC] ou [TOC:Titre personnalisé] dans votre contenu :
[TOC:Sommaire]
### Section 1
Contenu...
### Section 2
Contenu...Système de cache
Architecture du cache
Le système utilise trois niveaux de cache :
- Cache Markdown : Rendus HTML des fichiers .md
- Cache Pages : Pages complètes avec templates
- Cache Stats : Statistiques pré-calculées
TTL Personnalisables
Les durées de vie (TTL) sont configurables indépendamment :
"cache_ttl": {
"markdown": 3600, // Rendu Markdown (1h)
"pages": 7200, // Pages complètes (2h)
"stats": 300, // Statistiques (5min)
"rss": 3600, // Flux RSS (1h)
"sitemap": 86400 // Sitemap XML (24h)
}Gestion du cache
// Vider tout le cache
CacheManager::clearAll();
// Vider uniquement le cache Markdown
CacheManager::clearMarkdownCache();
// Obtenir les statistiques du cache
$stats = CacheManager::getStats();
// Nettoyer les fichiers expirés
CacheManager::cleanExpired();Page d'administration
Accéder à /cache-admin (nécessite debug.enabled: true) pour :
- Visualiser les statistiques du cache
- Vider le cache sélectivement
- Voir les détails des fichiers en cache
Système de statistiques
Fonctionnalités
- Comptage des vues uniques par IP
- Statistiques par jour/heure
- Pages populaires
- Rapports hebdomadaires
- Cache de 5 minutes pour les performances
Utilisation
// Obtenir les stats des 30 derniers jours
$stats = StatsTracker::getStats(30);
// Obtenir un rapport texte
$report = StatsTracker::getSimpleReport(7);
// Reconstruire le cache
StatsTracker::rebuildCache();Structure des données
[
'total_views' => 1234,
'pages_count' => 45,
'recent_days' => [
'2024-01-15' => 56,
'2024-01-14' => 42,
// ...
],
'popular_pages' => [
'/article' => [
'title' => 'Mon Article',
'total_views' => 234,
'type' => 'post'
]
]
]Routage
Routes disponibles
| Route | Description |
|---|---|
/ | Page d'accueil |
/blog | Liste des articles |
/blog?page=2 | Pagination |
/blog?tag=php | Filtrage par tag |
/blog?auteur=John | Filtrage par auteur |
/blog?q=recherche | Recherche |
/sitemap | Sitemap XML |
/rss | Flux RSS |
/stats | Statistiques |
/cache-admin | Admin cache (debug) |
/logout | Déconnexion pages privées |
Formulaire de contact
Configuration
Le formulaire utilise l'email configuré dans site.json :
"contact_email": "contact@example.com",
"contact_subjects": {
"general": "Question générale",
"support": "Support technique"
}Sécurité
- Protection CSRF avec tokens
- Honeypot anti-spam
- Validation côté serveur
- Rate limiting
Templates personnalisables
themes/pico/contact/
├── contact-form.php # Formulaire
├── contact-success.php # Message succès
├── contact-errors.php # Affichage erreurs
├── contact-sent.php # Confirmation envoi
└── email-contact.php # Template email HTMLOptimisation des performances
Compression de sortie
"compress_output": true // Active gzipMinification HTML
"minify_html": true // Supprime espaces inutilesOPcache
Activer OPcache dans php.ini :
opcache.enable=1
opcache.memory_consumption=128
opcache.max_accelerated_files=10000
opcache.revalidate_freq=2SEO
Features intégrées
- ✅ Sitemap XML automatique
- ✅ Flux RSS complet
- ✅ Meta tags Open Graph
- ✅ Twitter Cards
- ✅ URLs canoniques
- ✅ Pagination SEO-friendly
- ✅ Structured data
Optimisation
---
titre: Mon article SEO-optimisé
description: Description unique de 150-160 caractères
tags: mot-clé1, mot-clé2
---Sécurité
Protection des dossiers
Tous les dossiers sensibles sont protégés automatiquement :
cache/→ Accès refuséconfig/→ Accès refusélogs/→ Accès refusésrc/→ Accès refusépages/→ Fichiers .md non accessibles
Sessions
"session_timeout": 1800 // 30 minutesRate Limiting
Protection contre les abus sur les formulaires.
Debugging
Activer le mode debug
"debug": {
"enabled": true,
"level": "INFO",
"display_errors": true
}Métriques affichées
- ⏱️ Temps d'exécution
- 💾 Mémoire utilisée
- 📊 Statistiques du cache
- 🔧 Configuration active
- ⚡ OPcache status
API et Helpers
ConfigLoader
// Obtenir une valeur
$value = ConfigLoader::get('site.name');
$value = ConfigLoader::get('missing.key', 'default');
// Vérifier une feature
if (ConfigLoader::isFeatureEnabled('cache')) {
// Cache activé
}
// Obtenir un TTL spécifique
$ttl = ConfigLoader::getCacheTTL('markdown');CacheManager
// Chemins
$cache_dir = CacheManager::getCacheDir();
$md_cache = CacheManager::getMarkdownCachePath();
// Statistiques
$stats = CacheManager::getStats();
$size = CacheManager::getTotalSize();
// Nettoyage
CacheManager::clearAll();
CacheManager::clearMarkdownCache();
CacheManager::cleanExpired(3600);
// Protection
$checks = CacheManager::checkProtection();MarkdownParser
// Parser avec cache
$result = MarkdownParser::parse($content, $source_file);
// ['metadata' => [], 'content' => '...']
// Statistiques
$stats = MarkdownParser::getCacheStats();
$size = MarkdownParser::getCacheSize();
$details = MarkdownParser::getCacheDetails();
// Nettoyage
MarkdownParser::clearCache();Migration et Maintenance
Sauvegarde
Fichiers à sauvegarder régulièrement :
config/site.json
pages/*.md
logs/stats.jsonRestauration
- Restaurer les fichiers
- Le cache sera régénéré automatiquement
Mise à jour
- Sauvegarder
config/etpages/ - Remplacer les fichiers système
- Vérifier
config/site.jsonpour nouvelles options - Vider le cache :
/cache-admin
Dépannage
Le cache ne fonctionne pas
- Vérifier
cache_enabled: truedanssite.json - Vérifier les permissions du dossier
cache/ - Vérifier les logs en mode debug
Les statistiques ne s'affichent pas
- Vérifier
stats_enabled: true - Vérifier les permissions de
logs/ - Vérifier
stats_access_enabledpour l'URL/stats
Erreur 500
- Activer le mode debug
- Vérifier les logs PHP
- Vérifier les permissions des dossiers
- Vérifier la syntaxe du
site.json
Pages privées ne fonctionnent pas
- Vérifier que le hash bcrypt est correct
- Vérifier que les sessions PHP fonctionnent
- Vérifier
session_timeoutdans la config
License
- See LICENSE file for details
Support
For support and questions, please visit the project repository or contact the development team.
Version: 1.0.0-stable
Dernière mise à jour: Novembre 2025