Predloge
Nette uporablja sistem predlog Latte. Delsno zato, ker gre za najbolj varen sistem predlog za PHP, in hkrati tudi najbolj intuitiven sistem. Ni se vam treba učiti veliko novega, zadostuje znanje PHP in nekaj značk.
Običajno je, da se stran sestavi iz predloge postavitve + predloge dane akcije. Takole na primer lahko izgleda predloga
postavitve, opazite bloke {block}
in značko {include}
:
<!DOCTYPE html>
<html>
<head>
<title>{block title}Moja Aplikacija{/block}</title>
</head>
<body>
<header>...</header>
{include content}
<footer>...</footer>
</body>
</html>
In tole bo predloga akcije:
{block title}Domača stran{/block}
{block content}
<h1>Domača stran</h1>
...
{/block}
Ta definira blok content
, ki se vstavi na mesto {include content}
v postavitvi, in tudi ponovno
definira blok title
, s katerim prepiše {block title}
v postavitvi. Poskusite si predstavljati
rezultat.
Iskanje predlog
Ni vam treba v presenterjih navajati, katera predloga naj se izriše, ogrodje pot izpelje samo in vam prihrani pisanje.
Če uporabljate strukturo map, kjer ima vsak presenter svojo mapo, preprosto namestite predlogo v to mapo pod imenom akcije
(oz. view), tj. za akcijo default
uporabite predlogo default.latte
:
app/ └── Presentation/ └── Home/ ├── HomePresenter.php └── default.latte
Če uporabljate strukturo, kjer so skupaj presenterji v eni mapi in predloge v mapi templates
, jo shranite
bodisi v datoteko <Presenter>.<view>.latte
ali <Presenter>/<view>.latte
:
app/ └── Presenters/ ├── HomePresenter.php └── templates/ ├── Home.default.latte ← 1. varianta └── Home/ └── default.latte ← 2. varianta
Mapa templates
je lahko nameščena tudi eno raven višje, tj. na isti ravni, kot je mapa z razredi
presenterjev.
Če predloga ni najdena, presenter odgovori z napako 404 – stran ni najdena.
View spremenite s pomočjo $this->setView('jineView')
. Prav tako lahko neposredno določite datoteko
s predlogo s pomočjo $this->template->setFile('/path/to/template.latte')
.
Datoteke, kjer se iščejo predloge, lahko spremenite s prepisom metode formatTemplateFiles(), ki vrne polje možnih imen datotek.
Iskanje predloge postavitve
Nette tudi samodejno išče datoteko s postavitvijo.
Če uporabljate strukturo map, kjer ima vsak presenter svojo mapo, namestite postavitev bodisi v mapo s presenterjem, če je specifična samo zanj, ali eno raven višje, če je skupna za več presenterjev:
app/ └── Presentation/ ├── @layout.latte ← skupna postavitev └── Home/ ├── @layout.latte ← samo za presenter Home ├── HomePresenter.php └── default.latte
Če uporabljate strukturo, kjer so skupaj presenterji v eni mapi in predloge v mapi templates
, se bo postavitev
pričakovala na teh mestih:
app/ └── Presenters/ ├── HomePresenter.php └── templates/ ├── @layout.latte ← skupna postavitev ├── Home.@layout.latte ← samo za Home, 1. varianta └── Home/ └── @layout.latte ← samo za Home, 2. varianta
Če se presenter nahaja v modulu, se bo iskalo tudi na višjih ravneh map, glede na gnezdenje modula.
Ime postavitve lahko spremenite s pomočjo $this->setLayout('layoutAdmin')
in potem se bo pričakovalo
v datoteki @layoutAdmin.latte
. Prav tako lahko neposredno določite datoteko s predlogo postavitve s pomočjo
$this->setLayout('/path/to/template.latte')
.
S pomočjo $this->setLayout(false)
ali značke {layout none}
znotraj predloge se iskanje
postavitve izklopi.
Datoteke, kjer se iščejo predloge postavitve, lahko spremenite s prepisom metode formatLayoutTemplateFiles(), ki vrne polje možnih imen datotek.
Spremenljivke v predlogi
Spremenljivke v predlogo posredujemo tako, da jih zapišemo v $this->template
in potem jih imamo na voljo
v predlogi kot lokalne spremenljivke:
$this->template->article = $this->articles->getById($id);
Tako enostavno lahko v predloge posredujemo kakršnekoli spremenljivke. Pri razvoju robustnih aplikacij pa je običajno bolj koristno se omejiti. Na primer tako, da eksplicitno definiramo seznam spremenljivk, ki jih predloga pričakuje, in njihovih tipov. Zahvaljujoč temu nam bo lahko PHP preverjal tipe, IDE pravilno predlagal in statična analiza odkrivala napake.
In kako takšen seznam definiramo? Preprosto v obliki razreda in njegovih lastnosti. Poimenujemo ga podobno kot presenter, le
s Template
na koncu:
/**
* @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;
// in druge spremenljivke
}
Objekt $this->template
v presenterju bo zdaj instanca razreda ArticleTemplate
. Tako bo PHP pri
zapisu preverjal deklarirane tipe. In od različice PHP 8.2 naprej bo opozoril tudi na zapis v neobstoječo spremenljivko,
v prejšnjih različicah lahko isto dosežemo z uporabo traite Nette\SmartObject.
Anotacija @property-read
je namenjena za IDE in statično analizo, zahvaljujoč njej bo delovalo predlaganje, glej
PhpStorm and code completion for
$this->template.

Luksuza predlaganja si lahko privoščite tudi v predlogah, dovolj je v PhpStorm namestiti vtičnik za Latte in navesti na začetek predloge ime razreda, več v članku Latte: kako do tipskega sistema:
{templateType App\Presentation\Article\ArticleTemplate}
...
Tako delujejo tudi predloge v komponentah, dovolj je le upoštevati imensko konvencijo in za komponento npr.
FifteenControl
ustvariti razred predloge FifteenTemplate
.
Če potrebujete ustvariti $template
kot instanco drugega razreda, uporabite metodo
createTemplate()
:
public function renderDefault(): void
{
$template = $this->createTemplate(SpecialTemplate::class);
$template->foo = 123;
// ...
$this->sendTemplate($template);
}
Privzete spremenljivke
Presenterji in komponente samodejno posredujejo v predloge nekaj uporabnih spremenljivk:
$basePath
je absolutna URL pot do korenskega direktorija (npr./eshop
)$baseUrl
je absolutni URL do korenskega direktorija (npr.http://localhost/eshop
)$user
je objekt ki predstavlja uporabnika$presenter
je trenutni presenter$control
je trenutna komponenta ali presenter$flashes
polje sporočil poslanih s funkcijoflashMessage()
Če uporabljate lasten razred predloge, se te spremenljivke posredujejo, če zanje ustvarite lastnost.
Ustvarjanje povezav
V predlogi se ustvarjajo povezave na druge presenterje & akcije na ta način:
<a n:href="Product:show">podrobnosti izdelka</a>
Atribut n:href
je zelo priročen za HTML značke <a>
. Če želimo povezavo izpisati drugje, na
primer v besedilu, uporabimo {link}
:
Naslov je: {link Home:default}
Več informacij najdete v poglavju Ustvarjanje URL povezav.
Lastni filtri, značke ipd.
Sistem predlog Latte lahko razširimo z lastnimi filtri, funkcijami, značkami ipd. To lahko storimo neposredno v metodi
render<View>
ali beforeRender()
:
public function beforeRender(): void
{
// dodajanje filtra
$this->template->addFilter('foo', /* ... */);
// ali konfiguriramo neposredno objekt Latte\Engine
$latte = $this->template->getLatte();
$latte->addFilterLoader(/* ... */);
}
Latte v različici 3 ponuja naprednejši način in to je ustvarjanje si extension za vsak spletni projekt. Primer takšnega razreda:
namespace App\Presentation\Accessory;
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()),
// ...
];
}
// ...
}
Registriramo jo s pomočjo konfiguracije:
latte:
extensions:
- App\Presentation\Accessory\LatteExtension
Prevajanje
Če programirate večjezično aplikacijo, boste najverjetneje potrebovali nekatera besedila v predlogi izpisati v različnih
jezikih. Nette Framework za ta namen definira vmesnik za prevajanje Nette\Localization\Translator, ki ima eno samo
metodo translate()
. Ta sprejema sporočilo $message
, kar je praviloma niz, in poljubne druge parametre.
Naloga je vrniti preveden niz. V Nette ni nobene privzete implementacije, lahko si izberete glede na svoje potrebe iz več
pripravljenih rešitev, ki jih najdete na Componette. V njihovi
dokumentaciji boste izvedeli, kako prevajalnik konfigurirati.
Predlogam lahko nastavimo prevajalnik, ki si ga pustimo posredovati, z metodo
setTranslator()
:
protected function beforeRender(): void
{
// ...
$this->template->setTranslator($translator);
}
Prevajalnik je alternativno mogoče nastaviti s pomočjo konfiguracije:
latte:
extensions:
- Latte\Essential\TranslatorExtension(@Nette\Localization\Translator)
Nato lahko prevajalnik uporabljamo na primer kot filter |translate
, in to vključno z dopolnilnimi parametri, ki
se posredujejo metodi translate()
(glej foo, bar
):
<a href="basket">{='Košarica'|translate}</a>
<span>{$item|translate}</span>
<span>{$item|translate, foo, bar}</span>
Ali kot podčrtajno značko:
<a href="basket">{_'Košarica'}</a>
<span>{_$item}</span>
<span>{_$item, foo, bar}</span>
Za prevod odseka predloge obstaja parna značka {translate}
(od Latte 2.11, prej se je uporabljala značka
{_}
):
<a href="order">{translate}Naročilo{/translate}</a>
<a href="order">{translate foo, bar}Naročilo{/translate}</a>
Prevajalnik se standardno kliče med izvajanjem pri izrisovanju predloge. Latte različice 3 pa zna vsa statična besedila prevajati že med kompilacijo predloge. S tem se prihrani zmogljivost, ker se vsak niz prevede samo enkrat in končni prevod se zapiše v prevedeno obliko. V mapi s predpomnilnikom tako nastane več prevedenih različic predloge, ena za vsak jezik. Za to je dovolj le navesti jezik kot drugi parameter:
protected function beforeRender(): void
{
// ...
$this->template->setTranslator($translator, $lang);
}
Statično besedilo je mišljeno na primer {_'hello'}
ali {translate}hello{/translate}
. Nestatična
besedila, kot na primer {_$foo}
, se bodo še naprej prevajala med izvajanjem.