Nette Documentation Preview

syntax
Şablonlar
*********

.[perex]
Nette [Latte |latte:] şablon sistemini kullanır. Latte, PHP için en güvenli şablon sistemi ve aynı zamanda en sezgisel sistem olduğu için kullanılır. Yeni bir şey öğrenmenize gerek yok, sadece PHP ve birkaç Latte etiketi bilmeniz yeterli.

Sayfanın düzen şablonu + eylem şablonundan tamamlanması olağandır. Bir düzen şablonu böyle görünebilir, `{block}` bloklarına ve `{include}` etiketine dikkat edin:

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

Bu da eylem şablonu olabilir:

```latte
{block title}Homepage{/block}

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

Düzende `{include content}` yerine eklenen `content` bloğunu tanımlar ve ayrıca düzende `{block title}` 'un üzerine yazılan `title` bloğunu yeniden tanımlar. Sonucu hayal etmeye çalışın.


Şablon Arama .[#toc-search-for-templates]
-----------------------------------------

Şablonların yolu basit bir mantığa göre çıkarılır. Sunucu sınıfının bulunduğu dizine göre bu şablon dosyalarından birinin var olup olmadığına bakılır, burada `<Presenter>` geçerli sunum yapan kişinin adı ve `<view>` geçerli eylemin adıdır:

- `templates/<Presenter>/<view>.latte`
- `templates/<Presenter>.<view>.latte`

Şablon bulunamazsa, `templates` dizininde bir seviye yukarıda, yani sunum yapan sınıfın bulunduğu dizinle aynı seviyede arama yapmaya çalışacaktır.

Şablon orada da bulunamazsa, yanıt [404 hatası |presenters#Error 404 etc.] olur.

Ayrıca `$this->setView('otherView')` adresini kullanarak görünümü değiştirebilirsiniz. Ya da arama yapmak yerine `$this->template->setFile('/path/to/template.latte')` adresini kullanarak şablon dosyasının adını doğrudan belirtin.

.[note]
Olası dosya yollarından oluşan bir dizi döndüren [formatTemplateFiles |api:Nette\Application\UI\Presenter::formatTemplateFiles()] yöntemini geçersiz kılarak şablonların arandığı yolları değiştirebilirsiniz.

Düzen aşağıdaki dosyalarda beklenmektedir:

- `templates/<Presenter>/@<layout>.latte`
- `templates/<Presenter>.@<layout>.latte`
- `templates/@<layout>.latte` birden fazla sunumcu için ortak düzen

`<Presenter>` geçerli sunum yapan kişinin adı ve `<layout>` varsayılan olarak `'layout'` olan düzenin adıdır. İsim `$this->setLayout('otherLayout')` ile değiştirilebilir, böylece `@otherLayout.latte` dosyaları denenecektir.

Düzen şablonunun dosya adını `$this->setLayout('/path/to/template.latte')` adresini kullanarak doğrudan da belirtebilirsiniz. `$this->setLayout(false)` adresini kullanmak düzen aramayı devre dışı bırakacaktır.

.[note]
Olası dosya yollarından oluşan bir dizi döndüren [formatLayoutTemplateFiles |api:Nette\Application\UI\Presenter::formatLayoutTemplateFiles()] yöntemini geçersiz kılarak şablonların arandığı yolları değiştirebilirsiniz.


Şablondaki Değişkenler .[#toc-variables-in-the-template]
--------------------------------------------------------

Değişkenler `$this->template` adresine yazılarak şablona aktarılır ve daha sonra yerel değişkenler olarak şablonda kullanılabilir:

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

Bu şekilde herhangi bir değişkeni şablonlara kolayca aktarabiliriz. Ancak, sağlam uygulamalar geliştirirken, kendimizi sınırlamak genellikle daha yararlıdır. Örneğin, şablonun beklediği değişkenlerin ve türlerinin bir listesini açıkça tanımlayarak. Bu, PHP'nin tip kontrolü yapmasına, IDE'nin doğru şekilde otomatik tamamlama yapmasına ve statik analizin hataları tespit etmesine olanak tanıyacaktır.

Peki böyle bir numaralandırmayı nasıl tanımlarız? Basitçe bir sınıf ve onun özellikleri şeklinde. Bunu presenter'a benzer şekilde adlandırıyoruz, ancak sonunda `Template` var:

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

	// ve diğer değişkenler
}
```

