Șabloane

Nette utilizează sistemul de șabloane Latte. Latte este utilizat deoarece este cel mai sigur sistem de șabloane pentru PHP și, în același timp, cel mai intuitiv sistem. Nu trebuie să învățați prea multe lucruri noi, trebuie doar să cunoașteți PHP și câteva etichete Latte.

Este obișnuit ca pagina să fie completată din șablonul layout + șablonul de acțiune. Iată cum ar putea arăta un șablon layout, observați blocurile {block} și tag-ul {include}:

<!DOCTYPE html>
<html>
<head>
	<title>{block title}My App{/block}</title>
</head>
<body>
	<header>...</header>
	{include content}
	<footer>...</footer>
</body>
</html>

Iar acesta ar putea fi șablonul de acțiune:

{block title}Homepage{/block}

{block content}
<h1>Homepage</h1>
...
{/block}

Acesta definește blocul content, care este inserat în locul lui {include content} în machetă și, de asemenea, redefinește blocul title, care suprascrie {block title} în machetă. Încercați să vă imaginați rezultatul.

Căutați șabloane

Calea către șabloane este dedusă conform unei logici simple. Se încearcă să se vadă dacă unul dintre aceste fișiere șablon există în raport cu directorul în care se află clasa presenter, unde <Presenter> este numele prezentatorului curent și <view> este numele acțiunii curente:

  • templates/<Presenter>/<view>.latte
  • templates/<Presenter>.<view>.latte

Dacă șablonul nu este găsit, se va încerca căutarea în directorul templates cu un nivel mai sus, adică la același nivel cu directorul cu clasa de prezentator.

Dacă șablonul nu este găsit nici acolo, răspunsul este o eroare 404.

De asemenea, puteți schimba vizualizarea folosind $this->setView('otherView'). Sau, în loc să căutați, specificați direct numele fișierului șablon folosind $this->template->setFile('/path/to/template.latte').

Puteți modifica căile în care sunt căutate șabloanele prin suprascrierea metodei formatTemplateFiles, care returnează o matrice de posibile căi de acces la fișiere.

Prezentarea este așteptată în următoarele fișiere:

  • templates/<Presenter>/@<layout>.latte
  • templates/<Presenter>.@<layout>.latte
  • templates/@<layout>.latte aspect comun pentru mai mulți prezentatori

<Presenter> este numele prezentatorului curent și <layout> este numele structurii, care este în mod implicit 'layout'. Numele poate fi schimbat cu $this->setLayout('otherLayout'), astfel încât să se încerce să se utilizeze fișierele @otherLayout.latte.

De asemenea, puteți specifica direct numele de fișier al șablonului de machetă cu $this->setLayout('/path/to/template.latte'). Utilizarea $this->setLayout(false) va dezactiva căutarea de machete.

Puteți modifica căile de căutare a șabloanelor prin suprascrierea metodei formatLayoutTemplateFiles, care returnează o matrice de posibile căi de acces la fișiere.

Variabilele din șablon

Variabilele sunt transmise șablonului prin scrierea lor pe $this->template și apoi sunt disponibile în șablon ca variabile locale:

$this->template->article = $this->articles->getById($id);

În acest fel, putem trece cu ușurință orice variabile în șabloane. Cu toate acestea, atunci când dezvoltăm aplicații robuste, este adesea mai util să ne limităm. De exemplu, prin definirea explicită a unei liste de variabile pe care șablonul le așteaptă și a tipurilor acestora. Acest lucru va permite PHP să verifice tipul, IDE-ului să se autocompleteze corect, iar analizei statice să detecteze erorile.

Și cum definim o astfel de enumerare? Pur și simplu sub forma unei clase și a proprietăților sale. O denumim în mod similar cu presenter, dar cu Template la sfârșit:

