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.php
wraps every page with head/foot and includes partials. - partials/ — Reusable chunks.
header.php
andfooter.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
$title
and$content
(HTML). templates/main.php
outputs 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
$content
already HTML‑ified from Markdown. - Menus are old‑school: edit
partials/header.php
by hand.
Deploy Notes
- Apache: enable
.htaccess
as included. Nginx: route non‑file requests toindex.php
. - Set correct
base_url
inconfig.php
if serving from a subdirectory. - Set permissions: directories
755
, files644
.