Sunucudaki `$this->template` nesnesi artık `ArticleTemplate` sınıfının bir örneği olacaktır. Böylece PHP, yazıldıklarında bildirilen türleri kontrol edecektir. PHP 8.2'den başlayarak, varolmayan bir değişkene yazma konusunda da uyaracaktır, önceki sürümlerde aynı şey [Nette\SmartObject |utils:smartobject] özelliği kullanılarak elde edilebilir.

`@property-read` ek açıklaması IDE ve statik analiz içindir, otomatik tamamlamanın çalışmasını sağlar, "PhpStorm ve $this->template için kod tamamlama":https://blog.nette.org/en/phpstorm-and-code-completion-for-this-template bölümüne bakın.

[* phpstorm-completion.webp *]

Şablonlarda da fısıldama lüksünün tadını çıkarabilirsiniz, sadece PhpStorm'da Latte eklentisini kurun ve şablonun başında sınıf adını belirtin, "Latte: sistem nasıl yazılır":https://blog.nette.org/tr/latte-tip-sistemi-nasil-kullanilir makalesine bakın:

```latte
{templateType App\Presenters\ArticleTemplate}
...
```

Şablonlar bileşenlerde de bu şekilde çalışır, sadece adlandırma kuralını takip edin ve bileşen için bir şablon sınıfı `FifteenTemplate` oluşturun, örneğin `FifteenControl`.

Başka bir sınıfın örneği olarak bir `$template` oluşturmanız gerekiyorsa, `createTemplate()` yöntemini kullanın:

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


