v0.2.0

<p>Runtime state - pages, users, the registry, file variants - moves out of site/ into a new sibling data/ root, a site-wide Changes page adds publish/discard for pending edits, and images drop their old eager-mirror-to-disk behavior.</p>

28 September 2026

Added

  • A new data/ root (sibling to site/) holding pages/, users/, and storage/ (registry, cache, file variants, rate limits) - App::__construct() now validates site/public/ (proof of a site root) and data/pages/ (proof of a data/ sibling) independently. env.json/env.cli.json now load from data/.
  • A site-wide "Changes" admin page listing every page with uncommitted git changes, including deleted pages - previously a deleted page's History tab disappeared with it, leaving no way to publish or discard the deletion.
  • A navigate-away overlay on the browse preview panel when the embedded iframe follows a link to a different page than the one being edited.
  • The text fieldtype's editor switched from a single-line input to an auto-expanding textarea, with a new "multiline" option (off by default, blocking Enter/pasted line breaks for a single-line field).
  • Res::removeHeader(); Session/SessionRoot::hasCookie() promoted to a public accessor.

Fixed

  • A :blockname fragment response no longer inherits a view's shared-cache opt-in - always no-store, since a fragment is more likely to carry per-visitor content than the page shell it's addressed from.
  • A cacheable response now has any Set-Cookie header stripped before sending, closing a path where a session-touching hook running on a cached view could leak one visitor's session cookie to others.
  • PageFiles::rebuild()'s public-mirror sweep now validates each recorded image variant against its real source file (existence, public flag, modified time) instead of fragile filename-stem matching, catching stale/debris mirrors it previously kept or wrongly invalidated.
  • Admin preview edit-mode gating switched from a spoofable ?_preview=1 query parameter to a real iframe-request check, so click-to-edit affordances can't be triggered by just visiting a URL with that query string.
  • Clockwork no longer starts a session for an anonymous visitor just to log an id, guarded on the same session-cookie check added last release.

Changed

  • PageImage::url() no longer eagerly mirrors the original file to the public directory on first call - a plain image URL is now served live through PHP like any other file; only transform()'s resized variants still produce a public mirror.
  • Hx::trigger() changed from variadic string ...$events to array $events, ?string $target = null - $target lets a caller dispatch on an explicit CSS selector instead of the (possibly already-swapped-out) requesting element.
  • The git-backed publish workflow now operates against data/, not site/, as its working tree.

Comments

No comments yet. Be the first!

Loading form…