Markdown Publishing Site
Build a publishing website with Laravel where articles are written as Markdown files with a small header (front matter) for the title, date, tags and summary. The site turns them into pages with clean URLs (slugs), lists articles newest first with pagination, lets readers browse by tag, and offers an RSS feed. Drafts and future-dated articles stay hidden until their time. Because parsing Markdown on every visit would be slow, rendered articles are cached and refreshed only when a file changes. You'll learn Laravel routing, controllers and Blade templates, parsing Markdown safely with league/commonmark, front matter, slugs and redirects, caching, and feature tests.
- Estimate
- ~11h
- Steps
- 6
- Completed by
- 0
- Proposed by
- codeseed.app
Laravel · Composer
Project roadmap
- 01
Define the content rules
~1.5hWrite README.md: articles live in content/posts/*.md with front matter (title and date required; tags, summary, draft and an optional slug); slugs come from the title (Str::slug) unless given, and must be unique; URLs are /posts/{slug}, /tags/{tag} and /feed.xml; drafts and future dates are hidden in production. Create a Laravel project. Done when: README.md defines the content format and URLs.
- 02
Load and validate articles
~2.5hWrite a PostRepository that reads the files, splits the front matter (with league/commonmark's front matter extension or symfony/yaml), and validates each field with Laravel's Validator, reporting invalid files with their name and the problem. Detect duplicate slugs. Add an artisan command posts:check that lists all problems. Done when: posts:check reports every broken file in a test folder.
- 03
Render pages
~2hConvert Markdown with league/commonmark (with GitHub-flavored Markdown, and raw HTML disabled so content can't inject scripts). Build Blade templates for the home page (newest first, paginated), an article page with its date and tags, and tag pages. Return 404 for unknown slugs and hidden articles. Done when: the site shows articles and tags correctly.
- 04
Cache rendered articles
~1.5hCache each rendered article with a key including the file's modification time (or content hash), so edits appear immediately while unchanged articles aren't parsed again. Cache the list of articles the same way. Add a posts:cache-clear command. Done when: editing a file updates the page on the next visit, and unchanged pages load from the cache.
- 05
Add a feed and handle changed slugs
~1.5hAdd /feed.xml with the 20 latest articles as valid RSS. Let articles list old slugs (an aliases field), and redirect old URLs with 301 to the current slug, so links shared earlier keep working. Add a sitemap.xml. Done when: the feed validates, and old URLs redirect to the right article.
- 06
Test it
~2hWrite Laravel feature tests using a test content folder: the home page order and pagination, article pages, tag pages, drafts and future articles hidden, 404 for unknown slugs, redirects from aliases, the feed, and posts:check finding invalid files. Done when: php artisan test passes.
Resources
Ready to build this?
Get a GitHub repo and start building. Your AI reviewer checks each step as you go.
Tech stack