Documentation

Ship the site. Not the stack.

Forma is a portable PHP + SQLite CMS — dark admin, Markdown, SEO, Agent API, and versioned site packages. This page is assembled with reusable snippets: [[​site-head]], [[​site-header]], [[​site-footer]].

PHP 8.1+ SQLite one file Agent HTTPS API SEO built-in

Install

No MySQL. No Composer. Drop Forma on a host with PHP 8.1+, pdo_sqlite, and rewrite support.

chmod -R 775 database uploads feeds
php -S localhost:8787 router.php

Open /admin, log in with the default credentials, and change them immediately under Settings → Account.

Hosting tip: keep database/ and uploads/ when you redeploy code. Use Settings → Server to ensure .htaccess routes robots.txt / sitemap.xml through Forma, and delete any leftover static robots.txt.

Admin

The admin is htmx + CodeMirror — sections load into the main pane without a SPA rebuild.

  • Pages — HTML/Twig or Markdown, META block for slug + SEO
  • Blog — Markdown posts, RSS/JSON feeds
  • Podcasts — episodes + iTunes-compatible feed (license unlock)
  • Uploads — media library; image fields use Browse / Upload pickers
  • Snippets — reusable HTML via shortcodes
  • Settings — site, SEO, server, agents, backup

Pages & blog

Full HTML documents are served as-is (great for marketing pages). Fragments get a minimal shell. Blog posts are Markdown with publish dates — unpublished posts 404 on purpose.

META block

<!--META
slug: /docs
title: Docs
seo_title: Forma Docs
seo_description: …
-->

Snippets

This docs chrome is snippet-driven so you can reuse nav and footer everywhere:

  • [[​site-head]] — fonts + shared CSS tokens
  • [[​site-header]] — sticky nav / menu
  • [[​site-footer]] — footer links

Edit them under Admin → Snippets. Twig is optional inside snippet bodies if you need site config variables.

SEO

Settings → SEO covers sitewide defaults; pages/posts override per document.

  • Auto /robots.txt and /sitemap.xml (including images)
  • Open Graph / Twitter, favicon, default share image
  • JSON-LD (Person / Organization / LocalBusiness)
  • Redirects manager
  • Health score for missing titles, descriptions, images

Agent API

Create a token in Settings → Agents. Prefer HTTPS. Discover the map with:

curl -H "Authorization: Bearer fx_…" \
  https://forma-cms.me/api/v1/help

DreamHost-safe alternate header: X-Forma-Token. Scopes include content:*, media:write, settings:write, backup:read, podcast:write.

Useful routes

GET  /api/v1/site
GET  /api/v1/pages/{filename}
PUT  /api/v1/pages/{filename}
GET  /api/v1/export/site
POST /api/v1/import/site
POST /api/v1/cache/flush

Site packages

Settings → Backup → Download site package, or GET /api/v1/export/site.

manifest.json     # format_version + schema_version
data.json         # portable content
database/forma.db # SQLite snapshot
uploads/          # media

Future Forma versions migrate using schema_version. Packages newer than the running app are rejected.

Cursor MCP

Point the Forma MCP server at your site URL + token. Start with formax_help, then pages/posts/snippets/media/SEO/export tools.

export FORMA_X_URL=https://forma-cms.me
export FORMA_X_TOKEN=fx_…
php tools/formax.php site
php tools/formax.php export-site ./backup.zip