/**
 * @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;

	// și alte variabile
}

Obiectul $this->template din prezentator va fi acum o instanță a clasei ArticleTemplate. Astfel, PHP va verifica tipurile declarate atunci când acestea sunt scrise. Începând cu PHP 8.2, PHP va avertiza, de asemenea, în cazul în care se scrie pe o variabilă inexistentă; în versiunile anterioare, același lucru poate fi realizat cu ajutorul trăsăturii Nette\SmartObject.

Adnotarea @property-read este pentru IDE și analiza statică, va face ca autocompletarea să funcționeze, a se vedea PhpStorm și finalizarea codului pentru $this->template.

Vă puteți permite și luxul de a șopti în șabloane, trebuie doar să instalați pluginul în PhpStorm și să specificați numele clasei la începutul șablonului, consultați articolul Latte: cum se tastează sistemul:

{templateType App\Presenters\ArticleTemplate}
...

Acesta este, de asemenea, modul în care funcționează șabloanele în componente, trebuie doar să urmați convenția de denumire și să creați o clasă șablon FifteenTemplate pentru componentă, de exemplu FifteenControl.

Dacă aveți nevoie să creați un $template ca instanță a unei alte clase, utilizați metoda createTemplate():

public function renderDefault(): void
{
	$template = $this->createTemplate(SpecialTemplate::class);
	$template->foo = 123;
	// ...
	$this->sendTemplate($template);
}

Variabile implicite

Prezentatorii și componentele transmit automat mai multe variabile utile către șabloane:

  • $basePath este o cale URL absolută către directorul rădăcină (de exemplu, /CD-collection)
  • $baseUrl este o adresă URL absolută către directorul rădăcină (de exemplu http://localhost/CD-collection)
  • $user este un obiect care reprezintă utilizatorul
  • $presenter este prezentatorul curent
  • $control este componenta sau prezentatorul curent
  • $flashes lista mesajelor trimise prin metoda flashMessage()

Dacă utilizați o clasă de șablon personalizată, aceste variabile sunt transmise dacă creați o proprietate pentru ele.

În șablon, creăm legături către alți prezentatori și acțiuni după cum urmează:

<a n:href="Product:show">detail</a>

Atributul n:href este foarte util pentru etichetele HTML <a>. Dacă dorim să imprimăm link-ul în altă parte, de exemplu în text, folosim {link}:

URL is: {link Home:default}

Pentru mai multe informații, consultați Crearea de linkuri.

Filtre personalizate, etichete etc.

Sistemul de modelare Latte poate fi extins cu filtre, funcții, etichete etc. personalizate. Acest lucru se poate face direct în render<View> sau beforeRender():

public function beforeRender(): void
{
	// adăugarea unui filtru
	$this->template->addFilter('foo', /* ... */);

	// sau configurați direct obiectul Latte\Engine
	$latte = $this->template->getLatte();
	$latte->addFilterLoader(/* ... */);
}

Latte versiunea 3 oferă o metodă mai avansată prin crearea unei extensii pentru fiecare proiect web. Iată un exemplu aproximativ al unei astfel de clase:

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()),
			// ...
		];
	}

	// ...
}

O înregistrăm folosind configuration:

latte:
	extensions:
		- App\Templating\LatteExtension

Traducerea

Dacă programați o aplicație multilingvă, probabil că va trebui să scoateți o parte din textul din șablon în diferite limbi. Pentru a face acest lucru, Nette Framework definește o interfață de traducere Nette\Localization\Translator, care are o singură metodă translate(). Aceasta acceptă mesajul $message, care este de obicei un șir de caractere, și orice alți parametri. Sarcina este de a returna șirul tradus. Nu există o implementare implicită în Nette, puteți alege în funcție de nevoile dumneavoastră din mai multe soluții gata făcute care pot fi găsite pe Componette. Documentația acestora vă spune cum să configurați traducătorul.

Șabloanele pot fi configurate cu un traducător, pe care ni-l vom trece, folosind metoda setTranslator():

protected function beforeRender(): void
{
	// ...
	$this->template->setTranslator($translator);
}

Alternativ, traducătorul poate fi setat cu ajutorul configurației:

latte:
	extensions:
		- Latte\Essential\TranslatorExtension

Traducătorul poate fi apoi utilizat, de exemplu, ca filtru |translate, cu parametri suplimentari trecuți la metoda translate() (a se vedea foo, bar):

<a href="basket">{='Basket'|translate}</a>
<span>{$item|translate}</span>
<span>{$item|translate, foo, bar}</span>

Sau ca o etichetă de subliniere:

<a href="basket">{_'Basket'}</a>
<span>{_$item}</span>
<span>{_$item, foo, bar}</span>

Pentru traducerea secțiunii de șablon, există o etichetă pereche {translate} (de la Latte 2.11, anterior se folosea eticheta {_} ):

<a href="order">{translate}Order{/translate}</a>
<a href="order">{translate foo, bar}Order{/translate}</a>

Traducătorul este apelat în mod implicit în timpul execuției la redarea șablonului. Cu toate acestea, versiunea 3 a Latte poate traduce tot textul static în timpul compilării șablonului. Acest lucru economisește performanță, deoarece fiecare șir de caractere este tradus o singură dată, iar traducerea rezultată este scrisă în formularul compilat. Astfel, se creează mai multe versiuni compilate ale șablonului în directorul cache, una pentru fiecare limbă. Pentru a face acest lucru, trebuie doar să specificați limba ca al doilea parametru:

protected function beforeRender(): void
{
	// ...
	$this->template->setTranslator($translator, $lang);
}

Prin text static înțelegem, de exemplu, {_'hello'} sau {translate}hello{/translate}. Textul nestatic, cum ar fi {_$foo}, va continua să fie compilat din mers.

versiune: 4.0