Tworzenie własnych funkcji
Łatwo dodasz do szablonów Latte własne funkcje pomocnicze. Wywołuj logikę PHP bezpośrednio w wyrażeniach, aby wykonywać obliczenia, sięgać po usługi czy generować dynamiczną treść, a szablony pozostaną czyste i potężne.
Czym są funkcje?
Funkcje Latte pozwalają rozszerzyć zestaw funkcji wywoływalnych w wyrażeniach szablonu ({...}). Traktuj je jak
własne funkcje PHP dostępne wyłącznie wewnątrz szablonów Latte. Daje to kilka korzyści:
Wygoda: Możesz zdefiniować logikę pomocniczą (jak obliczenia, formatowanie czy sięganie po dane aplikacji)
i wywoływać ją prostą, znajomą składnią funkcji bezpośrednio w szablonie, tak samo jak w PHP wywołujesz
strlen() czy date().
{var $userInitials = initials($userName)} {* np. 'J. D.' *}
{if hasPermission('article', 'edit')}
<a href="...">Edytuj</a>
{/if}
Brak zanieczyszczania zasięgu globalnego: W odróżnieniu od zdefiniowania prawdziwej funkcji globalnej w PHP, funkcje Latte istnieją tylko w kontekście renderowania szablonu. Nie musisz zaśmiecać globalnej przestrzeni nazw PHP pomocnikami przeznaczonymi dla szablonów.
Integracja z logiką aplikacji: Callable PHP stojący za funkcją Latte może być czymkolwiek – domknięciem,
metodą statyczną albo metodą instancji. Oznacza to, że funkcje szablonowe mogą łatwo sięgać po usługi aplikacji, bazy
danych, konfigurację czy dowolną inną logikę, przechwytując zmienne (w domknięciach) albo przez wstrzykiwanie zależności
(w obiektach). Powyższy przykład z hasPermission dobrze to pokazuje – w tle prawdopodobnie wywołuje usługę
autoryzacji.
Nadpisywanie funkcji natywnych (opcjonalne): Możesz nawet zdefiniować funkcję Latte o takiej samej nazwie jak
natywna funkcja PHP. W szablonie zostanie wywołana Twoja wersja. Bywa to przydatne, gdy chcesz zapewnić zachowanie specyficzne
dla szablonów albo spójną obsługę (np. sprawić, by strlen zawsze był bezpieczny dla wielobajtowych). Używaj
tej możliwości ostrożnie, aby uniknąć zamieszania.
Domyślnie Latte pozwala wywoływać wszystkie natywne funkcje PHP (o ile nie ogranicza tego Sandbox). Własne funkcje uzupełniają tę wbudowaną bibliotekę o specyficzne potrzeby Twojego projektu.
Jeśli przekształcasz pojedynczą wartość, bardziej idiomatyczny może być własny filtr.
Tworzenie i rejestrowanie funkcji
Podobnie jak przy filtrach, własne funkcje można definiować i rejestrować na kilka sposobów.
Bezpośrednia rejestracja przez addFunction()
Najprostsza metoda to użycie addFunction() na obiekcie Latte\Engine. Podajesz nazwę funkcji (taką,
jaka pojawi się w szablonie) i odpowiadający jej callable PHP.
$latte = new Latte\Engine;
// prosta funkcja pomocnicza
$latte->addFunction('initials', function (string $name): string {
preg_match_all('#\b\w#u', $name, $m);
return implode('. ', $m[0]) . '.';
});
Użycie w szablonie:
{var $userInitials = initials($userName)}
Argumenty funkcji w szablonie są przekazywane bezpośrednio do callable PHP w tej samej kolejności. Możliwości PHP, takie
jak deklaracje typów, wartości domyślne i parametry wariadyczne (...), działają zgodnie z oczekiwaniami.
Rejestracja przez rozszerzenie
Dla lepszej organizacji i możliwości ponownego użycia rejestruj funkcje w rozszerzeniu Latte. To zalecane podejście dla nietrywialnych aplikacji i współdzielonych bibliotek.
namespace App\Templating;
use Latte\Extension;
use Nette\Security\Authorizator;
class MyLatteExtension extends Extension
{
public function __construct(
// zakładamy, że usługa Authorizator istnieje
private Authorizator $authorizator,
) {
}
public function getFunctions(): array
{
// rejestrujemy metody jako funkcje Latte
return [
'hasPermission' => $this->hasPermission(...),
];
}
public function hasPermission(string $resource, string $action): bool
{
return $this->authorizator->isAllowed($resource, $action);
}
}
// rejestracja (zakładamy, że $container zawiera kontener DI)
$extension = $container->getByType(MyLatteExtension::class);
$latte = new Latte\Engine;
$latte->addExtension($extension);
To podejście wyraźnie pokazuje, jak funkcje zdefiniowane w Latte mogą być oparte na metodach obiektów, które z kolei mogą mieć własne zależności zarządzane przez kontener wstrzykiwania zależności lub fabrykę Twojej aplikacji. Logika szablonów pozostaje dzięki temu połączona z rdzeniem aplikacji, a jednocześnie uporządkowana.
Funkcje używające klasy z atrybutami
Tak samo jak filtry, funkcje można definiować jako metody w klasie parametrów szablonu za pomocą atrybutu
#[Latte\Attributes\TemplateFunction].
use Latte\Attributes\TemplateFunction;
class TemplateParameters
{
public function __construct(
public string $userName,
// inne parametry...
) {}
// ta metoda staje się w szablonie dostępna jako {initials(...)}
#[TemplateFunction]
public function initials(string $name): string
{
preg_match_all('#\b\w#u', $name, $m);
return implode('. ', $m[0]) . '.';
}
}
// przekazujemy obiekt do szablonu
$params = new TemplateParameters(userName: 'John Doe', /* ... */);
$latte->render('template.latte', $params);
Latte automatycznie odnajduje i rejestruje metody oznaczone tym atrybutem, gdy obiekt parametrów zostanie przekazany do szablonu. Nazwa funkcji w szablonie odpowiada nazwie metody.
{* użycie funkcji zdefiniowanej w klasie parametrów *}
{var $inits = initials($userName)}
Funkcje kontekstowe?
W odróżnieniu od filtrów funkcje nie otrzymują obiektu FilterInfo. Funkcja może jednak uzyskać dostęp do
kontekstu szablonu: jeśli jej pierwszy parametr ma typ Latte\Runtime\Template, Latte automatycznie przekaże do niej
bieżący obiekt szablonu. Dokładnie tak zaimplementowane są wbudowane funkcje hasBlock() i
hasTemplate().