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.