v0.42.0

3 November 2026

The pages cache gets its own store, installed addons move back to the project root, and the framework repo no longer carries a site.

Changed

  • The pages cache is its own store, data/cache/pages.db, reached only through $page->cache(). Its config key is cache.pages.enabled (was cache.fragments.enabled).
  • $app->cache($name) writes to data/cache/app.{name}.db, accepts only lowercase letters, numbers and dashes, and can no longer reach the pages cache. An app store's config key is cache.app.{name}.enabled.
  • Cache::flushTree() takes no URL and clears its own page's tree. To empty the whole pages cache, call $app->page('/')->cache()->flushTree().
  • cache.get:after, cache.set:after and cache.flush:after pass pages or app.{name} as the store name.
  • Installed addons (git submodules) live at addons/{creator}/{name}/ in the project root again, beside site/. site/addons/ holds only site-only addons. The addons:* commands run git in the project root.
  • The license exception is part of LICENSE. LICENSE-EXCEPTION is gone.

Removed

  • The docs site is no longer a submodule of the framework repo. It lives in its own project, along with its deploy.php, compose.yaml, Docker files and php.ini.
  • The site theme build scripts (build:styles, watch:styles, build:htmx) and task phlat:watch. A site builds its own CSS. npm run build builds the admin assets only.

Upgrading

  • Replace $app->cache('fragments')->flushTree($page->url()) with $page->cache()->flushTree(), and $app->cache('fragments')->flush() with $app->page('/')->cache()->flushTree(). Rename cache.fragments.enabled and any cache.{name}.enabled keys. Listeners that test the store name compare to pages. Run phlat cache:clear to drop the old cache files.
  • For each submodule at site/addons/{creator}/{name}, run git mv site/addons/{creator}/{name} addons/{creator}/{name} from the project root, and make sure .gitignore does not ignore /addons.