Skip to content

Released version 3.3.0

Latest

Choose a tag to compare

@dg dg released this 24 Jun 17:13
· 21 commits to master since this release

The headline of 3.3 is CSRF protection that the browser handles for you – no token, no cookie, no server-side state, and it holds even against XSS. On top of that, the confusing {formContext} / {formContainer} pair collapses into a single {form scope}, you can finally nest forms with {form detached}, and a round of housekeeping clears out long-deprecated APIs. Please test and report anything that breaks for you.

  • PHP 8.3+ and Latte 3.1.4+ are now required.

πŸ’₯ Breaking Changes

  • CSRF is now strictly same-origin. Forms validate the Sec-Fetch-Site header instead of the old SameSite cookie. The previous mechanism trusted submissions from any subdomain of the same site; the new one demands an exact origin match (scheme + host + port).
  • setValues() / setDefaults() now expect iterable|stdClass.
  • RadioList / CheckboxList: getControlPart() and getLabelPart() throw on an invalid item key instead of silently returning a nonsensical result.
  • Removed long-deprecated APIs:** DataClassGenerator, LatteRenderer, getValues(true) (use getValues('array')), and the $default parameter of getOption() (use the ?? operator), negative validation rules

✨ New Features

  • {form scope name} – one tag to replace the easily-confused {formContext} and {formContainer}. It pushes the form onto the stack without emitting <form>, resolving the name relatively to an active form when there is one, otherwise from the top level.
  • {form detached name} – nest forms at last. HTML forbids nested <form> tags, so detached emits an empty <form></form> up front and links every control back to it via the HTML5 form="..." attribute, no matter where they sit in the DOM.
  • addSubmit() accepts an $onSubmit callback – attach a click handler right when you create the button, without a separate ->onClick[] =.

πŸ—‘οΈ Deprecations

  • A missing comma before {form} arguments – write {form name, attr=val} instead of {form name attr=val}, freeing keywords like scope/detached next to the name.
  • Several magic properties