Sablonok
A Nette a Latte sablonrendszert használja. A Latte-t azért használjuk, mert ez a legbiztonságosabb sablonrendszer a PHP számára, ugyanakkor a legintuitívabb rendszer. Nem kell sok újat tanulnod, csak ismerned kell a PHP-t és néhány Latte taget.
Az a szokásos, hogy az oldal az elrendezési sablonból + az akció sablonból készül el. Így nézhet ki egy layout sablon,
figyeld meg a {block}
blokkokat és a {include}
címkét :
<!DOCTYPE html>
<html>
<head>
<title>{block title}My App{/block}</title>
</head>
<body>
<header>...</header>
{include content}
<footer>...</footer>
</body>
</html>
És ez lehet az akció sablon:
{block title}Homepage{/block}
{block content}
<h1>Homepage</h1>
...
{/block}
Meghatározza a content
blokkot, amely az elrendezésben a {include content}
helyére kerül, és
újra definiálja a title
blokkot is, amely felülírja az elrendezésben a {block title}
blokkot.
Próbálja meg elképzelni az eredményt.
Sablonok keresése
A sablonok elérési útvonalát egyszerű logika szerint vezetjük le. Megpróbálja megnézni, hogy létezik-e valamelyik
sablonfájl ahhoz a könyvtárhoz képest, ahol a prezenter osztály található, ahol a <Presenter>
az
aktuális prezenter neve és <view>
az aktuális művelet neve:
templates/<Presenter>/<view>.latte
templates/<Presenter>.<view>.latte
Ha a sablon nem található, a program megpróbál a templates
könyvtárban keresni egy szinttel feljebb, azaz
ugyanazon a szinten, mint a bemutató osztályt tartalmazó könyvtár.
Ha a sablon ott sem található, a válasz 404-es hiba.
A nézetet a $this->setView('otherView')
segítségével is megváltoztathatja. Vagy a keresés helyett
közvetlenül megadhatja a sablonfájl nevét a $this->template->setFile('/path/to/template.latte')
segítségével.
A formatTemplateFiles metódus felülbírálásával módosíthatja azokat az elérési utakat, ahol a sablonok keresése történik, amely a lehetséges fájl elérési utak tömbjét adja vissza.
Az elrendezés a következő fájlokban várható:
templates/<Presenter>/@<layout>.latte
templates/<Presenter>.@<layout>.latte
templates/@<layout>.latte
több előadónál közös elrendezés
<Presenter>
az aktuális előadó neve és <layout>
az elrendezés neve, amely
alapértelmezés szerint 'layout'
. A név megváltoztatható a $this->setLayout('otherLayout')
segítségével, így a @otherLayout.latte
fájlokat próbálja meg.
Az elrendezéssablon fájlnevét közvetlenül is megadhatja a $this->setLayout('/path/to/template.latte')
segítségével. A $this->setLayout(false)
használata letiltja az elrendezés keresését.
A formatLayoutTemplateFiles metódus felülbírálásával módosíthatja a sablonok keresési útvonalait, amely a lehetséges fájlútvonalak tömbjét adja vissza.
Változók a sablonban
A változókat a $this->template
címre írva adjuk át a sablonba, majd a sablonban helyi változóként
állnak rendelkezésre:
$this->template->article = $this->articles->getById($id);
Így könnyen átadhatunk bármilyen változót a sablonoknak. Robusztus alkalmazások fejlesztésénél azonban gyakran hasznosabb, ha korlátozzuk magunkat. Például úgy, hogy explicit módon definiáljuk a sablon által elvárt változók listáját és azok típusát. Ez lehetővé teszi a PHP számára a típusellenőrzést, az IDE számára a helyes automatikus kitöltést, a statikus elemzés számára pedig a hibák felderítését.
És hogyan definiáljunk egy ilyen felsorolást? Egyszerűen egy osztály és annak tulajdonságai formájában.
A presenterhez hasonlóan nevezzük el, de a végén Template
címmel:
/**
* @property-read ArticleTemplate $template
*/
class ArticlePresenter extends Nette\Application\UI\Presenter
{
}
class ArticleTemplate extends Nette\Bridges\ApplicationLatte\Template
{
public Model\Article $article;
public Nette\Security\User $user;
// és egyéb változók
}
A $this->template
objektum a prezenterben mostantól a ArticleTemplate
osztály példánya lesz.
A PHP tehát ellenőrizni fogja a deklarált típusokat íráskor. A PHP 8.2-től kezdve pedig figyelmeztetni fog a nem létező
változóba való írásra is, a korábbi verziókban ugyanezt a Nette\SmartObject tulajdonsággal lehet elérni.
A @property-read
annotáció az IDE és a statikus elemzés számára készült, ez teszi működőképessé az
automatikus kitöltést, lásd PhpStorm és
kódkiegészítés $this->template számára.

