Content Storage
All CMS content lives on the filesystem under _content/. There is no database for page content. This design makes content git-friendly, agent-friendly, and trivially portable.
Directory layout
Each page context maps to a directory. Here is what a typical site looks like:
_content/
├── home/
│ ├── widgets.json # text & image values for the home page
│ ├── intro.html # cms_html('intro', ...) content
│ ├── _feature-1/
│ │ ├── widgets.json # heading text for Feature 1
│ │ └── body.html # body HTML for Feature 1
│ ├── _feature-2/
│ │ ├── widgets.json
│ │ └── body.html
│ └── _feature-3/
│ ├── widgets.json
│ └── body.html
├── about/
│ ├── widgets.json
│ └── body.html
├── team/
│ └── erik/
│ └── widgets.json # name, role, photo for /team/erik
├── routes.php # page routing definitions
├── models.php # entity registrations
└── site.json # site name and description
widgets.json
Text and image values are stored as a flat JSON object keyed by slug:
{
"heading": "About Our Company",
"photo": "/uploads/team/photo.jpg"
}
The file is pretty-printed so diffs are clean and agents can edit values directly with standard JSON tools.
HTML files
cms_html() content is stored in separate .html files named after the slug: body.html, intro.html, etc. This keeps rich content out of JSON (no escaping issues) and produces meaningful git diffs.
An agent editing HTML content should write the file directly:
# Read current content
cat _content/about/body.html
# Write updated content
cat > _content/about/body.html <<'HTML'
<p>Updated paragraph with <strong>bold</strong> text.</p>
<p>A second paragraph.</p>
HTML
Editing content programmatically
The ContentStore class provides the read/write API:
$store = \mini\Mini::$mini->get(ContentStore::class);
// Text and image widgets
$value = $store->readWidget('home', 'heading');
$store->writeWidget('home', 'heading', 'New Title');
// HTML content
$html = $store->readHtml('home', 'intro');
$store->writeHtml('home', 'intro', '<p>New content.</p>');
But for agents, editing the files directly is usually simpler.
Path construction
Mini CMS uses mini\Util\Path for all filesystem path operations. Paths are joined and canonicalized — no manual string concatenation with /. This ensures correct behavior across platforms.