Yönlendirme (Routing)
Yönlendirici (Router), URL adresleriyle ilgili her şeyden sorumludur, böylece artık onlar hakkında düşünmek zorunda kalmazsınız. Şunları göstereceğiz:
- URL'lerin istediğiniz gibi olması için yönlendirici nasıl ayarlanır
- SEO ve yönlendirme hakkında konuşacağız
- ve kendi yönlendiricinizi nasıl yazacağınızı göstereceğiz
Daha insancıl URL'ler (veya havalı ya da güzel URL'ler) daha kullanışlı, daha akılda kalıcıdır ve SEO'ya olumlu katkıda bulunurlar. Nette bunu düşünür ve geliştiricilere tam destek verir. Uygulamanız için tam olarak istediğiniz URL adresi yapısını tasarlayabilirsiniz. Hatta uygulama bittiğinde bile tasarlayabilirsiniz, çünkü kodda veya şablonlarda herhangi bir müdahale gerektirmez. Zarif bir şekilde tek bir yerde, yönlendiricide tanımlanır ve böylece tüm presenter'lara anotasyonlar şeklinde dağılmaz.
Nette'deki yönlendirici, çift yönlü olmasıyla olağanüstüdür. Hem HTTP isteğindeki URL'yi çözebilir hem de bağlantılar oluşturabilir. Bu nedenle Nette Application'da hayati bir rol oynar, çünkü hem mevcut isteği hangi presenter ve eylemin yürüteceğine karar verir hem de şablonda vb. URL oluşturmak için kullanılır.
Ancak yönlendirici yalnızca bu kullanımla sınırlı değildir, presenter'ların hiç kullanılmadığı uygulamalarda, REST API'ler için vb. kullanabilirsiniz. Daha fazla bilgi samostatné použití bölümünde.
Rota Koleksiyonu
Uygulamadaki URL adreslerinin şeklini tanımlamanın en hoş yolu Nette\Application\Routers\RouteList sınıfını sunar. Tanım, sözde rotaların, yani URL adresi maskelerinin ve bunlarla ilişkili presenter'ların ve eylemlerin basit bir API kullanılarak bir listesinden oluşur. Rotaları herhangi bir şekilde adlandırmamız gerekmez.
$router = new Nette\Application\Routers\RouteList;
$router->addRoute('rss.xml', 'Feed:rss');
$router->addRoute('article/<id>', 'Article:view');
// ...
Örnek, tarayıcıda https://domain.com/rss.xml
açarsak, Feed
presenter'ının rss
eylemiyle görüntüleneceğini, https://domain.com/article/12
açarsak, Article
presenter'ının
view
eylemiyle görüntüleneceğini vb. söyler. Uygun bir rota bulunamazsa, Nette Application BadRequestException istisnası
atarak yanıt verir, bu da kullanıcıya 404 Not Found hata sayfası olarak gösterilir.
Rotaların Sırası
Bireysel rotaların listelendiği sıra kesinlikle anahtar öneme sahiptir, çünkü yukarıdan aşağıya doğru sırayla değerlendirilirler. Rotaları özgülden genele doğru bildirme kuralı geçerlidir:
// YANLIŞ: 'rss.xml' ilk rota tarafından yakalanır ve bu dizeyi <slug> olarak anlar
$router->addRoute('<slug>', 'Article:view');
$router->addRoute('rss.xml', 'Feed:rss');
// DOĞRU
$router->addRoute('rss.xml', 'Feed:rss');
$router->addRoute('<slug>', 'Article:view');
Rotalar, bağlantılar oluşturulurken de yukarıdan aşağıya doğru değerlendirilir:
// YANLIŞ: 'Feed:rss' bağlantısı 'admin/feed/rss' olarak oluşturulur
$router->addRoute('admin/<presenter>/<action>', 'Admin:default');
$router->addRoute('rss.xml', 'Feed:rss');
// DOĞRU
$router->addRoute('rss.xml', 'Feed:rss');
$router->addRoute('admin/<presenter>/<action>', 'Admin:default');
Doğru rota derlemesinin belirli bir beceri gerektirdiğini sizden saklamayacağız. Buna hakim olana kadar, yönlendirme paneli sizin için yararlı bir yardımcı olacaktır.
Maske ve Parametreler
Maske, web sitesinin kök dizininden göreceli yolu tanımlar. En basit maske statik bir URL'dir:
$router->addRoute('products', 'Products:default');
Genellikle maskeler sözde parametreler içerir. Bunlar sivri parantez içinde belirtilir (örn.
<year>
) ve hedef presenter'a, örneğin renderShow(int $year)
metoduna veya kalıcı parametre
$year
'a iletilir:
$router->addRoute('chronicle/<year>', 'History:show');
Örnek, tarayıcıda https://example.com/chronicle/2020
açarsak, History
presenter'ının
show
eylemiyle ve year: 2020
parametresiyle görüntüleneceğini söyler.
Parametrelere doğrudan maskede varsayılan bir değer atayabiliriz ve böylece isteğe bağlı hale gelirler:
$router->addRoute('chronicle/<year=2020>', 'History:show');
Rota şimdi https://example.com/chronicle/
URL'sini de kabul edecektir, bu da yine History:show
'u
year: 2020
parametresiyle görüntüler.
Parametre elbette presenter ve eylem adı da olabilir. Örneğin şöyle:
$router->addRoute('<presenter>/<action>', 'Home:default');
Belirtilen rota, örn. /article/edit
veya /catalog/list
şeklindeki URL'leri kabul eder ve bunları
Article:edit
ve Catalog:list
presenter'ları ve eylemleri olarak anlar.
Aynı zamanda presenter
ve action
parametrelerine Home
ve default
varsayılan değerlerini verir ve dolayısıyla bunlar da isteğe bağlıdır. Yani rota, /article
şeklindeki URL'yi
de kabul eder ve onu Article:default
olarak anlar. Veya tersi, Product:default
bağlantısı
/product
yolunu, varsayılan Home:default
bağlantısı /
yolunu oluşturur.
Maske yalnızca web sitesinin kök dizininden göreceli yolu değil, aynı zamanda eğik çizgiyle başlıyorsa mutlak yolu veya hatta iki eğik çizgiyle başlıyorsa tüm mutlak URL'yi tanımlayabilir:
// document root'a göreceli
$router->addRoute('<presenter>/<action>', /* ... */);
// mutlak yol (alan adına göreceli)
$router->addRoute('/<presenter>/<action>', /* ... */);
// alan adı dahil mutlak URL (şemaya göreceli)
$router->addRoute('//<lang>.example.com/<presenter>/<action>', /* ... */);
// şema dahil mutlak URL
$router->addRoute('https://<lang>.example.com/<presenter>/<action>', /* ... */);
Doğrulama İfadeleri
Her parametre için düzenli ifade kullanarak bir
doğrulama koşulu belirlenebilir. Örneğin, id
parametresinin yalnızca rakamlardan oluşabileceğini
\d+
düzenli ifadesiyle belirleriz:
$router->addRoute('<presenter>/<action>[/<id \d+>]', /* ... */);
Tüm parametreler için varsayılan düzenli ifade [^/]+
'dır, yani eğik çizgi dışındaki her şey.
Parametrenin eğik çizgileri de kabul etmesi gerekiyorsa, .+
ifadesini belirtiriz:
// https://example.com/a/b/c kabul eder, path 'a/b/c' olur
$router->addRoute('<path .+>', /* ... */);
İsteğe Bağlı Diziler
Maskede isteğe bağlı bölümleri köşeli parantez kullanarak işaretleyebilirsiniz. Maskenin herhangi bir bölümü isteğe bağlı olabilir, içinde parametreler de bulunabilir:
$router->addRoute('[<lang [a-z]{2}>/]<name>', /* ... */);
// Yolları kabul eder:
// /tr/download => lang => tr, name => download
// /download => lang => null, name => download
Parametre isteğe bağlı bir dizinin parçası olduğunda, doğal olarak isteğe bağlı hale gelir. Varsayılan bir değeri belirtilmemişse, null olur.
İsteğe bağlı bölümler alan adında da olabilir:
$router->addRoute('//[<lang=en>.]example.com/<presenter>/<action>', /* ... */);
Diziler istenildiği gibi iç içe geçirilebilir ve birleştirilebilir:
$router->addRoute(
'[<lang [a-z]{2}>[-<sublang>]/]<name>[/page-<page=0>]',
'Home:default',
);
// Yolları kabul eder:
// /tr/hello
// /en-us/hello
// /hello
// /hello/page-12
URL oluşturulurken en kısa varyant hedeflenir, bu nedenle atlanabilecek her şey atlanır. Bu yüzden örneğin
index[.html]
rotası /index
yolunu oluşturur. Sol köşeli parantezden sonra bir ünlem işareti
belirterek davranışı tersine çevirmek mümkündür:
// /hello ve /hello.html kabul eder, /hello oluşturur
$router->addRoute('<name>[.html]', /* ... */);
// /hello ve /hello.html kabul eder, /hello.html oluşturur
$router->addRoute('<name>[!.html]', /* ... */);
Köşeli parantez olmadan isteğe bağlı parametreler (yani varsayılan değere sahip parametreler) aslında aşağıdaki gibi parantez içine alınmış gibi davranırlar:
$router->addRoute('<presenter=Home>/<action=default>/<id=>', /* ... */);
// şuna karşılık gelir:
$router->addRoute('[<presenter=Home>/[<action=default>/[<id>]]]', /* ... */);
Eğer bitiş eğik çizgisinin davranışını etkilemek isteseydik, örneğin /home/
yerine sadece
/home
oluşturulsun, bunu şu şekilde başarabiliriz:
$router->addRoute('[<presenter=Home>[/<action=default>[/<id>]]]', /* ... */);
Joker Karakterler
Mutlak yol maskesinde aşağıdaki joker karakterleri kullanabilir ve böylece örneğin geliştirme ve üretim ortamlarında farklı olabilen alan adını maskeye yazma zorunluluğundan kaçınabiliriz:
%tld%
= üst düzey alan adı, örn.com
veyaorg
%sld%
= ikinci düzey alan adı, örn.example
%domain%
= alt alan adları olmadan alan adı, örn.example.com
%host%
= tüm ana bilgisayar adı, örn.www.example.com
%basePath%
= kök dizine giden yol
$router->addRoute('//www.%domain%/%basePath%/<presenter>/<action>', /* ... */);
$router->addRoute('//www.%sld%.%tld%/%basePath%/<presenter>/<action', /* ... */);
Genişletilmiş Gösterim
Genellikle Presenter:eylem
şeklinde yazılan rota hedefi, bireysel parametreleri ve varsayılan değerlerini
tanımlayan bir dizi kullanılarak da yazılabilir:
$router->addRoute('<presenter>/<action>[/<id \d+>]', [
'presenter' => 'Home',
'action' => 'default',
]);
Daha ayrıntılı belirtim için, varsayılan değerlere ek olarak parametrelerin diğer özelliklerini, örneğin doğrulama
düzenli ifadesini (bkz. id
parametresi) ayarlayabileceğimiz daha da genişletilmiş bir form kullanılabilir:
use Nette\Routing\Route;
$router->addRoute('<presenter>/<action>[/<id>]', [
'presenter' => [
Route::Value => 'Home',
],
'action' => [
Route::Value => 'default',
],
'id' => [
Route::Pattern => '\d+',
],
]);
Dizide tanımlanan parametreler yol maskesinde belirtilmemişse, değerlerinin URL'deki soru işaretinden sonra belirtilen sorgu parametreleri kullanılarak bile değiştirilemeyeceğini belirtmek önemlidir.
Filtreler ve Çeviriler
Uygulamanın kaynak kodlarını İngilizce yazıyoruz, ancak web sitesinin Türkçe URL'lere sahip olması gerekiyorsa, o zaman basit yönlendirme türü:
$router->addRoute('<presenter>/<action>', 'Home:default');
/product/123
veya /cart
gibi İngilizce URL'ler üretecektir. URL'deki presenter'ların ve eylemlerin
Türkçe kelimelerle temsil edilmesini istiyorsak (örn. /urun/123
veya /sepet
), bir çeviri sözlüğü
kullanabiliriz. Yazımı için zaten ikinci parametrenin “daha konuşkan” varyantına ihtiyacımız var:
use Nette\Routing\Route;
$router->addRoute('<presenter>/<action>', [
'presenter' => [
Route::Value => 'Home',
Route::FilterTable => [
// URL'deki dize => presenter
'urun' => 'Product',
'sepet' => 'Cart',
'katalog' => 'Catalog',
],
],
'action' => [
Route::Value => 'default',
Route::FilterTable => [
'liste' => 'list',
],
],
]);
Çeviri sözlüğünün birden fazla anahtarı aynı presenter'a yol açabilir. Böylece ona farklı takma adlar oluşturulur. Kanonik varyant (yani oluşturulan URL'de olacak olan) olarak son anahtar kabul edilir.
Çeviri tablosu bu şekilde herhangi bir parametreye uygulanabilir. Çeviri mevcut değilse, orijinal değer alınır. Bu
davranışı Route::FilterStrict => true
ekleyerek değiştirebiliriz ve rota daha sonra değer sözlükte yoksa
URL'yi reddeder.
Dizi şeklindeki çeviri sözlüğüne ek olarak, kendi çeviri fonksiyonlarımızı da dağıtabiliriz.
use Nette\Routing\Route;
$router->addRoute('<presenter>/<action>/<id>', [
'presenter' => [
Route::Value => 'Home',
Route::FilterIn => function (string $s): string { /* ... */ },
Route::FilterOut => function (string $s): string { /* ... */ },
],
'action' => 'default',
'id' => null,
]);
Route::FilterIn
fonksiyonu, URL'deki parametre ile daha sonra presenter'a iletilen dize arasında dönüştürme
yapar, FilterOut
fonksiyonu ters yönde dönüştürmeyi sağlar.
presenter
, action
ve module
parametrelerinin zaten URL'de kullanılan PascalCase veya
camelCase ve kebab-case stilleri arasında dönüştürme yapan önceden tanımlanmış filtreleri vardır. Parametrelerin
varsayılan değeri zaten dönüştürülmüş biçimde yazılır, bu yüzden örneğin presenter durumunda
<presenter=ProductEdit>
yazarız, <presenter=product-edit>
değil.
Genel Filtreler
Belirli parametrelere yönelik filtrelere ek olarak, tüm parametrelerin ilişkisel bir dizisini alan, bunları herhangi bir
şekilde değiştirebilen ve sonra döndüren genel filtreler de tanımlayabiliriz. Genel filtreleri null
anahtarı
altında tanımlarız.
use Nette\Routing\Route;
$router->addRoute('<presenter>/<action>', [
'presenter' => 'Home',
'action' => 'default',
null => [
Route::FilterIn => function (array $params): array { /* ... */ },
Route::FilterOut => function (array $params): array { /* ... */ },
],
]);
Genel filtreler, rotanın davranışını kesinlikle herhangi bir şekilde değiştirme yeteneği verir. Bunları örneğin
parametreleri diğer parametrelere göre değiştirmek için kullanabiliriz. Örneğin, <presenter>
ve
<action>
'ın mevcut <lang>
parametresinin değerine göre çevrilmesi.
Bir parametrenin kendi filtresi tanımlanmışsa ve aynı zamanda genel bir filtre varsa, kendi FilterIn
filtresi
genel filtreden önce ve tersine genel FilterOut
filtresi kendi filtresinden önce yürütülür. Yani genel filtre
içinde, presenter
veya action
parametrelerinin değerleri PascalCase veya camelCase stilinde
yazılır.
Tek Yönlüler (OneWay)
Tek yönlü rotalar, uygulamanın artık oluşturmadığı ancak hala kabul ettiği eski URL'lerin işlevselliğini korumak
için kullanılır. Bunları OneWay
bayrağıyla işaretleriz:
// eski URL /product-info?id=123
$router->addRoute('product-info', 'Product:detail', $router::ONE_WAY);
// yeni URL /product/123
$router->addRoute('product/<id>', 'Product:detail');
Eski URL'ye erişildiğinde, presenter otomatik olarak yeni URL'ye yönlendirir, böylece arama motorları bu sayfaları iki kez indekslemez (SEO ve kanonikleştirme bölümüne bakın).
Geri Çağrılarla Dinamik Yönlendirme
Geri çağırmalarla dinamik yönlendirme, rotalara doğrudan, ilgili yol ziyaret edildiğinde yürütülecek fonksiyonlar (geri çağırmalar) atamanıza olanak tanır. Bu esnek işlevsellik, uygulamanız için çeşitli uç noktaları (endpoints) hızlı ve verimli bir şekilde oluşturmanıza olanak tanır:
$router->addRoute('test', function () {
echo '/test adresindesiniz';
});
Ayrıca maskede, geri çağırmanıza otomatik olarak iletilecek parametreler tanımlayabilirsiniz:
$router->addRoute('<lang tr|en>', function (string $lang) {
echo match ($lang) {
'tr' => 'Web sitemizin Türkçe versiyonuna hoş geldiniz!',
'en' => 'Welcome to the English version of our website!',
};
});
Modüller
Ortak bir modüle ait birden
fazla rotamız varsa, withModule()
kullanırız:
$router = new RouteList;
$router->withModule('Forum') // aşağıdaki rotalar Forum modülünün bir parçasıdır
->addRoute('rss', 'Feed:rss') // presenter Forum:Feed olacak
->addRoute('<presenter>/<action>')
->withModule('Admin') // aşağıdaki rotalar Forum:Admin modülünün bir parçasıdır
->addRoute('sign:in', 'Sign:in');
Alternatif olarak module
parametresini kullanmaktır:
// URL manage/dashboard/default, Admin:Dashboard presenter'ına eşlenir
$router->addRoute('manage/<presenter>/<action>', [
'module' => 'Admin',
]);
Alt Alan Adları
Rota koleksiyonlarını alt alan adlarına göre bölebiliriz:
$router = new RouteList;
$router->withDomain('example.com')
->addRoute('rss', 'Feed:rss')
->addRoute('<presenter>/<action>');
Alan adında joker karakterler de kullanılabilir:
$router = new RouteList;
$router->withDomain('example.%tld%')
// ...
Yol Öneki
Rota koleksiyonlarını URL'deki yola göre bölebiliriz:
$router = new RouteList;
$router->withPath('eshop')
->addRoute('rss', 'Feed:rss') // /eshop/rss URL'sini yakalar
->addRoute('<presenter>/<action>'); // /eshop/<presenter>/<action> URL'sini yakalar
Kombinasyonlar
Yukarıdaki bölümlemeyi birbirleriyle birleştirebiliriz:
$router = (new RouteList)
->withDomain('admin.example.com')
->withModule('Admin')
->addRoute(/* ... */)
->addRoute(/* ... */)
->end()
->withModule('Images')
->addRoute(/* ... */)
->end()
->end()
->withDomain('example.com')
->withPath('export')
->addRoute(/* ... */)
// ...
Sorgu Parametreleri
Maskeler ayrıca sorgu parametrelerini (URL'deki soru işaretinden sonraki parametreler) de içerebilir. Bunlar için bir doğrulama ifadesi tanımlanamaz, ancak presenter'a iletilecekleri adı değiştirebilirsiniz:
// 'cat' sorgu parametresini uygulamada 'categoryId' adıyla kullanmak istiyoruz
$router->addRoute('product ? id=<productId> & cat=<categoryId>', /* ... */);
Foo Parametreleri
Şimdi daha derine iniyoruz. Foo parametreleri aslında düzenli bir ifadeyle eşleşmeyi sağlayan isimsiz parametrelerdir.
Örnek olarak /index
, /index.html
, /index.htm
ve /index.php
kabul eden bir
rota verilebilir:
$router->addRoute('index<? \.html?|\.php|>', /* ... */);
URL oluşturulurken kullanılacak dizeyi açıkça tanımlamak da mümkündür. Dize doğrudan soru işaretinden sonra
yerleştirilmelidir. Aşağıdaki rota öncekine benzer, ancak /index
yerine /index.html
oluşturur,
çünkü .html
dizesi oluşturma değeri olarak ayarlanmıştır:
$router->addRoute('index<?.html \.html?|\.php|>', /* ... */);
Uygulamaya Dahil Etme
Oluşturulan yönlendiriciyi uygulamaya dahil etmek için DI konteynerine ondan bahsetmeliyiz. En kolay yol, yönlendirici
nesnesini üretecek bir fabrika hazırlamak ve konteyner yapılandırmasında onu kullanmasını söylemektir. Bu amaçla
App\Core\RouterFactory::createRouter()
metodunu yazdığımızı varsayalım:
namespace App\Core;
use Nette\Application\Routers\RouteList;
class RouterFactory
{
public static function createRouter(): RouteList
{
$router = new RouteList;
$router->addRoute(/* ... */);
return $router;
}
}
Yapılandırmaya şunu yazarız:
services:
- App\Core\RouterFactory::createRouter
Veritabanı vb. gibi herhangi bir bağımlılık, fabrika metoduna parametreleri olarak autowiring kullanılarak iletilir:
public static function createRouter(Nette\Database\Connection $db): RouteList
{
// ...
}
SimpleRouter
Rota koleksiyonundan çok daha basit bir yönlendirici SimpleRouter'dır. URL şekli
konusunda özel gereksinimlerimiz olmadığında, mod_rewrite
(veya alternatifleri) mevcut olmadığında veya henüz
güzel URL'lerle uğraşmak istemediğimizde kullanırız.
Kabaca şu şekilde adresler üretir:
http://example.com/?presenter=Product&action=detail&id=123
SimpleRouter'ın kurucu parametresi, parametresiz bir sayfa açtığımızda, örn. http://example.com/
,
yönlendirilmesi gereken varsayılan presenter ve eylemdir.
// varsayılan presenter 'Home' ve eylem 'default' olacak
$router = new Nette\Application\Routers\SimpleRouter('Home:default');
SimpleRouter'ı doğrudan yapılandırmada tanımlamanızı öneririz:
services:
- Nette\Application\Routers\SimpleRouter('Home:default')
SEO ve Kanonikleştirme
Framework, farklı URL'lerde yinelenen içeriği önleyerek SEO'ya (arama motoru optimizasyonu) katkıda bulunur. Belirli bir
hedefe birden fazla adres yönlendiriyorsa, örn. /index
ve /index.html
, framework bunlardan ilkini
birincil (kanonik) olarak belirler ve diğerlerini HTTP kodu 301 ile ona yönlendirir. Bu sayede arama motorları
sayfalarınızı iki kez indekslemez ve sayfa sıralamalarını seyreltmez.
Bu sürece kanonikleştirme denir. Kanonik URL, yönlendirici tarafından oluşturulan URL'dir, yani koleksiyondaki OneWay bayrağı olmayan ilk uygun rotadır. Bu nedenle koleksiyonda birincil rotaları ilk olarak belirtiriz.
Kanonikleştirme presenter tarafından yapılır, daha fazla bilgi kanonikleştirme bölümünde.
HTTPS
HTTPS protokolünü kullanabilmek için barındırmada etkinleştirmek ve sunucuyu doğru şekilde yapılandırmak gerekir.
Tüm web sitesinin HTTPS'ye yönlendirilmesi sunucu düzeyinde ayarlanmalıdır, örneğin uygulamamızın kök dizinindeki .htaccess dosyası kullanılarak ve HTTP kodu 301 ile. Ayar barındırmaya göre değişebilir ve kabaca şöyle görünür:
<IfModule mod_rewrite.c>
RewriteEngine On
...
RewriteCond %{HTTPS} off
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
...
</IfModule>
Yönlendirici, sayfanın yüklendiği protokolle aynı protokole sahip URL'ler üretir, bu yüzden başka bir şey ayarlamaya gerek yoktur.
Ancak istisnai olarak farklı rotaların farklı protokoller altında çalışması gerekiyorsa, bunu rota maskesinde belirtiriz:
// HTTP ile bir adres üretecek
$router->addRoute('http://%host%/<presenter>/<action>', /* ... */);
// HTTPS ile bir adres üretecek
$router->addRoute('https://%host%/<presenter>/<action>', /* ... */);
Yönlendirici Hata Ayıklaması
Tracy Bar'da görüntülenen yönlendirme paneli, rotaların listesini ve yönlendiricinin URL'den aldığı parametreleri gösteren yararlı bir yardımcıdır.
Yeşil çubuk ve ✓ sembolü, mevcut URL'yi işleyen rotayı temsil eder; mavi renk ve ≈ sembolü, yeşil olan onları geçmeseydi URL'yi de işleyecek olan rotaları gösterir. Ayrıca mevcut presenter ve eylemi de görürüz.

Aynı zamanda, kanonikleştirme nedeniyle beklenmedik bir yönlendirme olursa, yönlendiricinin URL'yi başlangıçta nasıl anladığını ve neden yönlendirdiğini öğrenmek için redirect çubuğundaki panele bakmak yararlıdır.
Yönlendiriciyi hata ayıklarken, tarayıcıda Geliştirici Araçları'nı (Ctrl+Shift+I veya Cmd+Option+I) açmanızı ve Ağ panelinde önbelleği devre dışı bırakmanızı öneririz, böylece yönlendirmeler orada saklanmaz.
Performans
Rotaların sayısı yönlendiricinin hızını etkiler. Sayıları kesinlikle birkaç düzineyi geçmemelidir. Web sitenizin çok karmaşık bir URL yapısı varsa, özel bir vlastní router yazabilirsiniz.
Yönlendiricinin örneğin veritabanı gibi herhangi bir bağımlılığı yoksa ve fabrikası herhangi bir argüman kabul etmiyorsa, derlenmiş formunu doğrudan DI konteynerine serileştirebilir ve böylece uygulamayı biraz hızlandırabiliriz.
routing:
cache: true
Özel Yönlendirici
Aşağıdaki satırlar çok ileri düzey kullanıcılar içindir. Kendi yönlendiricinizi oluşturabilir ve onu tamamen doğal bir şekilde rota koleksiyonuna dahil edebilirsiniz. Yönlendirici, iki metoda sahip Nette\Routing\Router arayüzünün bir uygulamasıdır:
use Nette\Http\IRequest as HttpRequest;
use Nette\Http\UrlScript;
class MyRouter implements Nette\Routing\Router
{
public function match(HttpRequest $httpRequest): ?array
{
// ...
}
public function constructUrl(array $params, UrlScript $refUrl): ?string
{
// ...
}
}
match
metodu, yalnızca URL'yi değil, aynı zamanda başlıkları vb. de alabileceğiniz mevcut isteği $httpRequest işler ve presenter adını ve parametrelerini içeren bir diziye
dönüştürür. İsteği işleyemezse, null döndürür. İsteği işlerken en azından presenter ve eylemi döndürmeliyiz.
Presenter adı tamdır ve olası modülleri de içerir:
[
'presenter' => 'Front:Home',
'action' => 'default',
]
constructUrl
metodu ise tam tersine, parametreler dizisinden sonuçta ortaya çıkan mutlak URL'yi oluşturur.
Bunun için mevcut URL olan $refUrl
parametresindeki bilgileri kullanabilir.
add()
kullanarak rota koleksiyonuna eklersiniz:
$router = new Nette\Application\Routers\RouteList;
$router->add($myRouter);
$router->addRoute(/* ... */);
// ...
Bağımsız Kullanım
Bağımsız kullanım derken, Nette Application ve presenter'ları kullanmayan bir uygulamada yönlendiricinin yeteneklerini kullanmayı kastediyoruz. Bu bölümde gösterdiğimiz hemen hemen her şey onun için geçerlidir, şu farklılıklarla:
- rota koleksiyonları için Nette\Routing\RouteList sınıfını kullanırız
- basit yönlendirici olarak Nette\Routing\SimpleRouter sınıfını kullanırız
Presenter:eylem
çifti olmadığı için, genişletilmiş gösterimi kullanırız
Yani yine bize yönlendiriciyi oluşturacak bir metot oluştururuz, örn.:
namespace App\Core;
use Nette\Routing\RouteList;
class RouterFactory
{
public static function createRouter(): RouteList
{
$router = new RouteList;
$router->addRoute('rss.xml', [
'controller' => 'RssFeedController',
]);
$router->addRoute('article/<id \d+>', [
'controller' => 'ArticleController',
]);
// ...
return $router;
}
}
DI konteyneri kullanıyorsanız, ki bunu öneririz, metodu tekrar yapılandırmaya ekleriz ve ardından yönlendiriciyi HTTP isteğiyle birlikte konteynerden alırız:
$router = $container->getByType(Nette\Routing\Router::class);
$httpRequest = $container->getByType(Nette\Http\IRequest::class);
Veya nesneleri doğrudan üretiriz:
$router = App\Core\RouterFactory::createRouter();
$httpRequest = (new Nette\Http\RequestFactory)->fromGlobals();
Şimdi geriye sadece yönlendiriciyi işe koymak kalıyor:
$params = $router->match($httpRequest);
if ($params === null) {
// uygun bir rota bulunamadı, 404 hatası göndeririz
exit;
}
// alınan parametreleri işleriz
$controller = $params['controller'];
// ...
Ve tersine, bir bağlantı oluşturmak için yönlendiriciyi kullanırız:
$params = ['controller' => 'ArticleController', 'id' => 123];
$url = $router->constructUrl($params, $httpRequest->getUrl());