Framework

Repository Author Commit message Committed SHA  
 
application by dg PresenterFactory: mapping accepts submodules like 'Admin:Forum', the longest prefix wins

Previously such a key was silently ignored.

application by dg Component: StatePersistent component that is not UI\Component cannot be added (BC break)

Its state was silently skipped by Presenter::getGlobalState().

application by dg Control: flashMessage() does not create the template

In the most typical flow - flashMessage() followed by redirect() - the template
was created just to be thrown away, which builds a whole Latte\Engine instance.
The messages are written to the session first and into the template only if it
already exists; a template created later gets them from the template factory,
which reads the flashes from the session on its own.

application by dg AccessPolicy: class-level #[Requires] is inherited from ancestors

ReflectionClass::getAttributes() does not return attributes of parent classes,
so a rule placed on a common ancestor (a typical #[Requires(sameOrigin: true)]
on BaseAdminPresenter) was silently not enforced in its descendants. Attributes
are now collected along the whole ancestor chain; a rule explicitly set in a
descendant overrides the same rule of its ancestors.

application by dg Presenter::argsToParams() now distinguish between NULL and ''
application by dg removed {templatePrint}
application by dg uses nette/routing 4.0
application by dg RoutingPanel: added support for AI agents
application by dg removed support for @annotations (BC break)
application by dg Presenter: removed constructor (BC break!)
application by dg Component: only UI components can be added to presenter/component (BC break) WIP
application by dg Component: method checkRequirements() is called for createComponent<Name>() methods (BC break)
application by dg Revert "UI\PresenterComponent: removed references created by loadState() for persistent parameters. [Closes nette/nette#703][Closes nette/nette#703][Closes #69]" (possible BC break)

This reverts commit cda17f460d020b0f042364d4e140742022a7e94d.

See https://forum.nette.org/cs/35528-stejne-pojmenovany-parametr-akce-presenteru-a-persistentni-odlisne-chovani-v-nette-2-0-oproti-aktualnimu#p221742

BC break: Property must be nullable, ie: #[Persistent] public ?int $foo

latte by dg Escaper: <textarea> and <title> keep braces intact

Their content is text that the browser does not parse as HTML, so the empty
comment separating braces was displayed and corrupted the value, e.g. a {{ }}
in a submitted form (#409). The content now gets the subType rcdata, printed
by HtmlHelpers::escapeRcData() without touching braces.

A block placed in <textarea> or <title> has the content type html/rcdata,
which contextual filters now see instead of html; |stripHtml and |stripTags
accept it.

latte by dg HtmlHelpers: {{ cannot form from adjacent outputs [security]

Vue, petite-vue and AngularJS read the DOM after the browser has decoded
entities, so the &#123; that escapeText() used for a single brace did not
protect anything: {$a}{$b} with '{' and '{7*7}}' produced a live {{ }}, and so
did '{{{' because strtr() replaced only non-overlapping pairs. A brace followed
by another one or ending the string, and a leading one, is now separated by an
empty comment; a brace in the middle stays as it is.

escapeRawHtml() for <script type="text/template"> did not separate braces at
all, so Vue evaluated {{ }} from a variable there.

latte by dg Filters: number() and bytes() reuse the NumberFormatter

Creating a formatter costs about 7 µs, formatting with an existing one 0.3 µs.
The rounding mode is now set in a single place.

latte by dg Nodes: positional argument after a named one is deprecated

In {include}, {embed}, {extends}, {layout} and {import} the arguments are
bound to parameters by position and by name, so in {include block, name: $a, $b}
the positional $b takes position 0 and overrides $name. PHP forbids such a call;
Latte now triggers E_USER_DEPRECATED and will throw in the next minor version.
Arrays of n:attr and n:class are not affected.

latte by vosikar Filters: number() and bytes() with locale round half up like without locale, instead of NumberFormatter's default half-even
latte by zipper Add Latte+ to the list of PhpStorm plugins
latte by vrana Passes: null in URL attribute drops it like in other attributes (BC break)

Since 3.1, a null value of an attribute means the attribute is omitted. URL
attributes were an exception: the checkUrls pass appends |checkUrl, which
converts null to '', so <a href={$url}> with null rendered href="". That
makes the element a link to the current page.

The pass now appends the filter as nullsafe ?|checkUrl, so null skips it and
the attribute is dropped. With migration warnings, the change is reported like
for other attributes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

latte by vrana HtmlHelpers: srcdoc triggers a migration warning for a value previously rendered as HTML

With Feature::MigrationWarnings, a plain srcdoc value that renders as a different
document now than before (it contains '<' or a character reference) triggers
a warning suggesting to wrap trusted HTML in Latte\Runtime\Html. Text such as
'a & b' renders the same document as before and stays quiet; so does an Html
object, whose tags were stripped before and are kept now. |accept silences it.

It covers dynamic attributes (srcdoc={$x}, srcdoc="{$x}") and n:attr. A mixed
value like srcdoc="<p>{$x}</p>" is escaped by code the Escaper emits, which has
no access to feature flags, so it does not warn.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

latte by vrana Escaper: srcdoc attribute is escaped as an HTML document [security] (BC break)

The value of srcdoc is an HTML document: the browser attribute-decodes it and
then parses the result as HTML. Latte escaped it like any other attribute, so
<iframe srcdoc="<p>{$x}</p>"> with $x = '<script>...</script>' rendered
&lt;script&gt;, which decodes to a live <script>. An iframe without sandbox
shares the parent's origin, so this was an XSS.

srcdoc now gets its own html/attr/html context: a value is escaped as HTML text
first and as an attribute second (HtmlHelpers::escapeHtmlAttr). This covers the
static attribute, the dynamic attribute srcdoc={$x}, n:attr and blocks or
templates included into srcdoc.

An Html object is encoded only once, so trusted markup keeps its tags;
previously they were stripped.

BC break: trusted HTML passed as a plain string is now displayed as text. Wrap
it in Latte\Runtime\Html (or use |noescape).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

di by dg properties, static properties and constants are written the same way everywhere in the configuration (BC break)

A member written without parentheses is read, also as a link of a chain:
@foo::getBar()::baz reads the property baz instead of calling baz(), and
@foo::bar::getBaz() reads bar before it calls getBaz(). ::$name is a static
property (@foo::$bar, Foo::$bar, @foo::getBar()::$baz), a name starting with
a capital letter is a constant, and an undefined constant Foo::BAR is an error
instead of a string. A method written without parentheses fails with a hint
to add them.

In setup, @foo::$bar = value assigns the static property as well; a property
of another service is assigned by @foo::bar = value.

di by dg requires nette/neon 4, the reader of nette/neon 3 removed (BC break)
di by dg requires PHP 8.4
di by dg removed Statement compatibility shims from expression classes (BC break)

Expression nodes extend Expression and no longer carry getEntity() or mutable
$arguments. A setup step may be any Expression, typed() and tagged() complete
to ServiceCollection.

di by dg deprecated magic properties (BC break)
di by dg removed compatibility for old class names
di by dg removed Definition::generateMethod() (BC break)
di by dg removed deprecated stuff

- %parameters%
- three ... dots
- @inject & @var

di by dg opened 4.0-dev
di by dg Resolver: typed() and tagged() can be passed to a variadic parameter by name

Last synchronization: 2026-10-29 05:02:43