Latte: how to use type system?
Type system is main thing for the development of robust applications. Types in PHP have a superiority over other dynamic languages such as Python, Ruby or JavaScript. Nette Framework leads programmers to produce typed and strict code from the beginning. Latte 2.7 brought the type support to templates as well.
To knowing what data or object type each variable is allows
- IDE to correctly autocomplete
- static analysis to detect errors
Two points that significantly improve the quality and convenience of development.
How to declare types on PHP side?
We will pass data to the template as an object of a class that defines all variables and their types. Using the new features of PHP 7.4, it could look like this:
class MailTemplate
{
public string $lang = 'cs';
public Address $address;
public string $subject;
public ?float $price = null;
}
Usage:
$template = new MailTemplate;
$template->price = $this->getPrice();
...
$latte->render('mail.latte', $template);
Addition: thanks to the new features of PHP 8, the example can be written more interestingly like this:
class MailTemplate
{
public function __construct(
public string $lang = 'cs',
public Address $address,
public string $subject,
public ?float $price = null,
) {}
}
$latte->render('mail.latte', new MailTemplate(
lang: $this->lang,
subject: $title,
price: $this->getPrice(),
address: $userAddress,
));
How to declare types in a template?
We can now associate that class with the template. We just need to state it at the beginning:
{templateType MailTemplate}
And with that, we have defined that the template will contain a quartet of
variables $lang
, $address
, $subject
and
$price
including their respective types.
The alternative is to define the types of each variable directly in the
template, i.e. without creating a class. The tag {varType}
is used
for this purpose:
{varType string $lang}
{varType Address $address}
Of course, both can be combined. Create a class, as this will ensure
completion on the presenter side, link it to the template using
{templateType}
and use {varType}
for other local
variables in blocks, etc. This can be understood as an analogy
/** @var type $variable */
, which is a comment that we sometimes
use in PHP code to instruct IDE or static analysis tool.
Also, the type can be specified in {var}
, {default}
or {define}
:
{var Model\Page $page = $items['page']}
{define form, string $name}
...
{/define}
Note: for historical reasons, it was possible to write variables in the
{var}
and {default}
tags without the leading dollar
sign. Because this creates ambiguity whether it is a type or a variable, this
syntax is deprecated and Latte will warn you when you use it.
How do you simplify your work?
How to write a template class or {varType}
as easy as possible?
Get them generated. That is precisely what pair of tags
{templatePrint}
and {varPrint}
do.
If you place one of these tags in a template, the code of class or template is displayed instead of the normal rendering. Then simply select and copy the code into your project.
Nette/application 3.1 (beta) includes an overloaded tag
{templatePrint}
that generates code that is better suitable for
presenters.
The {varPrint}
tag lists local variables that are not template
parameters. If you want to list all variables, use
{varPrint all}
.
IDE code completion
The latest version of the PhpStorm Latte plugin can take advantage of the
above tags and then suggest based on types. The plugin also knows the types of
standard variables such as $user
, $presenter
,
$basePath
, etc.
Static analysis
The final goal is that all declared types can also be used for static analysis. For example, to use PHPStan to check templates as easily as other PHP files.
We are working on this and you will see it in one of the next versions of Latte.
Comments
Nice, I'm using it just for a few weeks, and it's awesome, now, there is no template system what could compete with Latte. 😍
♥️ ♥️ ♥️ This is the feature of the year!
Sign in to submit a comment