Latte: Wie sieht es mit dem Typsystem aus?

vor 5 Jahren von David Grudl  

Das Typsystem. Ein Schlüsselelement für die Entwicklung robuster Anwendungen, bei dem PHP einen großen Vorsprung gegenüber dynamischen Sprachen wie Python, Ruby oder JavaScript gewonnen hat. Das Nette Framework leitet Programmierer von Anfang an zur typisierten und strikten Programmierung an. Latte 2.7 brachte Unterstützung für Typen auch in Templates.

Dadurch, dass wir wissen, welcher Daten- oder Objekttyp in jeder Variablen steckt, kann

  • die IDE korrekt Vorschläge machen
  • die statische Analyse Fehler aufdecken

Zwei Punkte, die die Qualität und den Komfort der Entwicklung grundlegend verbessern.

Wie deklariert man Typen auf der PHP-Seite?

Wir übergeben Daten an das Template als Objekt einer Klasse, die alle Variablen und deren Typen definiert. Mit den neuen Eigenschaften von PHP 7.4 könnte sie etwa so aussehen:

class MailTemplate
{
	public string $lang = 'cs';
	public Address $address;
	public string $subject;
	public ?float $price = null;
}

Verwendung:

$template = new MailTemplate;
$template->price = $this->getPrice();
...
$latte->render('mail.latte', $template);

Ergänzung: Dank der neuen Eigenschaften von PHP 8 lässt sich das Beispiel noch interessanter so schreiben:

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,
));

Wie deklariert man Typen im Template?

Die angegebene Klasse können wir nun mit dem Template verbinden. Es genügt, am Anfang anzugeben:

{templateType MailTemplate}

Damit haben wir definiert, dass im Template die vier Variablen $lang, $address, $subject und $price einschließlich der entsprechenden Typen vorhanden sein werden.

Eine Alternative ist, die Typen der einzelnen Variablen direkt im Template zu definieren, d.h. ohne eine Klasse zu erstellen. Dazu dient der Tag {varType}:

{varType string $lang}
{varType Address $address}

Natürlich kann man beides kombinieren. Eine Klasse erstellen, um Vorschläge auf der Presenter-Seite sicherzustellen, sie mit dem Template über {templateType} verbinden und für andere lokale Variablen in Blöcken usw. {varType} verwenden. Dies können wir als Analogon zu /** @var type $variable */ verstehen, einem Kommentar, mit dem wir gelegentlich im PHP-Code die IDE oder den statischen Analysator instruieren.

Neu kann der Typ auch in den Tags {var}, {default} oder {define} angegeben werden:

{var Model\Page $page = $items['page']}
{define form, string $name}
	...
{/define}

Anmerkung: Aus historischen Gründen war es möglich, in den Tags {var} und {default} Variablen auch ohne das führende Dollarzeichen (und mit einem Pfeil anstelle des Gleichheitszeichens) zu schreiben. Da dies zu Mehrdeutigkeiten führt, ob es sich um einen Typ oder eine Variable handelt, ist diese Syntax verboten und Latte wird Sie bei ihrer Verwendung warnen. Eine einfache Möglichkeit, Ihre Templates zu durchsuchen, ob Sie diese alte Schreibweise verwenden, ist die Suche nach den regulären Ausdrücken /\{(var|default) [^$]/ und /\{(var|default) [^}]*=>/.

Wie kann man sich Arbeit sparen?

Wie schreibt man am einfachsten eine Template-Klasse oder {varType}-Tags? Lassen Sie sie generieren. Genau dafür gibt es das Tag-Paar {templatePrint} und {varPrint}.

Wenn Sie einen dieser Tags in ein Template einfügen, wird anstelle des normalen Renderings ein Vorschlag für den Klassencode bzw. eine Liste von {varPrint}-Tags angezeigt. Den Code können Sie dann einfach mit einem Klick markieren und in Ihr Projekt kopieren.

Teil von nette/application 3.1 (in Beta-Version) ist ein überladener {templatePrint}-Tag, der Code generiert, der besser für Presenter geeignet ist.

Der Tag {varPrint} listet lokale Variablen auf, die keine Template-Parameter sind. Wenn Sie alle Variablen auflisten möchten, verwenden Sie {varPrint all}.

Vorschläge in der IDE

Die neueste Version des Latte-Plugins für PhpStorm kann die oben genannten Tags nutzen und dann basierend auf den Typen Vorschläge machen. Das Plugin kennt auch die Typen von Standardvariablen wie $user, $presenter, $basePath usw.

Statische Analyse

Ziel ist es, dass alle deklarierten Typen auch für die statische Analyse verwendet werden können. Damit beispielsweise mit PHPStan Templates genauso einfach überprüft werden können wie andere PHP-Dateien.

Daran arbeiten wir und Sie können sich in einer der nächsten Versionen von Latte darauf freuen.