v0.6.2
<p>URLs are limited to lowercase slugs and file names, error messages and URL fields are locked down, and registry queries escape LIKE wildcards.</p>
5 October 2026
Added
- A URL grammar. A page path segment is
V::slug()(lowercase letters and digits with single hyphens) and a file name isV::filename()(photo.jpg,htmx.min.js).Request::$validis false for any path outside it, andAppanswers 404 without looking anything up. The same holds for a block that isn't a slug and a revision that isn't hex. The{slug}route token andPage::move()use the grammar, and a collection item uuid must be a slug. Str::slug()is ASCII only. It transliterates Latin letters with a fixed table instead oficonv, whose output depends on the libc, and drops the rest. A name with nothing Latin left slugs to an empty string and is rejected.San::filename()slugs the stem and lowercases the extension.phlat files:fixrenames existing files that fall outside the grammar and reports the ones it can't.Log::error()writes to the PHP error log, andDb::like()escapes%,_and\forLIKE ... ESCAPE '\'.registry:checkreports pages whoseindex.jsonlackscreatedorupdated, and--healstamps them throughPage::save().
Changed
- A visitor sees an exception's message only when it is an
HttpExceptionor debug is on. Anything else shows "Something went wrong" and goes to the log, as does every 5xx. San::url()andV::url()accept only http, https and mailto URLs.javascript:,vbscript:andfile:URLs fail.- Revision URLs (
~rev) are for editors only; anyone else gets a 403. - A session whose user has been deleted counts as signed out.
- A
HEADrequest is answered by the GET route. Arr::mergeRecursive()replaces a list instead of merging it by index, as in JSON Merge Patch. A config layer can now shrink a list as well as grow it.{all}routes always pass one capture, empty when nothing follows.- Image variant filenames use a preset name only when it is a valid slug, otherwise a hash. A variant is encoded in the format its extension names.
PageFile::url()andPageImage::url()add the source's modification time as a cache-busting token. - Deleting a page also removes its collection items, public mirrors and variant rows (
Registry::deleteSubtree()is public). - The
codefieldtype builds its highlighter on first use.Recordmemoizes its field values. compose.yamlno longer runs the FrankenPHPappservice. The shipped admin icon isphlatpage-icon-2x.png.
Fixed
- Registry
*=,^=and$=matched%and_in the search value as wildcards. - A loose match on a list field returned the same page once per matching entry, and
countRows()counted it that often. - A list entry or a URL path segment of
0was dropped as empty.
Comments
No comments yet. Be the first!
Loading form…