Migration from Latte 3.0
Latte 3.1 brings several improvements and changes that make templates safer and more convenient to write. Most changes are backward compatible, but some require attention during migration. This guide summarizes the breaking changes and how to handle them.
Latte 3.1 requires PHP 8.2 or newer.
Smart Attributes and Migration
The most significant change in Latte 3.1 is the new behavior of Smart
Attributes. This affects how null values and boolean values in data- attributes are rendered.
nullvalues: Previously,title={$null}rendered astitle="". Now, the attribute is completely dropped.data-attributes: Previously,data-foo={=true}/data-foo={=false}rendered asdata-foo="1"/data-foo="". Now, it renders asdata-foo="true"/data-foo="false".
To help you identify places where the output has changed in your application, Latte provides a migration tool.
Migration Warnings
You can enable migration warnings, which will warn you during rendering if the output differs from Latte 3.0.
$latte = new Latte\Engine;
$latte->setMigrationWarnings();
When enabled, check your application logs or Tracy bar for E_USER_WARNINGs. Each warning will point to the
specific line, and column in template.
How to resolve warnings:
If the new behavior is correct (e.g. you want the empty attribute to disappear), confirm it using the |accept
filter to suppress the warning:
<div class="{$var|accept}"></div>
If you want to keep the attribute as empty (e.g. title="") instead of dropping it, use the null coalescing
operator:
<div title={$var ?? ''}></div>
Or, if you strictly require the old behavior (e.g. "1" for true), explicitly cast the value to
string:
<div data-foo={(string) $bool}></div>
After you resolve all warnings:
Once all warnings are resolved, disable migration warnings and remove all |accept filters from your
templates, as they are no longer needed.
Strict Types
Latte 3.1 enables declare(strict_types=1) by default for all compiled templates. This improves type safety but
might cause type errors in PHP expressions inside your templates if you were relying on loose typing.
If you cannot fix the types immediately, you can disable this behavior:
$latte->setStrictTypes(false);
Global Constants
The template parser has been improved to better distinguish between simple strings and constants. As a result, global constants
must now be prefixed with a backslash \.
{* Old way (throws a warning; in the future will be interpreted as the string 'PHP_VERSION') *}
{if PHP_VERSION > ...}
{* New way (correctly interpreted as constant) *}
{if \PHP_VERSION > ...}
This change prevents ambiguity and allows you to use unquoted strings more freely.
Removed Features
Reserved Variables: Variables starting with $__ (double underscore) and the variable $this are
now strictly reserved for Latte's internal use. You cannot use them in your templates.
Undefined-safe Operator: The ??-> operator, which was a Latte-specific feature created before PHP 8, has
been removed. It is a historical relic. Please use the standard PHP nullsafe operator ?->.
Filter Loader The Engine::addFilterLoader() method has been deprecated and removed. It was an inconsistent
concept not found elsewhere in Latte.
Date Format The static property Latte\Runtime\Filters::$dateFormat was removed to avoid global state.
New Features
While migrating, you can start enjoying the new features:
- **Smart HTML
Attributes:** Pass arrays to class and style, auto-drop null attributes.
- Nullsafe filters: Use
{$var?|filter}to skip filtering null values. n:elseif: You can now usen:elseifalongsiden:ifandn:else.- Simplified syntax: Write
<div n:if={$cond}>without quotes. - Toggle filter: Use
|togglefor manual control over boolean attributes.