NostalgiaPHP — Project Tour
This is a tiny file‑based PHP CMS: Markdown in, HTML out. No database, no framework.
Top-Level Files
- index.php — Router. Reads the URL and decides whether to render a page, a collection list, or a collection item.
- functions.php — Helpers: config, paths, URL building, front‑matter parsing, Markdown → HTML, loaders, and render.
- config.php — Site settings (name, timezone, base_url) and collection definitions.
- .htaccess — Pretty URLs when using Apache in production (everything routes to
index.php).
Folders
- templates/ — Layouts.
main.phpwraps every page with head/foot and includes partials. - partials/ — Reusable chunks.
header.phpandfooter.php. - content/ — File‑based content.
- pages/ — Static pages (e.g.,
about.md). URL is/{filename}. - collections/ — Named groups (e.g.,
blog/). Items are/{collection}/{slug}.
- pages/ — Static pages (e.g.,
- static/ — CSS, images, etc. Served as static files.
Routing Flow (index.php)
- Parse the current request path.
- If
/→ rendercontent/pages/index.md. - If
/{collection}→ list items undercontent/collections/{collection}. - If
/{collection}/{slug}→ render that item. - Else treat as a page:
content/pages/{slug}.md.
Template Flow
- Router prepares
$titleand$content(HTML). templates/main.phpoutputs HTML head, includespartials/header.php, dumps$content, and includespartials/footer.php.
Content Files
Each .md file can start with simple front‑matter followed by Markdown:
---
title: Hello World
date: 2025-09-01
draft: false
---
# Heading
Some **markdown** body text.
Supported front‑matter keys are free-form; date is auto‑cast to DateTime if YYYY-MM-DD.
Collections
Define collections in config.php:
'collections' => [
'blog' => [
'permalink' => '/blog/{slug}',
'list_url' => '/blog',
'sort' => ['date','desc'],
],
],
Create items under content/collections/blog/*.md. The filename (without .md) is the slug unless overridden in front‑matter.
Helpers Cheat Sheet (functions.php)
site($key)— read site config (e.g.,site('name')).path($key)— resolve paths:pages,collections,templates,partials.url($path)— base‑aware URL builder (works in subfolders).request_path()— current URL path (e.g.,about,blog/hello-world).load_page($slug)— loadcontent/pages/{slug}.md.list_collection($name)— list items with meta for a collection.load_collection_item($name, $slug)— load one item.render($view, $vars)— include template with variables.
Mental Model for WP Folks
- Think template hierarchy without the hierarchy: it’s all handled by
index.php. - Think Loop, but the “query” is a directory listing for a collection.
- Think the_content() being
$contentalready HTML‑ified from Markdown. - Menus are old‑school: edit
partials/header.phpby hand.
Deploy Notes
- Apache: enable
.htaccessas included. Nginx: route non‑file requests toindex.php. - Set correct
base_urlinconfig.phpif serving from a subdirectory. - Set permissions: directories
755, files644.