Latte News: Linter and Strict Mode

10 months ago by David Grudl  

How can you detect errors in templates in a timely manner? You have several methods at your disposal.

Linter: Checking templates on disk

Before deploying a project, it's useful to go through all the templates and check for any syntactical errors. The Linter tool can help with this. It is launched from the console:

vendor/bin/latte-lint <path> [--strict]

Use the --strict parameter to activate strict parsing mode, see below. If you are using custom tags, create a customized Linter.

Checking templates during runtime

How do you check the validity of templates during program execution, for example, if they are edited by a user? In the case of a syntactical error in a .latte file, a Latte\CompileException exception will be thrown during template compilation. However, things are a bit more complicated. If the template is fine, Latte will compile it into PHP code. This code is, of course, syntactically correct, but be careful: incorrect code can be generated by third-party extensions, and more importantly, even in syntactically valid code, forbidden operations can be hidden. An example of this is the assignment $this = 123. Since PHP has records of about two hundred different forbidden situations, it is not Latte's ambition to monitor them all. For checking, it uses the PHP engine. To do this, it needs to know the path to the PHP binary, which we set using the enablePhpLinter() method:

$latte = new Latte\Engine;
$latte->enablePhpLinter('/path/to/php');
try {
	$latte->compile('home.latte');
} catch (Latte\CompileException $e) {
	// now also catches PHP compilation errors
	echo 'Error: ' . $e->getMessage();
}

The path to the binary can also be passed via configuration:

latte:
	phpLinter: ...

Note: Full runtime checking is useful when, for example, you allow users to edit templates. During regular development, it's perfectly fine to let PHP alert you to these types of errors when attempting to render the template.

Strict Parsing Mode

Although Latte understands HTML very well, it is lenient in how you write it. It doesn't strictly enforce whether all tags are correctly closed or if you're mixing them into a “tag soup”. It operates under the assumption that as a template author, you know what you're doing.

A new feature is the strict mode of the parser, in which Latte, on the contrary, alerts you to all infractions. For example:

<p>                  // unclosed tag
<p>...<p>            // missing /
<p>...</x>           // bad closing tag
{if x}<a>{/if} </a>  // risk of non-valid HTML
<foo{foo}>           // risk of affecting the tag name

The mode can be enabled by:

$latte = new Latte\Engine;
$latte->setStrictParsing();

Or in the configuration file:

latte:
	strictParsing: true

In this mode, Latte ensures that your templates adhere to the highest standards of code quality.

One more thing

Latte now supports dynamic HTML tags, which are useful when you need flexibility in tag names:

<h{$level}>Heading</h{$level}>

For example, the code above can generate <h1>Heading</h1> or <h2>Heading</h2> depending on the value of the variable $level. Dynamic HTML tags in Latte must always be paired. Their alternative is the n:tag.

Because Latte is a secure templating system, it checks that the resulting tag name is valid and contains no unwanted or malicious values. It also ensures that the end tag name is always the same as the opening tag name. Even if the value of the $level variable has changed.