Varsayılan Değişkenler .[#toc-default-variables]
------------------------------------------------

Sunucular ve bileşenler çeşitli faydalı değişkenleri şablonlara otomatik olarak aktarır:

- `$basePath` kök dizine giden mutlak bir URL yoludur (örneğin `/CD-collection`)
- `$baseUrl` kök dizine mutlak bir URL'dir (örneğin `http://localhost/CD-collection`)
- `$user` [kullanıcıyı temsil eden bir nesnedir|security:authentication]
- `$presenter` şu anki sunucu
- `$control` geçerli bileşen veya sunum yapan kişidir
- `$flashes` yöntem tarafından gönderilen [mesajların |presenters#flash-messages] listesi `flashMessage()`

Özel bir şablon sınıfı kullanıyorsanız, bu değişkenler için bir özellik oluşturduğunuzda bu değişkenler geçirilir.


Bağlantı Oluşturma .[#toc-creating-links]
-----------------------------------------

Şablonda diğer sunumculara ve eylemlere aşağıdaki gibi bağlantılar oluşturuyoruz:

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

Öznitelik `n:href` HTML etiketleri için çok kullanışlıdır `<a>`. Bağlantıyı başka bir yere, örneğin metnin içine yazdırmak istiyorsak `{link}` adresini kullanırız:

```latte
URL is: {link Home:default}
```

Daha fazla bilgi için [Bağlantı Oluşturma |Creating Links] bölümüne bakın.


Özel Filtreler, Etiketler vb. .[#toc-custom-filters-tags-etc]
-------------------------------------------------------------

Latte şablonlama sistemi özel filtreler, fonksiyonlar, etiketler vb. ile genişletilebilir. Bu işlem doğrudan `render<View>` veya `beforeRender()` yöntemini kullanabilirsiniz:

```php
public function beforeRender(): void
{
	// bir filtre ekleme
	$this->template->addFilter('foo', /* ... */);

	// veya Latte\Engine nesnesini doğrudan yapılandırın
	$latte = $this->template->getLatte();
	$latte->addFilterLoader(/* ... */);
}
```

Latte sürüm 3, her web projesi için bir [uzantı |latte:creating-extension] oluşturarak daha gelişmiş bir yol sunar. İşte böyle bir sınıfın kabaca bir örneği:

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

	// ...
}
```

[configuration |configuration#Latte] kullanarak kaydediyoruz:

```neon
latte:
	extensions:
		- App\Templating\LatteExtension
```


Çeviri .[#toc-translating]
--------------------------

Çok dilli bir uygulama programlıyorsanız, muhtemelen şablondaki bazı metinlerin çıktısını farklı dillerde almanız gerekecektir. Bunu yapmak için Nette Framework, `translate()` tek bir yöntemi olan bir çeviri arayüzü [api:Nette\Localization\Translator] tanımlar. Bu, genellikle bir dize olan `$message` mesajını ve diğer parametreleri kabul eder. Görev, çevrilmiş dizeyi döndürmektir.
Nette'de varsayılan bir uygulama yoktur, [Componette |https://componette.org/search/localization]'de bulunabilecek çeşitli hazır çözümler arasından ihtiyaçlarınıza göre seçim yapabilirsiniz. Belgeleri size çevirmeni nasıl yapılandıracağınızı anlatır.

Şablonlar, `setTranslator()` yöntemi kullanılarak [bize iletilecek |dependency-injection:passing-dependencies] bir çevirmen ile kurulabilir:

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

Alternatif olarak, çevirmen [yapılandırma |configuration#Latte] kullanılarak ayarlanabilir:

```neon
latte:
	extensions:
		- Latte\Essential\TranslatorExtension
```

Çevirmen daha sonra örneğin `|translate` filtresi olarak kullanılabilir ve ek parametreler `translate()` yöntemine aktarılabilir (bkz. `foo, bar`):

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

Veya bir alt çizgi etiketi olarak:

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

Şablon bölüm çevirisi için eşleştirilmiş bir `{translate}` etiketi vardır (Latte 2.11'den beri, daha önce `{_}` etiketi kullanılıyordu):

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

Çevirmen, şablon oluşturulurken varsayılan olarak çalışma zamanında çağrılır. Ancak Latte sürüm 3, şablon derleme sırasında tüm statik metni çevirebilir. Bu performans tasarrufu sağlar çünkü her dize yalnızca bir kez çevrilir ve sonuçta ortaya çıkan çeviri derlenmiş forma yazılır. Bu, önbellek dizininde şablonun her dil için bir tane olmak üzere birden fazla derlenmiş sürümünü oluşturur. Bunu yapmak için yalnızca ikinci parametre olarak dili belirtmeniz gerekir:

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

Statik metin ile örneğin `{_'hello'}` veya `{translate}hello{/translate}` kastedilmektedir. `{_$foo}` gibi statik olmayan metinler anında derlenmeye devam edecektir.

Şablonlar

Nette Latte şablon sistemini kullanır. Latte, PHP için en güvenli şablon sistemi ve aynı zamanda en sezgisel sistem olduğu için kullanılır. Yeni bir şey öğrenmenize gerek yok, sadece PHP ve birkaç Latte etiketi bilmeniz yeterli.

Sayfanın düzen şablonu + eylem şablonundan tamamlanması olağandır. Bir düzen şablonu böyle görünebilir, {block} bloklarına ve {include} etiketine dikkat edin:

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

Bu da eylem şablonu olabilir:

{block title}Homepage{/block}

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

Düzende {include content} yerine eklenen content bloğunu tanımlar ve ayrıca düzende {block title} 'un üzerine yazılan title bloğunu yeniden tanımlar. Sonucu hayal etmeye çalışın.

Şablon Arama

Şablonların yolu basit bir mantığa göre çıkarılır. Sunucu sınıfının bulunduğu dizine göre bu şablon dosyalarından birinin var olup olmadığına bakılır, burada <Presenter> geçerli sunum yapan kişinin adı ve <view> geçerli eylemin adıdır:

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

Şablon bulunamazsa, templates dizininde bir seviye yukarıda, yani sunum yapan sınıfın bulunduğu dizinle aynı seviyede arama yapmaya çalışacaktır.

Şablon orada da bulunamazsa, yanıt 404 hatası olur.

Ayrıca $this->setView('otherView') adresini kullanarak görünümü değiştirebilirsiniz. Ya da arama yapmak yerine $this->template->setFile('/path/to/template.latte') adresini kullanarak şablon dosyasının adını doğrudan belirtin.

Olası dosya yollarından oluşan bir dizi döndüren formatTemplateFiles yöntemini geçersiz kılarak şablonların arandığı yolları değiştirebilirsiniz.

Düzen aşağıdaki dosyalarda beklenmektedir:

  • templates/<Presenter>/@<layout>.latte
  • templates/<Presenter>.@<layout>.latte
  • templates/@<layout>.latte birden fazla sunumcu için ortak düzen

<Presenter> geçerli sunum yapan kişinin adı ve <layout> varsayılan olarak 'layout' olan düzenin adıdır. İsim $this->setLayout('otherLayout') ile değiştirilebilir, böylece @otherLayout.latte dosyaları denenecektir.

Düzen şablonunun dosya adını $this->setLayout('/path/to/template.latte') adresini kullanarak doğrudan da belirtebilirsiniz. $this->setLayout(false) adresini kullanmak düzen aramayı devre dışı bırakacaktır.

Olası dosya yollarından oluşan bir dizi döndüren formatLayoutTemplateFiles yöntemini geçersiz kılarak şablonların arandığı yolları değiştirebilirsiniz.

Şablondaki Değişkenler

Değişkenler $this->template adresine yazılarak şablona aktarılır ve daha sonra yerel değişkenler olarak şablonda kullanılabilir:

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

Bu şekilde herhangi bir değişkeni şablonlara kolayca aktarabiliriz. Ancak, sağlam uygulamalar geliştirirken, kendimizi sınırlamak genellikle daha yararlıdır. Örneğin, şablonun beklediği değişkenlerin ve türlerinin bir listesini açıkça tanımlayarak. Bu, PHP'nin tip kontrolü yapmasına, IDE'nin doğru şekilde otomatik tamamlama yapmasına ve statik analizin hataları tespit etmesine olanak tanıyacaktır.

Peki böyle bir numaralandırmayı nasıl tanımlarız? Basitçe bir sınıf ve onun özellikleri şeklinde. Bunu presenter'a benzer şekilde adlandırıyoruz, ancak sonunda Template var:

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

	// ve diğer değişkenler
}

Sunucudaki $this->template nesnesi artık ArticleTemplate sınıfının bir örneği olacaktır. Böylece PHP, yazıldıklarında bildirilen türleri kontrol edecektir. PHP 8.2'den başlayarak, varolmayan bir değişkene yazma konusunda da uyaracaktır, önceki sürümlerde aynı şey Nette\SmartObject özelliği kullanılarak elde edilebilir.

@property-read ek açıklaması IDE ve statik analiz içindir, otomatik tamamlamanın çalışmasını sağlar, PhpStorm ve $this->template için kod tamamlama bölümüne bakın.

Şablonlarda da fısıldama lüksünün tadını çıkarabilirsiniz, sadece PhpStorm'da Latte eklentisini kurun ve şablonun başında sınıf adını belirtin, Latte: sistem nasıl yazılır makalesine bakın:

{templateType App\Presenters\ArticleTemplate}
...

Şablonlar bileşenlerde de bu şekilde çalışır, sadece adlandırma kuralını takip edin ve bileşen için bir şablon sınıfı FifteenTemplate oluşturun, örneğin FifteenControl.

Başka bir sınıfın örneği olarak bir $template oluşturmanız gerekiyorsa, createTemplate() yöntemini kullanın:

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

Varsayılan Değişkenler

Sunucular ve bileşenler çeşitli faydalı değişkenleri şablonlara otomatik olarak aktarır:

  • $basePath kök dizine giden mutlak bir URL yoludur (örneğin /CD-collection)
  • $baseUrl kök dizine mutlak bir URL'dir (örneğin http://localhost/CD-collection)
  • $user kullanıcıyı temsil eden bir nesnedir
  • $presenter şu anki sunucu
  • $control geçerli bileşen veya sunum yapan kişidir
  • $flashes yöntem tarafından gönderilen mesajların listesi flashMessage()

Özel bir şablon sınıfı kullanıyorsanız, bu değişkenler için bir özellik oluşturduğunuzda bu değişkenler geçirilir.

Şablonda diğer sunumculara ve eylemlere aşağıdaki gibi bağlantılar oluşturuyoruz:

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

Öznitelik n:href HTML etiketleri için çok kullanışlıdır <a>. Bağlantıyı başka bir yere, örneğin metnin içine yazdırmak istiyorsak {link} adresini kullanırız:

URL is: {link Home:default}

Daha fazla bilgi için Bağlantı Oluşturma bölümüne bakın.

Özel Filtreler, Etiketler vb.

Latte şablonlama sistemi özel filtreler, fonksiyonlar, etiketler vb. ile genişletilebilir. Bu işlem doğrudan render<View> veya beforeRender() yöntemini kullanabilirsiniz:

public function beforeRender(): void
{
	// bir filtre ekleme
	$this->template->addFilter('foo', /* ... */);

	// veya Latte\Engine nesnesini doğrudan yapılandırın
	$latte = $this->template->getLatte();
	$latte->addFilterLoader(/* ... */);
}

Latte sürüm 3, her web projesi için bir uzantı oluşturarak daha gelişmiş bir yol sunar. İşte böyle bir sınıfın kabaca bir örneği:

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

	// ...
}

configuration kullanarak kaydediyoruz:

latte:
	extensions:
		- App\Templating\LatteExtension

Çeviri

Çok dilli bir uygulama programlıyorsanız, muhtemelen şablondaki bazı metinlerin çıktısını farklı dillerde almanız gerekecektir. Bunu yapmak için Nette Framework, translate() tek bir yöntemi olan bir çeviri arayüzü Nette\Localization\Translator tanımlar. Bu, genellikle bir dize olan $message mesajını ve diğer parametreleri kabul eder. Görev, çevrilmiş dizeyi döndürmektir. Nette'de varsayılan bir uygulama yoktur, Componette'de bulunabilecek çeşitli hazır çözümler arasından ihtiyaçlarınıza göre seçim yapabilirsiniz. Belgeleri size çevirmeni nasıl yapılandıracağınızı anlatır.

Şablonlar, setTranslator() yöntemi kullanılarak bize iletilecek bir çevirmen ile kurulabilir:

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

Alternatif olarak, çevirmen yapılandırma kullanılarak ayarlanabilir:

latte:
	extensions:
		- Latte\Essential\TranslatorExtension

Çevirmen daha sonra örneğin |translate filtresi olarak kullanılabilir ve ek parametreler translate() yöntemine aktarılabilir (bkz. foo, bar):

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

Veya bir alt çizgi etiketi olarak:

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

Şablon bölüm çevirisi için eşleştirilmiş bir {translate} etiketi vardır (Latte 2.11'den beri, daha önce {_} etiketi kullanılıyordu):

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

Çevirmen, şablon oluşturulurken varsayılan olarak çalışma zamanında çağrılır. Ancak Latte sürüm 3, şablon derleme sırasında tüm statik metni çevirebilir. Bu performans tasarrufu sağlar çünkü her dize yalnızca bir kez çevrilir ve sonuçta ortaya çıkan çeviri derlenmiş forma yazılır. Bu, önbellek dizininde şablonun her dil için bir tane olmak üzere birden fazla derlenmiş sürümünü oluşturur. Bunu yapmak için yalnızca ikinci parametre olarak dili belirtmeniz gerekir:

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

Statik metin ile örneğin {_'hello'} veya {translate}hello{/translate} kastedilmektedir. {_$foo} gibi statik olmayan metinler anında derlenmeye devam edecektir.