Latte: jak korzystać z systemu typów?
System typów. Kluczowa kwestia dla rozwoju solidnych aplikacji, w której PHP zyskało dużą przewagę nad dynamicznymi językami takimi jak Python, Ruby czy JavaScript. Framework Nette od początku prowadzi programistów do programowania typowanego i ścisłego. Latte 2.7 wprowadziło wsparcie dla typów również w szablonach.

Dzięki temu, że wiemy, jaki typ danych lub obiektu znajduje się w każdej zmiennej, może:
- IDE poprawnie podpowiadać
- analiza statyczna wykrywać błędy
Dwa punkty, które zasadniczo zwiększają jakość i komfort programowania.
Jak deklarować typy po stronie PHP?
Dane będziemy przekazywać do szablonu jako obiekt klasy, która definiuje wszystkie zmienne i ich typy. Wykorzystując nowe funkcje PHP 7.4, mogłaby wyglądać na przykład tak:
class MailTemplate
{
public string $lang = 'cs';
public Address $address;
public string $subject;
public ?float $price = null;
}
Użycie:
$template = new MailTemplate;
$template->price = $this->getPrice();
...
$latte->render('mail.latte', $template);
Uzupełnienie: dzięki nowym funkcjom PHP 8 przykład można zapisać jeszcze ciekawiej w ten sposób:
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,
));
Jak deklarować typy w szablonie?
Podaną klasę możemy teraz połączyć z szablonem. Wystarczy umieścić na początku:
{templateType MailTemplate}
I tym zdefiniowaliśmy, że w szablonie będzie czwórka zmiennych
$lang
, $address
, $subject
i
$price
wraz z odpowiednimi typami.
Alternatywą jest zdefiniowanie typów poszczególnych zmiennych
bezpośrednio w szablonie, tj. bez tworzenia klasy. Służy do tego tag
{varType}
:
{varType string $lang}
{varType Address $address}
Oczywiście można łączyć obie metody. Utworzyć klasę, ponieważ zapewni
to podpowiadanie po stronie presentera, połączyć ją z szablonem za pomocą
{templateType}
, a dla pozostałych lokalnych zmiennych w blokach
itp. używać {varType}
. Które możemy rozumieć jako odpowiednik
/** @var type $variable */
, czyli komentarza, którym czasami w
kodzie PHP instruujemy IDE lub analizator statyczny.
Nowo można typ podać również w tagach {var}
,
{default}
lub {define}
:
{var Model\Page $page = $items['page']}
{define form, string $name}
...
{/define}
Uwaga: z powodów historycznych możliwe było w tagach {var}
i
{default}
pisanie zmiennych bez początkowego dolara (i ze
strzałką zamiast znaku równości). Ponieważ tworzy to niejednoznaczność,
czy chodzi o typ czy zmienną, ta składnia jest zabroniona i Latte będzie
ostrzegać przy jej użyciu. Prosty sposób na przeszukanie swoich szablonów,
czy nie ma tam tego starego zapisu, to szukanie wyrażeń regularnych
/\{(var|default) [^$]/
i
/\{(var|default) [^}]*=>/
.
Jak zaoszczędzić sobie pracy?
Jak najłatwiej napisać klasę szablonu lub tagi {varType}
?
Pozwól sobie je wygenerować. Właśnie do tego służy para tagów
{templatePrint}
i {varPrint}
.
Jeśli umieścisz któryś z tych tagów w szablonie, zamiast zwykłego
renderowania wyświetli się propozycja kodu klasy lub lista tagów
{varPrint}
. Kod wystarczy jednym kliknięciem zaznaczyć
i skopiować do projektu.
Częścią nette/application 3.1 (w wersji beta) jest przeciążony tag
{templatePrint}
, który generuje kod lepiej dostosowany do
presenterów.
Tag {varPrint}
wypisuje zmienne lokalne, które nie są
parametrami szablonu. Jeśli chcesz wypisać wszystkie zmienne, użyj
{varPrint all}
.
Podpowiadanie w IDE
Najnowsza wersja wtyczki Latte dla PhpStorm potrafi wykorzystać powyższe
tagi, a następnie podpowiadać na podstawie typów. Wtyczka jednocześnie zna
typy standardowych zmiennych, takich jak $user
,
$presenter
, $basePath
itd.

Analiza statyczna
Celem jest, aby wszystkie zadeklarowane typy można było użyć również do analizy statycznej. Aby na przykład za pomocą PHPStan można było kontrolować szablony tak samo łatwo, jak inne pliki PHP.
Pracujemy nad tym i pojawi się to w jednej z przyszłych wersji Latte.
Aby przesłać komentarz, proszę się zalogować