This commit is contained in:
julien
2026-03-09 15:14:57 +01:00
parent 50831ea83a
commit 4d678f1211
8 changed files with 86 additions and 30 deletions

19
.gitignore vendored
View File

@@ -1,13 +1,20 @@
# Environnement local # ============================================
# Environnement & Configuration
# ============================================
.env .env
# Composer # ============================================
# Dépendances Composer
# ============================================
/vendor/ /vendor/
composer.lock composer.lock
# Base de données SQLite # ============================================
/database/*.sqlite # Base de données
/database/*.db # ============================================
/database/
# Cache et logs # ============================================
# Cache & Logs
# ============================================
/var/ /var/

View File

@@ -15,7 +15,8 @@
"slim/psr7": "*", "slim/psr7": "*",
"twig/twig": "*", "twig/twig": "*",
"slim/twig-view": "^3.4", "slim/twig-view": "^3.4",
"catfan/medoo": "2.*" "catfan/medoo": "2.*",
"vlucas/phpdotenv": "^5.6"
}, },
"autoload": { "autoload": {
"psr-4": { "psr-4": {

View File

@@ -4,6 +4,12 @@ declare(strict_types=1);
require __DIR__ . '/../vendor/autoload.php'; require __DIR__ . '/../vendor/autoload.php';
use Dotenv\Dotenv;
// Charger les variables d'environnement
$dotenv = Dotenv::createImmutable(__DIR__ . '/..');
$dotenv->load();
use Slim\Factory\AppFactory; use Slim\Factory\AppFactory;
use Slim\Views\TwigMiddleware; use Slim\Views\TwigMiddleware;
use Slim\Views\Twig; use Slim\Views\Twig;
@@ -18,9 +24,12 @@ $env = $_ENV['APP_ENV'] ?? 'production';
$isDev = strtolower($env) === 'development'; $isDev = strtolower($env) === 'development';
// Dossier de cache Twig (false en dev, chemin en prod) // Dossier de cache Twig (false en dev, chemin en prod)
$twigCache = $isDev ? false : __DIR__ . '/../var/cache/twig'; $twigCache = false;
if ($twigCache && !is_dir($twigCache)) { if (!$isDev) {
@mkdir($twigCache, 0755, true); $twigCache = __DIR__ . '/../var/cache/twig';
if (!is_dir($twigCache)) {
@mkdir($twigCache, 0755, true);
}
} }
// Chemin base de données // Chemin base de données
@@ -76,6 +85,7 @@ $app->add(TwigMiddleware::create($app, $twig));
$controller = new PostController($twig, $db); $controller = new PostController($twig, $db);
$app->get('/', [$controller, 'index']); $app->get('/', [$controller, 'index']);
$app->get('/article/{slug}', [$controller, 'show']);
$app->get('/admin', [$controller, 'admin']); $app->get('/admin', [$controller, 'admin']);
$app->get('/admin/edit/{id}', [$controller, 'form']); $app->get('/admin/edit/{id}', [$controller, 'form']);
$app->post('/admin/create', [$controller, 'create']); $app->post('/admin/create', [$controller, 'create']);

View File

@@ -30,6 +30,33 @@ class PostController
return $this->view->render($res, 'pages/home.twig', ['posts' => $posts]); return $this->view->render($res, 'pages/home.twig', ['posts' => $posts]);
} }
/**
* Affiche un article complet par son slug.
*/
public function show(Request $req, Response $res, array $args): Response
{
$slug = (string)($args['slug'] ?? '');
// Récupérer tous les posts et chercher celui qui correspond au slug
$rows = $this->db->select('post', '*', ['ORDER' => ['id' => 'DESC']]);
$post = null;
foreach ($rows ?: [] as $row) {
$postObj = Post::fromArray($row);
if ($postObj->getSlug() === $slug) {
$post = $postObj;
break;
}
}
if (!$post) {
$res->getBody()->write('Article non trouvé');
return $res->withStatus(404);
}
return $this->view->render($res, 'pages/post_detail.twig', ['post' => $post]);
}
/** /**
* Affiche la page d'administration. * Affiche la page d'administration.
*/ */

View File

@@ -135,18 +135,6 @@ final class Post
return trim($slug, '-'); return trim($slug, '-');
} }
/**
* Indique si l'article a été créé récemment.
*
* @param int $days Nombre de jours
* @return bool
*/
public function isRecent(int $days = 7): bool
{
$limit = new DateTime("-{$days} days");
return $this->createdAt > $limit;
}
/** /**
* Retourne les données prêtes à persister en DB. * Retourne les données prêtes à persister en DB.
* *

View File

@@ -25,9 +25,6 @@
<tr> <tr>
<td> <td>
<strong>{{ post.title }}</strong> <strong>{{ post.title }}</strong>
{% if post.isRecent(7) %}
<span class="badge badge-new">Nouveau</span>
{% endif %}
</td> </td>
<td>{{ post.createdAt|date("d/m/Y H:i") }}</td> <td>{{ post.createdAt|date("d/m/Y H:i") }}</td>
<td>{{ post.updatedAt|date("d/m/Y H:i") }}</td> <td>{{ post.updatedAt|date("d/m/Y H:i") }}</td>

View File

@@ -9,9 +9,6 @@
<div class="post-meta"> <div class="post-meta">
<small>Publié le {{ post.createdAt|date("d/m/Y à H:i") }}</small> <small>Publié le {{ post.createdAt|date("d/m/Y à H:i") }}</small>
{% if post.isRecent(7) %}
<span class="badge badge-new">Nouveau</span>
{% endif %}
</div> </div>
<p>{{ post.getExcerpt(200) }}</p> <p>{{ post.getExcerpt(200) }}</p>

View File

@@ -0,0 +1,29 @@
{% extends "layout.twig" %}
{% block title %}{{ post.title }} Mon Blog{% endblock %}
{% block content %}
<article class="post">
<h1>{{ post.title }}</h1>
<div class="post-meta">
<small>Publié le {{ post.createdAt|date("d/m/Y à H:i") }}</small>
</div>
{% if post.updatedAt != post.createdAt %}
<div class="post-updated">
<small><em>Mis à jour le {{ post.updatedAt|date("d/m/Y à H:i") }}</em></small>
</div>
{% endif %}
<div class="post-content">
{{ post.content|raw }}
</div>
<hr>
<p>
<a href="/">← Retour aux articles</a>
</p>
</article>
{% endblock %}