v0.0.69
16 July 2026
App-level HTMX response wrappers, a new View class for editable view definitions, addon-scoped @id/ fieldtype references, and cascading page deletes.
Added
- App-level wrappers over the Hx toolkit, mirroring
Hx::methods but branching on$request->isPartial()so a direct (non-HTMX) request gets a real redirect instead of an inert header-only response:$app->location(),refresh(),pushUrl(),replaceUrl(),retarget(),reswap(),reselect(). Phlat\View: aRecordwrapping a view's ownindex.json(assigned fields and their per-view overrides), the site-author-editable counterpart toViews\PageView's template resolution.$app->view(name),viewNames(),views(),forgetView(name), plus$app->fieldNames()for the equivalent field-name listing.@id/nameaddon-scoped references for fieldtypes and fields (e.g.@reverse-field/reverse), resolved byApp::typeLookupRoots(). A bare name still searches the normal site-overrides-addon-overrides-phlat chain; the@id/prefix pins the search to one addon's own root.Page::delete(): deletes a page and its persisted subtree, emittingpage.delete:beforefor every descendant (and the page itself) ahead of removal.- Admin UI: view editing (assign/remove fields, per-view field overrides) and a delete button on the fields admin.
Fixed
PageFiles::build():Page::file()always passed$isImage = false, so a file that mime-sniffs as an image but was fetched throughfile()instead ofimage()never gotPageImage's eager public-mirror, and itsurl()silently 404'd.$isImageis now a minimum, not an override: true if either the caller passed it or the mime sniffs as an image.
Changed
- Removed the addon alias override system: aliases are no longer configurable via
config.addons.{id}.alias. Every addon now gets an automatic, fixed alias from its id's last segment (phlat/adminbecomesadmin), registered directly inAddonRegistry::register(). App::trigger()no longer exits: it wasnever-returning (callingHx::trigger()then an empty response), now it just sets the header and returns, so it can be combined with other response calls.