Getting Started

Project layout, entry point, key ideas, and local development.

New here? Start with the Quickstart.

Key ideas

Pages are folders. A page lives at data/pages/{slug}/ and its URL is its folder path. Content is in data.json, structural metadata in index.json.

Views tie a page to its code. A page's view selects its template, router, controller and field declarations, all named after the view.

Hypermedia-first. Routes return HTML, not JSON. HTMX fetches fragments at clean URLs, so the URL pattern is the API.

Entry point

The web server's document root must be site/public/, whose index.php is the entry point:

<?php

// DOCUMENT_ROOT stays the logical path; __DIR__ resolves through a shared symlink on deploy
$public = $_SERVER['DOCUMENT_ROOT'];

require_once "{$public}/../../vendor/autoload.php";

Phlat::app(dirname($public))->execute();

Phlat::app() returns the singleton App for the project root. execute() resolves the URL to a page, runs the view's router and renders the response.

Directory structure

my-site/
  phlat/          ← framework core (do not edit)
  site/           ← your code and config
    views/        ← templates, routers, and controllers (colocated per view)
    fields/       ← global field definitions
    fieldtypes/   ← custom field types
    addons/       ← site-specific addons
    public/       ← web document root
      index.php
    config.json   ← site config, merged over phlat/config.json
  data/           ← persistent state, survives redeploys
    pages/        ← your content
    users/        ← user accounts
    git/          ← History's deploy key (gitignored)
    storage/      ← registry, locks, rate limits (gitignored)
    cache/        ← compiled views, thumbnails; delete any time (gitignored)
    env.json      ← deployment secrets and overrides (gitignored)

Config merges in order, later wins: phlat/config.json, site/config.json, data/env.json.

Creating pages

A page is a folder in data/pages/ with an index.json (holding a uuid) and a data.json. The root page is data/pages/ itself, served at /.

Create pages in the admin, with phlat make:page, or in code with $page->new($slug, $data). All three mint the uuid and write both files. A page made in the admin or with make:page is unpublished until you publish it; $page->new() publishes it unless $data says 'published' => false. See Publishing and access.

data/pages/
  index.json      ← root page
  data.json       ← renders at /
  about/
    index.json
    data.json     ← renders at /about/
  blog/
    index.json
    data.json     ← renders at /blog/
    my-post/
      index.json
      data.json   ← renders at /blog/my-post/

Local development

npm run watch         # Tailwind watch, site theme
npm run watch:admin   # Tailwind watch, admin theme
npm run sync          # BrowserSync dev server

BrowserSync proxies the local server and reloads on template and content changes.