Latte'yi genişletme
Latte, genişletilebilirlik göz önünde tutularak tasarlanmıştır. Standart etiket, filtre ve fonksiyon kümesi birçok kullanım durumunu kapsasa da, sıklıkla kendi özel mantığınızı veya yardımcılarınızı eklemeniz gerekir. Bu sayfa, basit yardımcılardan karmaşık yeni sözdizimlerine kadar, Latte'yi projenizin gereksinimlerine tam olarak uyacak biçimde nasıl genişletebileceğinize genel bir bakış sunar.
Latte'yi genişletme yolları
İşte Latte'yi özelleştirmenin ve genişletmenin başlıca yollarına hızlı bir bakış:
- Özel filtreler: Veriyi doğrudan şablon çıktısında
biçimlendirmek veya dönüştürmek için (örneğin
{$var|myFilter}). Tarih biçimlendirme, metin işleme ya da belirli bir kaçış uygulama gibi işler için idealdir. İçeriği anonim bir{block}içine sarıp özel bir filtre uygulayarak daha büyük HTML içerik bloklarını değiştirmek için de kullanabilirsiniz. - Özel fonksiyonlar: Şablon ifadelerinin içinde
çağrılabilen yeniden kullanılabilir mantık eklemek için (örneğin
{myFunction($arg1, $arg2)}). Hesaplamalar, uygulama yardımcılarına erişim veya küçük içerik parçaları üretmek için yararlıdır. - Özel etiketler: Tamamen yeni dil yapıları oluşturmak için
(
{mytag}...{/mytag}veyan:mytag). Etiketler en fazla gücü sunar; özel yapılar tanımlamanıza, şablon ayrıştırmasını denetlemenize ve karmaşık render mantığı uygulamanıza olanak tanır. - Compiler pass'leri: Şablonun soyut sözdizim ağacını (AST) ayrıştırmadan sonra ama PHP kodu üretilmeden önce değiştiren fonksiyonlar. Gelişmiş iyileştirmeler, güvenlik denetimleri (Sandbox gibi) veya otomatik kod değişiklikleri için kullanılır.
- Özel loader'lar: Latte'nin şablon dosyalarını nasıl bulup yüklediğini değiştirmek için (örneğin bir veritabanından, şifreli bir depodan yükleme vb.).
Doğru genişletme yöntemini seçmek önemlidir. Karmaşık bir etiket oluşturmadan önce, daha basit bir filtrenin veya fonksiyonun yeterli olup olmayacağını düşünün. Bir örnekle gösterelim: argüman olarak üretilecek sözcük sayısını alan bir Lorem ipsum üreteci uygulamak.
- Etiket olarak?
{lipsum 40}– Mümkün, ama etiketler denetim yapıları veya karmaşık işaretleme üretimi için daha uygundur. Etiketler doğrudan ifadelerin içinde kullanılamaz. - Filtre olarak?
{=40|lipsum}– Teknik olarak çalışır, ama filtreler girdiyi dönüştürmek içindir. Burada40bir argüman, dönüştürülen değer değil. Anlamsal olarak yanlış geliyor. - Fonksiyon olarak?
{lipsum(40)}– En doğal seçenek budur! Fonksiyonlar argüman kabul edip değer döndürür, bu da onları herhangi bir ifadenin içinde kullanmak için mükemmel kılar:{var $text = lipsum(40)}.
Genel yönlendirme: Hesaplama/üretim için fonksiyonları, dönüştürme için filtreleri, yeni dil yapıları veya karmaşık işaretleme için etiketleri kullanın. AST işleme için pass'leri, şablon almak için loader'ları kullanın.
Doğrudan kayıt
Projeye özgü yardımcılar veya hızlı eklemeler için Latte, filtrelerin ve fonksiyonların doğrudan
Latte\Engine nesnesine kaydedilmesine izin verir.
Bir filtre kaydetmek için addFilter() kullanın. Filtre fonksiyonunuzun ilk argümanı | borusundan
önceki değer, sonraki argümanlar ise : iki nokta üst üstenin ardından verilenlerdir.
$latte = new Latte\Engine;
// Filtre tanımı (callable: fonksiyon, statik metot vb.)
$myTruncate = fn(string $s, int $length = 50) => mb_substr($s, 0, $length);
// Kaydet
$latte->addFilter('truncate', $myTruncate);
// Şablonda kullanımı: {$text|truncate} veya {$text|truncate:100}
Şablon ifadelerinin içinde kullanılabilecek bir fonksiyon kaydetmek için addFunction() kullanın.
$latte = new Latte\Engine;
// Fonksiyon tanımı
$isWeekend = fn(DateTimeInterface $date) => $date->format('N') >= 6;
// Kaydet
$latte->addFunction('isWeekend', $isWeekend);
// Şablonda kullanımı: {if isWeekend($myDate)}Hafta sonu!{/if}
Daha fazla ayrıntı için bkz. Özel filtreler oluşturma ve Fonksiyonlar.
Sağlam yol: Latte uzantısı
Doğrudan kayıt basit olsa da, Latte özelleştirmelerini paketlemenin ve dağıtmanın standart ve önerilen yolu uzantı sınıflarıdır. Bir uzantı, birden fazla etiketi, filtreyi, fonksiyonu, compiler pass'ini ve daha fazlasını kaydetmek için merkezî bir yapılandırma noktası gibi davranır.
Neden uzantı kullanılır?
- Düzen: İlişkili özelleştirmeleri (belirli bir özelliğe ait etiketler, filtreler vb.) tek bir sınıfta bir arada tutar.
- Yeniden kullanılabilirlik ve paylaşım: Uzantılarınızı başka projelerde kullanmak veya toplulukla paylaşmak (örneğin Composer aracılığıyla) için kolayca paketlersiniz.
- Tam güç: Özel etiketler ve compiler pass'leri yalnızca uzantılar aracılığıyla kaydedilebilir.
Bir uzantının kaydı
Uzantı, Latte'ye addExtension() ile (veya yapılandırma dosyası üzerinden)
kaydedilir:
$latte = new Latte\Engine;
$latte->addExtension(new MyProjectExtension);
Birden fazla uzantı kaydeder ve bunlar aynı adlı etiketler, filtreler veya fonksiyonlar tanımlarsa, en son eklenen uzantı kazanır. Bu ayrıca uzantılarınızın yerel etiketleri/filtreleri/fonksiyonları ezebileceği anlamına gelir.
Bir sınıfta değişiklik yaptığınızda ve otomatik yenileme kapalı değilse, Latte şablonlarınızı otomatik olarak yeniden derler.
Bir uzantı oluşturma
Kendi uzantınızı oluşturmak için Latte\Extension sınıfından kalıtım alan bir sınıf oluşturmanız gerekir. Uzantının neye benzediği hakkında fikir edinmek için yerleşik CoreExtension'a göz atın.
Hangi metotları uygulayabileceğinize bakalım:
beforeCompile (Latte\Engine $engine): void
Şablon derlenmeden önce çağrılır. Metot, örneğin derlemeyle ilgili hazırlıklar için kullanılabilir.
getTags(): array
Şablon derlenirken çağrılır. Etiket ayrıştırma fonksiyonları olan etiket adı ⇒ callable biçiminde ilişkisel bir dizi döndürür. Daha fazlası.
public function getTags(): array
{
return [
'foo' => FooNode::create(...),
'bar' => BarNode::create(...),
'n:baz' => NBazNode::create(...),
// ...
];
}
n:baz etiketi saf bir n:nitelik temsil eder,
yani yalnızca nitelik olarak yazılabilen bir etikettir.
foo ve bar etiketlerinde Latte, bunların çift etiket olup olmadığını otomatik tanır; öyleyse
n:inner-foo ve n:tag-foo ön ekli varyantlar dahil, n:nitelikleri kullanılarak otomatik
yazılabilirler.
Böyle n:niteliklerin yürütülme sırası, getTags()'in döndürdüğü dizideki sıralarına göre belirlenir.
Yani n:foo her zaman n:bar'dan önce yürütülür; nitelikler HTML etiketinde
<div n:bar="..." n:foo="..."> şeklinde ters sırada yazılmış olsa bile.
n:niteliklerin sırasını birden fazla uzantı arasında belirlemeniz gerekiyorsa, before ve/veya
after parametresinin hangi etiketlerin etiketten önce veya sonra sıralanacağını belirlediği
order() yardımcı metodunu kullanın.
public function getTags(): array
{
return [
'foo' => self::order(FooNode::create(...), before: 'bar'),
'bar' => self::order(BarNode::create(...), after: ['block', 'snippet']),
];
}
getPasses(): array
Şablon derlenirken çağrılır. AST'yi dolaşan ve değiştiren, compiler pass'leri denilen şeyleri temsil eden fonksiyonların bulunduğu pass adı ⇒ callable biçiminde ilişkisel bir dizi döndürür.
Burada da order() yardımcı metodu kullanılabilir. before veya after parametrelerinin
değeri, hepsinden önce/sonra anlamına gelen * olabilir.
public function getPasses(): array
{
return [
'optimize' => Passes::optimizePass(...),
'sandbox' => self::order($this->sandboxPass(...), before: '*'),
// ...
];
}
beforeRender (Latte\Runtime\Template $template): void
Her şablon render'ından önce çağrılır. Metot, örneğin render sırasında kullanılan değişkenleri ilklendirmek için kullanılabilir.
afterRender (Latte\Runtime\Template $template): void
Her şablon render'ından sonra çağrılır. Render {exitIf} ile erken bittiğinde veya bir istisnayla
kesildiğinde de çalışır, bu da onu temizlik ya da ölçüm için doğru yer yapar.
getFilters(): array
Uzantı addExtension() metoduyla kaydedildiğinde çağrılır. Filtreleri filtre adı ⇒ callable
biçiminde ilişkisel bir dizi olarak döndürür. Daha fazlası.
public function getFilters(): array
{
return [
'batch' => $this->batchFilter(...),
'trim' => $this->trimFilter(...),
// ...
];
}
getFunctions(): array
Uzantı addExtension() metoduyla kaydedildiğinde çağrılır. Fonksiyonları fonksiyon adı ⇒
callable biçiminde ilişkisel bir dizi olarak döndürür. Daha
fazlası.
public function getFunctions(): array
{
return [
'clamp' => $this->clampFunction(...),
'divisibleBy' => $this->divisibleByFunction(...),
// ...
];
}
getProviders(): array
Uzantı addExtension() metoduyla kaydedildiğinde çağrılır. Genellikle etiketlerin çalışma zamanında
kullandığı nesneler olan sağlayıcıların dizisini döndürür. Onlara $this->global->... üzerinden
erişilir. Daha fazlası.
public function getProviders(): array
{
return [
'myFoo' => $this->foo,
'myBar' => $this->bar,
// ...
];
}
getCacheKey (Latte\Engine $engine): mixed
Şablon render edilmeden önce çağrılır. Dönüş değeri, hash'i derlenmiş şablon dosyasının adında bulunan anahtarın parçası olur. Böylece farklı dönüş değerleri için Latte farklı önbellek dosyaları üretir.