PHP: Prosty blog z wykorzystaniem markdown

Wpis na blogu opisujący trochę czemu kiedyś napisałem tego bloga: Prosty blog w markdownie

Konstrukcja rozwiązania

Poniżej struktura plików:

🗀 /blog
├── 🗀 posts
│ ├── post1.md
│ └── post2.md
├── index.php
└── blog.php

Schemat działania programu

Kod

Zawartość index.php:

<?php declare(strict_types=1); $postsDir = __DIR__ . '/posts/'; $posts = []; // scan markdown files foreach (glob($postsDir . '*.md') as $file) { $filename = basename($file, '.md'); $content = file_get_contents($file); // extract first markdown H1 if (preg_match('/^#\s+(.+)$/m', $content, $matches)) { $title = trim($matches[1]); } else { $title = $filename; } $posts[] = [ 'slug' => $filename, 'title' => $title, 'time' => filemtime($file), ]; } <html> // sort newest first usort($posts, fn($a, $b) => $b['time'] <=> $a['time']); ?> <?php if (empty($posts)): ?> <p>Brak wpisów.</p> <?php else: ?> <ul class="post-list"> <?php foreach ($posts as $post): ?> <li class="post-item"> <a href="/blog/blog.php?b=<?= htmlspecialchars($post['slug']) ?>"> <?= htmlspecialchars($post['title']) ?> </a> <time datetime="<?= date('c', $post['time']) ?>"> <?= date('Y-m-d', $post['time']) ?> </time> </li> <?php endforeach; ?> </ul> <?php endif; ?> </main> </html>

Zawartość blog.php:

<?php declare(strict_types=1); // ======================== // CONFIG // ======================== $blogDir = __DIR__ . '/posts/'; $defaultPost = 'index'; // ======================== // SECURITY: sanitize input // ======================== $post = $_GET['b'] ?? $defaultPost; // allow only safe filenames if (!preg_match('/^[a-zA-Z0-9_-]+$/', $post)) { http_response_code(400); die('Invalid post name.'); } $mdFile = $blogDir . $post . '.md'; if (!file_exists($mdFile)) { http_response_code(404); $mdContent = "# 404\n\nPost not found."; } else { $mdContent = file_get_contents($mdFile); } // ======================== // MARKDOWN PARSER // ======================== require_once __DIR__ . '/../vendor/Parsedown.php'; require_once __DIR__ . '/../vendor/ParsedownExtra.php'; $parser = new ParsedownExtra(); $parser->setSafeMode(false); // allow HTML in markdown $parser->setMarkupEscaped(false); // don't escape HTML $htmlContent = $parser->text($mdContent); ?> <html> <body> <?= $htmlContent ?> </main> </html>