A sablonokban is megengedheted magadnak a suttogás luxusát, csak telepítsd a Latte plugint a PhpStormban, és add meg az osztály nevét a sablon elején, lásd a Latte: hogyan kell tipizálni a rendszert című cikket:
{templateType App\Presenters\ArticleTemplate}
...
Így működnek a sablonok a komponensekben is, csak kövesse a névadási konvenciót, és hozzon létre egy sablon osztályt
FifteenTemplate
a komponenshez pl. FifteenControl
.
Ha a $template
egy másik osztály példányaként kell létrehozni, használjuk a createTemplate()
metódust:
public function renderDefault(): void
{
$template = $this->createTemplate(SpecialTemplate::class);
$template->foo = 123;
// ...
$this->sendTemplate($template);
}
Alapértelmezett változók
A prezenterek és komponensek számos hasznos változót adnak át automatikusan a sablonoknak:
$basePath
egy abszolút URL elérési útvonal a gyökérkönyvtárhoz (például/CD-collection
).$baseUrl
egy abszolút URL cím a gyökérkönyvtárhoz (pl.http://localhost/CD-collection
)$user
egy objektum, amely a felhasználót képviseli$presenter
az aktuális előadó$control
az aktuális komponens vagy bemutató$flashes
a módszer által küldött üzenetek listájaflashMessage()
Ha egyéni sablonosztályt használ, ezeket a változókat akkor adja át, ha létrehoz egy tulajdonságot számukra.
Linkek létrehozása
A sablonban az alábbiak szerint hozunk létre linkeket más előadókra és műveletekre:
<a n:href="Product:show">detail</a>
A n:href
attribútum nagyon hasznos a HTML címkékhez. <a>
. Ha a linket máshol, például a
szövegben akarjuk kiírni, akkor a {link}
-t használjuk:
URL is: {link Home:default}
További információért lásd: Linkek létrehozása.
Egyéni szűrők, címkék stb.
A Latte templating rendszer kibővíthető egyéni szűrőkkel, függvényekkel, címkékkel stb. Ez közvetlenül a
render<View>
vagy a beforeRender()
metódusban:
public function beforeRender(): void
{
// szűrő hozzáadása
$this->template->addFilter('foo', /* ... */);
// vagy közvetlenül a Latte\Engine objektum konfigurálása
$latte = $this->template->getLatte();
$latte->addFilterLoader(/* ... */);
}
A Latte 3. verziója egy fejlettebb módszert kínál, amely minden egyes webes projekthez egy bővítményt hoz létre. Íme egy durva példa egy ilyen osztályra:
namespace App\Templating;
final class LatteExtension extends Latte\Extension
{
public function __construct(
private App\Model\Facade $facade,
private Nette\Security\User $user,
// ...
) {
}
public function getFilters(): array
{
return [
'timeAgoInWords' => $this->filterTimeAgoInWords(...),
'money' => $this->filterMoney(...),
// ...
];
}
public function getFunctions(): array
{
return [
'canEditArticle' =>
fn($article) => $this->facade->canEditArticle($article, $this->user->getId()),
// ...
];
}
// ...
}
A configuration segítségével regisztráljuk:
latte:
extensions:
- App\Templating\LatteExtension
Fordítás
Ha többnyelvű alkalmazást programoz, valószínűleg a sablonban lévő szöveg egy részét különböző nyelveken kell
majd kiadnia. Ehhez a Nette Framework definiál egy fordítási felületet Nette\Localization\Translator, amelynek
egyetlen metódusa a translate()
. Ez elfogadja a $message
üzenetet, amely általában egy
karakterlánc, és bármilyen más paramétert. A feladat a lefordított karakterlánc visszaadása. A Nette-ben nincs
alapértelmezett implementáció, a Componette-en található számos
kész megoldás közül választhatunk igényeinknek megfelelően. A dokumentációjukból megtudhatjuk, hogyan kell a fordítót
konfigurálni.
A sablonokat a setTranslator()
metódus segítségével állíthatjuk be egy fordítóval, amelyet átadunk magunknak:
protected function beforeRender(): void
{
// ...
$this->template->setTranslator($translator);
}
Alternatívaként a fordítót a konfiguráció segítségével is beállíthatjuk:
latte:
extensions:
- Latte\Essential\TranslatorExtension
A fordító ekkor például a |translate
szűrőként használható, a translate()
metódusnak
átadott további paraméterekkel (lásd foo, bar
):
<a href="basket">{='Basket'|translate}</a>
<span>{$item|translate}</span>
<span>{$item|translate, foo, bar}</span>
Vagy aláhúzáscímkeként:
<a href="basket">{_'Basket'}</a>
<span>{_$item}</span>
<span>{_$item, foo, bar}</span>
A sablonrészlet fordításához van egy párosított tag {translate}
(a Latte 2.11 óta, korábban a
{_}
taget használták ):
<a href="order">{translate}Order{/translate}</a>
<a href="order">{translate foo, bar}Order{/translate}</a>
A fordítót alapértelmezés szerint futásidőben hívja meg a sablon renderelésekor. A Latte 3. verziója azonban képes lefordítani az összes statikus szöveget a sablon összeállítása során. Ez teljesítményt takarít meg, mivel minden egyes karakterláncot csak egyszer fordít le, és az így kapott fordítás a lefordított formába kerül. Ez a sablon több lefordított változatát hozza létre a gyorsítótárban, egyet-egyet minden nyelvhez. Ehhez csak a nyelvet kell megadni második paraméterként:
protected function beforeRender(): void
{
// ...
$this->template->setTranslator($translator, $lang);
}
Statikus szöveg alatt például a {_'hello'}
vagy a {translate}hello{/translate}
szöveget értjük.
A nem statikus szövegek, például a {_$foo}
, továbbra is menet közben kerülnek lefordításra.