Latte 3.1 – come test the beta version!

David Grudl
Nette Core | 8284
+
0
-

It's been an incredible three years since the release of Latte 3.0. Back then, I completely rewrote the library from scratch, incorporating a sophisticated PHP and HTML lexer, parser, and compiler.

Over time, several things have accumulated that I'd like to change, modify, or remove, and so the time has come to release version 3.1.

I should mention upfront that the changes concern edge cases and full compatibility should be maintained, i.e. Latte will only alert you to modifications by throwing an informational notice.

Whether your templates are compatible can be easily verified using the Linter. For example, in all my templates across all projects, I only had to make two minor adjustments.

So what I'd like to include in version 3.1:

New features:

  • smart HTML attributes – see https://forum.nette.org/…ing-to-latte
  • n:attr validates whether attribute names are valid
  • content-type based on file extension – template content type is detected from the extension, see below

Changes:

  • strictTypes is enabled by default: meaning templates will start with declare(strict_types=1) (this can of course be disabled, even in configuration)
  • global constants without backslash like FOO need to be written as \FOO, this clearly distinguishes them from the string FOO
  • complex expressions in tags like include, embed etc. should be written in parentheses: {include ($a ? 'a.latte' : 'b.latte')}

Removals:

  • using variables $this and $__* in templates – these are reserved for system purposes
  • undefined unsafe operator ??-> – I consider this a historical relic that emerged before the nullsafe ?-> operator
  • Latte\Runtime\Filters::$dateFormat – I don't like that it's a static variable
  • Engine::addFilterLoader() is deprecated – I consider this a historical relic, no other area in Latte has a loader

And a few more comments:

Regarding n:attr and invalid attribute names: here Latte will throw an exception immediately, however I know this breaks things like Ublaboo Datagrid, which uses <input n:attr="'rowspan=2' => $bool">, i.e. it specifies the entire attribute including the value as the attribute name. This exploits a side effect though – the correct syntax should be <input n:attr="rowspan => $bool ? 2"> and then the name rowspan can be validated. Unfortunately, these dynamic things can't be checked using the Linter.

By the way, with smart attributes, there will be no need to use n:attr for such things and it will be enough to write <input rowspan="$bool ? 2">

The proposal to distinguish global constants came from @mesour, because it simplifies the parser in PhpStorm, but I must say it's also helpful for me, because I'm not entirely sure myself what Latte understands as a string and what as a constant. When you write \FOO, it's clear.

Parenthesizing complex expressions in tags like include, embed, link (technically where Latte\Compiler\TagParser::parseUnquotedStringOrExpression() is used) is a preliminary step necessary for other possible syntax extensions. It's actually about having spaces clearly separate the “target” from parameters. And if the “target” contains a space, it must be in parentheses.

Distinguishing content-type by file extension means that when I render a template foo.xml.latte, it will automatically be parsed as XML, without needing to specify {contentType ...} at the beginning. But it also means I can write <script>{include script.js}</script> in a template and script.js will be understood as plain text and Latte won't be parsed in it at all.


All features are implemented and it would be great if you could try out the current version. At minimum, run the Linter on your templates. Because nothing is set in stone and anything can be changed before version 3.1 is released. But later complaints won't be considered :-)

composer require latte/latte:^3.1.x-dev