Smart HTML Attributes
Latte 3.1 comes with a set of improvements that focuses on one of the most common activities in templates – printing HTML attributes. It brings more convenience, flexibility and security.
Boolean Attributes
HTML uses special attributes like checked, disabled, selected, or hidden,
where the specific value is irrelevant—only their presence matters. They act as simple flags.
Latte handles them automatically. You can pass any expression to the attribute. If it is truthy, the attribute is rendered. If
it is falsey (e.g. false, null, 0, or an empty string), the attribute is completely
omitted.
This means you can say goodbye to cumbersome macro conditions or n:attr and simply use:
<input type="text" disabled={$isDisabled} readonly={$isReadOnly}>
If $isDisabled is false and $isReadOnly is true, it renders:
<input type="text" readonly>
If you need this toggling behavior for standard attributes that don't have this automatic handling (like data- or
aria- attributes), use the toggle filter.
Null Values
This is one of the most pleasant changes. Previously, if a variable was null, it printed as an empty string
"". This often led to empty attributes in HTML like class="" or title="".
In Latte 3.1, a new universal rule applies: A value of null means the attribute does not exist.
<div title="{$title}"></div>
If $title is null, the output is <div></div>. If it contains a string, e.g.
“Hello”, the output is <div title="Hello"></div>. Thanks to this, you don't have to wrap attributes
in conditions.
If you use filters, keep in mind that they usually convert null to a string (e.g. empty string). To prevent this,
use the nullsafe filter ?|:
<div title="{$title?|upper}"></div>
Classes
You can pass an array to the class attribute. This is perfect for conditional classes: if the array is
associative, the keys are used as class names and the values as conditions. The class is rendered only if the condition
is true.
<button class={[
btn,
btn-primary,
active => $isActive,
]}>Press me</button>
If $isActive is true, it renders:
<button class="btn btn-primary active">Press me</button>
This behavior is not limited to class. It works for any HTML attribute that expects a space-separated list of
values, such as itemprop, rel, sandbox, etc.
<a rel={[nofollow, noopener, external => $isExternal]}>link</a>
Styles
The style attribute also supports arrays. It is especially useful for conditional styles. If an array item
contains a key (CSS property) and a value, the property is rendered only if the value is not null.
<div style={[
background => lightblue,
display => $isVisible ? block : null,
font-size => '16px',
]}></div>
If $isVisible is false, it renders:
<div style="background: lightblue; font-size: 16px"></div>
Data Attributes
Often we need to pass configuration for JavaScript into HTML. Previously this was done via json_encode. Now you
can simply pass an array or stdClass object to a data- attribute and Latte will serialize it to JSON:
<div data-config={[ theme: dark, version: 2 ]}></div>
Outputs:
<div data-config='{"theme":"dark","version":2}'></div>
Also, true and false are rendered as strings "true" and "false" (i.e.
valid JSON).
Aria Attributes
The WAI-ARIA specification requires text values "true" and "false" for boolean values. Latte handles
this automatically for aria- attributes:
<button aria-expanded={=true} aria-checked={=false}></button>
Outputs:
<button aria-expanded="true" aria-checked="false"></button>
Type Checking
Have you ever seen <input value="Array"> in your generated HTML? It's a classic bug that often goes
unnoticed. Latte introduces strict type checking for HTML attributes to make your templates more resilient against such
oversight.
Latte knows which attributes are which and what values they expect:
- Standard attributes (like
href,id,value,placeholder…) expect a value that can be rendered as text. This includes strings, numbers, or stringable objects.nullis also accepted (it drops the attribute). However, if you accidentally pass an array, boolean or a generic object, Latte triggers a warning and intelligently ignores the invalid value. - Boolean attributes (like
checked,disabled…) accept any type, as their presence is determined by truthy/falsey logic. - Smart attributes (like
class,style,data-…) specifically handle arrays as valid inputs.
This check ensures that your application doesn't produce unexpected HTML.
Migration from Latte 3.0
Since the behavior of null (it used to print "", now it drops the attribute) and data-
attributes (booleans used to print "1"/"", now "true"/"false") has changed,
you might need to update your templates.
For a smooth transition, Latte provides a migration mode that highlights differences. Read the detailed guide Migration from Latte 3.0 to 3.1.
