Nette Documentation Preview

syntax
Yönlendirme
***********

<div class=perex>

Yönlendirici, URL'lerle ilgili her şeyden sorumludur, böylece artık bunları düşünmek zorunda kalmazsınız. Biz göstereceğiz:

- URL'lerin istediğiniz gibi görünmesi için yönlendiricinin nasıl ayarlanacağı
- SEO yönlendirmesi hakkında birkaç not
- ve size kendi yönlendiricinizi nasıl yazacağınızı göstereceğiz

</div>


Daha insani URL'ler (veya havalı veya güzel URL'ler) daha kullanılabilir, daha akılda kalıcıdır ve SEO'ya olumlu katkıda bulunur. Nette bunu göz önünde bulundurur ve geliştiricilerin isteklerini tam olarak karşılar. Uygulamanız için URL yapınızı tam olarak istediğiniz şekilde tasarlayabilirsiniz.
Hatta herhangi bir kod veya şablon değişikliği olmadan yapılabildiği için uygulama hazır olduktan sonra bile tasarlayabilirsiniz. Tek bir [yerde |#Integration], yönlendiricide zarif bir şekilde tanımlanır ve tüm sunumcularda ek açıklamalar şeklinde dağınık değildir.

Nette'deki yönlendirici özeldir çünkü **çift yönlüdür**, hem HTTP istek URL'lerinin kodunu çözebilir hem de bağlantılar oluşturabilir. Bu nedenle Nette [Uygulamasında |how-it-works#Nette Application] hayati bir rol oynar, çünkü mevcut isteği hangi sunumcu ve eylemin yürüteceğine karar verir ve ayrıca şablonda [URL |creating-links] oluşturma vb. için kullanılır.

Ancak, yönlendirici bu kullanımla sınırlı değildir, sunum yapanların hiç kullanılmadığı uygulamalarda, REST API'leri vb. için kullanabilirsiniz. [Ayrılmış kullanım |#separated usage] bölümünde daha fazlası.


Rota Koleksiyonu .[#toc-route-collection]
=========================================

Uygulamadaki URL adreslerini tanımlamanın en hoş yolu [api:Nette\Application\Routers\RouteList] sınıfıdır. Tanım, basit bir API kullanarak sözde rotaların bir listesinden, yani URL adreslerinin maskelerinden ve bunlarla ilişkili sunucu ve eylemlerden oluşur. Rotalara isim vermek zorunda değiliz.

```php
$router = new Nette\Application\Routers\RouteList;
$router->addRoute('rss.xml', 'Feed:rss');
$router->addRoute('article/<id>', 'Article:view');
// ...
```

Örnek, tarayıcıda `https://any-domain.com/rss.xml` eylemi ile `Feed` sunucusunun görüntüleneceğini, `https://domain.com/article/12` eylemi ile `Article` 'un görüntüleneceğini vb. söylüyor. Uygun bir rota bulunamazsa, Nette Application, kullanıcıya 404 Not Found hata sayfası olarak görünen bir [BadRequestException |api:Nette\Application\BadRequestException] istisnası atarak yanıt verir.


Rotaların Sırası .[#toc-order-of-routes]
----------------------------------------

Rotaların listelenme sırası **çok önemlidir** çünkü yukarıdan aşağıya doğru sırayla değerlendirilirler. Kural, rotaları **özelden genele** doğru beyan etmemizdir:

```php
// YANLIŞ: 'rss.xml' ilk rota ile eşleşir ve bunu <slug> olarak yanlış anlar
$router->addRoute('<slug>', 'Article:view');
$router->addRoute('rss.xml', 'Feed:rss');

// İYİ
$router->addRoute('rss.xml', 'Feed:rss');
$router->addRoute('<slug>', 'Article:view');
```

Bağlantılar oluşturulurken rotalar da yukarıdan aşağıya doğru değerlendirilir:

```php
// YANLIŞ: 'Feed:rss' için 'admin/feed/rss' şeklinde bir bağlantı oluşturur
$router->addRoute('admin/<presenter>/<action>', 'Admin:default');
$router->addRoute('rss.xml', 'Feed:rss');

// İYİ
$router->addRoute('rss.xml', 'Feed:rss');
$router->addRoute('admin/<presenter>/<action>', 'Admin:default');
```

Doğru bir liste oluşturmanın biraz beceri gerektirdiğini sizden saklamayacağız. İşin içine girene kadar, [yönlendirme paneli |#Debugging Router] faydalı bir araç olacaktır.


Maske ve Parametreler .[#toc-mask-and-parameters]
-------------------------------------------------

Maske, site kökünü temel alan göreli yolu tanımlar. En basit maske statik bir URL'dir:

```php
$router->addRoute('products', 'Products:default');
```

Genellikle maskeler **parametreler** olarak adlandırılan parametreler içerir. Bunlar açılı parantezler içine alınır (örn. `<year>`) ve hedef sunucuya, örneğin `renderShow(int $year)` yöntemine veya `$year` kalıcı parametresine aktarılır:

```php
$router->addRoute('chronicle/<year>', 'History:show');
```

Örnek, tarayıcıda `https://any-domain.com/chronicle/2020` sunumcusunun ve `year: 2020` parametreli `show` eyleminin görüntüleneceğini söylüyor.

Parametreler için doğrudan maske içinde varsayılan bir değer belirleyebiliriz ve böylece isteğe bağlı hale gelir:

```php
$router->addRoute('chronicle/<year=2020>', 'History:show');
```

Rota şimdi `https://any-domain.com/chronicle/` parametresiyle birlikte `History:show` adresini tekrar görüntüleyecektir.

Elbette, sunum yapan kişinin adı ve eylem de bir parametre olabilir. Örneğin:

```php
$router->addRoute('<presenter>/<action>', 'Home:default');
```

Bu rota, örneğin `/article/edit` veya `/catalog/list` şeklinde bir URL'yi kabul eder ve bunları `Article:edit` veya `Catalog:list` sunucularına ve eylemlerine çevirir.

Ayrıca `presenter` ve `action` parametrelerine`Home` ve `default` varsayılan değerlerini verir ve bu nedenle bunlar isteğe bağlıdır. Böylece rota `/article` URL'sini de kabul eder ve bunu `Article:default` olarak çevirir. Ya da tam tersi, `Product:default` adresine bir bağlantı `/product` yolunu oluşturur, varsayılan `Home:default` adresine bir bağlantı `/` yolunu oluşturur.

Maske yalnızca site köküne dayalı göreli yolu değil, aynı zamanda eğik çizgi ile başladığında mutlak yolu, hatta iki eğik çizgi ile başladığında tüm mutlak URL'yi de tanımlayabilir:

```php
// uygulama belgesi kök dizinine göreli yol
$router->addRoute('<presenter>/<action>', /* ... */);

// mutlak yol, sunucu ana bilgisayar adına göreli
$router->addRoute('/<presenter>/<action>', /* ... */);

// ana bilgisayar adı dahil mutlak URL (ancak şema göreli)
$router->addRoute('//<lang>.example.com/<presenter>/<action>', /* ... */);

// şema dahil mutlak URL
$router->addRoute('https://<lang>.example.com/<presenter>/<action>', /* ... */);
```


Doğrulama İfadeleri .[#toc-validation-expressions]
--------------------------------------------------

[Düzenli ifade |https://www.php.net/manual/en/reference.pcre.pattern.syntax.php] kullanılarak her parametre için bir doğrulama koşulu belirtilebilir. Örneğin, `\d+` regexp kullanarak `id` adresini yalnızca sayısal olacak şekilde ayarlayalım:

```php
$router->addRoute('<presenter>/<action>[/<id \d+>]', /* ... */);
```

Tüm parametreler için varsayılan düzenli ifade `[^/]+`yani eğik çizgi dışındaki her şey. Bir parametrenin eğik çizgiyle de eşleşmesi gerekiyorsa, düzenli ifadeyi `.+` olarak ayarlarız.

```php
// https://example.com/a/b/c adresini kabul eder, yol 'a/b/c' şeklindedir
$router->addRoute('<path .+>', /* ... */);
```


İsteğe Bağlı Diziler .[#toc-optional-sequences]
-----------------------------------------------

Köşeli parantezler maskenin isteğe bağlı kısımlarını belirtir. Parametreleri içerenler de dahil olmak üzere maskenin herhangi bir kısmı isteğe bağlı olarak ayarlanabilir:

```php
$router->addRoute('[<lang [a-z]{2}>/]<name>', /* ... */);

// Kabul edilen URL'ler:      Parametreler:
//   /en/download        lang => en, name => download
//   /download           lang => null, name => download
```

Elbette, bir parametre isteğe bağlı bir dizinin parçası olduğunda, o da isteğe bağlı hale gelir. Varsayılan bir değeri yoksa, null olacaktır.

İsteğe bağlı bölümler de etki alanında olabilir:

```php
$router->addRoute('//[<lang=en>.]example.com/<presenter>/<action>', /* ... */);
```

Diziler serbestçe iç içe geçirilebilir ve birleştirilebilir:

```php
$router->addRoute(
	'[<lang [a-z]{2}>[-<sublang>]/]<name>[/page-<page=0>]',
	'Home:default',
);

// Kabul edilen URL'ler:
//   /en/hello
//   /en-us/hello
//   /hello
//   /hello/page-12
```

URL oluşturucu URL'yi mümkün olduğunca kısa tutmaya çalışır, bu nedenle atlanabilecek şeyler atlanır. Bu nedenle, örneğin, bir rota `index[.html]` bir yol oluşturur `/index`. Sol köşeli ayraçtan sonra bir ünlem işareti yazarak bu davranışı tersine çevirebilirsiniz:

```php
// hem /hello hem de /hello.html kabul eder, /hello oluşturur
$router->addRoute('<name>[.html]', /* ... */);

// hem /hello hem de /hello.html kabul eder, /hello.html oluşturur
$router->addRoute('<name>[!.html]', /* ... */);
```

Köşeli parantezler olmadan isteğe bağlı parametreler (yani varsayılan değere sahip parametreler) bu şekilde sarılmış gibi davranır:

```php
$router->addRoute('<presenter=Home>/<action=default>/<id=>', /* ... */);

// eşittir:
$router->addRoute('[<presenter=Home>/[<action=default>/[<id>]]]', /* ... */);
```

En sağdaki eğik çizginin nasıl oluşturulduğunu değiştirmek için, yani `/home/` yerine bir `/home` almak için, rotayı bu şekilde ayarlayın:

```php
$router->addRoute('[<presenter=Home>[/<action=default>[/<id>]]]', /* ... */);
```


Wildcards .[#toc-wildcards]
---------------------------

Mutlak yol maskesinde, örneğin geliştirme ve üretim ortamında farklılık gösterebilecek maskeye bir etki alanı yazma ihtiyacından kaçınmak için aşağıdaki joker karakterleri kullanabiliriz:

- `%tld%` = üst düzey alan adı, örneğin `com` veya `org`
- `%sld%` = ikinci seviye alan adı, örn. `example`
- `%domain%` = alt alan adları olmayan alan adı, örn. `example.com`
- `%host%` = tüm ana bilgisayar, örn. `www.example.com`
- `%basePath%` = kök dizine giden yol

```php
$router->addRoute('//www.%domain%/%basePath%/<presenter>/<action>', /* ... */);
$router->addRoute('//www.%sld%.%tld%/%basePath%/<presenter>/<action', /* ... */);
```


Gelişmiş Notasyon .[#toc-advanced-notation]
-------------------------------------------

Genellikle `Presenter:action` şeklinde yazılan bir rotanın hedefi, tek tek parametreleri ve bunların varsayılan değerlerini tanımlayan bir dizi kullanılarak da ifade edilebilir:

```php
$router->addRoute('<presenter>/<action>[/<id \d+>]', [
	'presenter' => 'Home',
	'action' => 'default',
]);
```

Daha ayrıntılı bir belirtim için, varsayılan değerlere ek olarak, doğrulama düzenli ifadesi gibi diğer parametre özelliklerinin de ayarlanabildiği daha da genişletilmiş bir form kullanılabilir (bkz. `id` parametresi):

```php
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 maskesine dahil edilmemişse, URL'de bir soru işaretinden sonra belirtilen sorgu parametreleri kullanılsa bile değerlerinin değiştirilemeyeceğine dikkat etmek önemlidir.


Filtreler ve Çeviriler .[#toc-filters-and-translations]
-------------------------------------------------------

Kaynak kodunu İngilizce yazmak iyi bir uygulamadır, ancak web sitenizin URL'sinin farklı bir dile çevrilmesi gerekiyorsa ne olacak? Gibi basit rotalar:

```php
$router->addRoute('<presenter>/<action>', 'Home:default');
```

`/product/123` veya `/cart` gibi İngilizce URL'ler oluşturacaktır. URL'deki sunucuların ve eylemlerin Almanca'ya çevrilmesini istiyorsak (örneğin `/produkt/123` veya `/einkaufswagen`), bir çeviri sözlüğü kullanabiliriz. Bunu eklemek için, ikinci parametrenin "daha konuşkan" bir varyantına zaten ihtiyacımız var:

```php
use Nette\Routing\Route;

$router->addRoute('<presenter>/<action>', [
	'presenter' => [
		Route::Value => 'Home',
		Route::FilterTable => [
			// URL'deki dize => presenter
			'produkt' => 'Product',
			'einkaufswagen' => 'Cart',
			'katalog' => 'Catalog',
		],
	],
	'action' => [
		Route::Value => 'default',
		Route::FilterTable => [
			'liste' => 'list',
		],
	],
]);
```

Aynı sunum yapan kişi için birden fazla sözlük anahtarı kullanılabilir. Bunun için çeşitli takma adlar oluşturacaklardır. Son anahtar kanonik varyant olarak kabul edilir (yani oluşturulan URL'de yer alacak olan).

Çeviri tablosu bu şekilde herhangi bir parametreye uygulanabilir. Ancak, çeviri mevcut değilse, orijinal değer alınır. Bu davranışı `Route::FilterStrict => true` ekleyerek değiştirebiliriz ve değer sözlükte yoksa rota URL'yi reddedecektir.

Bir dizi biçimindeki çeviri sözlüğüne ek olarak, kendi çeviri işlevlerini ayarlamak da mümkündür:

```php
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` işlevi, URL'deki parametre ile daha sonra sunum yapan kişiye aktarılan dize arasında dönüşüm yapar, `FilterOut` işlevi ise dönüşümü ters yönde sağlar.

`presenter`, `action` ve `module` parametreleri, URL'de kullanılan PascalCase resp. camelCase stili ile kebab-case arasında dönüşüm yapan önceden tanımlanmış filtrelere sahiptir. Parametrelerin varsayılan değeri dönüştürülmüş formda zaten yazılmıştır, Bu nedenle, örneğin, bir sunum yapan kişi söz konusu olduğunda şunları yazarız `<presenter=ProductEdit>` yerine `<presenter=product-edit>`.


Genel Filtreler .[#toc-general-filters]
---------------------------------------

Belirli parametreler için filtrelerin yanı sıra, herhangi bir şekilde değiştirebilecekleri tüm parametrelerin ilişkisel bir dizisini alan ve ardından geri dönen genel filtreler de tanımlayabilirsiniz. Genel filtreler `null` tuşu altında tanımlanır.

```php
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 size rotanın davranışını kesinlikle herhangi bir şekilde ayarlama olanağı verir. Örneğin bunları, parametreleri diğer parametrelere göre değiştirmek için kullanabiliriz. Örneğin, çeviri `<presenter>` ve `<action>` parametresinin geçerli değerine göre `<lang>`.

Bir parametrede özel bir filtre tanımlanmışsa ve aynı zamanda genel bir filtre varsa, özel `FilterIn` genelden önce çalıştırılır ve bunun tersi olarak genel `FilterOut` özelden önce çalıştırılır. Böylece, genel filtrenin içinde `presenter` ve `action` parametrelerinin değerleri PascalCase ve camelCase stilinde yazılır.


OneWay Bayrağı .[#toc-oneway-flag]
----------------------------------

Tek yönlü rotalar, uygulamanın artık üretmediği ancak hala kabul ettiği eski URL'lerin işlevselliğini korumak için kullanılır. Bunları `OneWay` ile işaretleriz:

```php
// 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, sunucu otomatik olarak yeni URL'ye yönlendirir, böylece arama motorları bu sayfaları iki kez dizine eklemez (bkz. [SEO ve kanonizasyon |#SEO and canonization]).


Geri Çağırmalarla Dinamik Yönlendirme .[#toc-dynamic-routing-with-callbacks]
----------------------------------------------------------------------------

Geri aramalarla dinamik yönlendirme, belirtilen yol ziyaret edildiğinde yürütülecek olan işlevleri (geri aramalar) doğrudan yollara atamanıza olanak tanır. Bu esnek özellik, uygulamanız için hızlı ve verimli bir şekilde çeşitli uç noktalar oluşturmanızı sağlar:

```php
$router->addRoute('test', function () {
	echo 'You are at the /test address';
});
```

Maskede, geri aramanıza otomatik olarak aktarılacak parametreler de tanımlayabilirsiniz:

```php
$router->addRoute('<lang cs|en>', function (string $lang) {
	echo match ($lang) {
		'cs' => 'Welcome to the Czech version of our website!',
		'en' => 'Welcome to the English version of our website!',
	};
});
```


Modüller .[#toc-modules]
------------------------

Bir [modüle |modules] ait daha fazla rotamız varsa, bunları gruplamak için `withModule()` adresini kullanabiliriz:

```php
$router = new RouteList;
$router->withModule('Forum') // aşağıdaki yönlendiriciler Forum modülünün bir parçasıdır
	->addRoute('rss', 'Feed:rss') // Sunucu Forum:Feed
	->addRoute('<presenter>/<action>')

	->withModule('Admin') // aşağıdaki yönlendiriciler Forum:Admin modülünün bir parçasıdır
		->addRoute('sign:in', 'Sign:in');
```

Bir alternatif de `module` parametresini kullanmaktır:

```php
// URL manage/dashboard/default presenter Admin:Dashboard ile eşleşir
$router->addRoute('manage/<presenter>/<action>', [
	'module' => 'Admin',
]);
```


Alt Alanlar .[#toc-subdomains]
------------------------------

Rota koleksiyonları alt alan adlarına göre gruplandırılabilir:

```php
$router = new RouteList;
$router->withDomain('example.com')
	->addRoute('rss', 'Feed:rss')
	->addRoute('<presenter>/<action>');
```

Alan adınızda [joker karakter |#wildcards] ler de kullanabilirsiniz:

```php
$router = new RouteList;
$router->withDomain('example.%tld%')
	// ...
```


Yol Öneki .[#toc-path-prefix]
-----------------------------

Rota koleksiyonları URL'deki yola göre gruplandırılabilir:

```php
$router = new RouteList;
$router->withPath('eshop')
	->addRoute('rss', 'Feed:rss') // /eshop/rss URL'si ile eşleşir
	->addRoute('<presenter>/<action>'); // /eshop/<presenter>/<action> URL'si ile eşleşir
```


Kombinasyonlar .[#toc-combinations]
-----------------------------------

Yukarıdaki kullanım birleştirilebilir:

```php
$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 .[#toc-query-parameters]
--------------------------------------------

Maskeler sorgu parametreleri de içerebilir (URL'de soru işaretinden sonraki parametreler). Bir doğrulama ifadesi tanımlayamazlar, ancak sunum yapan kişiye iletildikleri adı değiştirebilirler:

```php
// uygulamada 'cat' sorgu parametresini 'categoryId' olarak kullan
$router->addRoute('product ? id=<productId> & cat=<categoryId>', /* ... */);
```


Foo Parametreleri .[#toc-foo-parameters]
----------------------------------------

Şimdi daha derine iniyoruz. Foo parametreleri temel olarak düzenli bir ifadeyle eşleşmeye izin veren isimsiz parametrelerdir. Aşağıdaki rota `/index`, `/index.html`, `/index.htm` ve `/index.php` ile eşleşir:

```php
$router->addRoute('index<? \.html?|\.php|>', /* ... */);
```

URL oluşturmak için kullanılacak bir dizeyi açıkça tanımlamak da mümkündür. Dize, soru işaretinden hemen sonra yerleştirilmelidir. Aşağıdaki rota bir öncekine benzer, ancak `/index` yerine `/index.html` oluşturur, çünkü `.html` dizesi "oluşturulan değer" olarak ayarlanmıştır.

```php
$router->addRoute('index<?.html \.html?|\.php|>', /* ... */);
```


Entegrasyon .[#toc-integration]
===============================

Yönlendiricimizi uygulamaya bağlamak için DI konteynerine bunu söylemeliyiz. Bunun en kolay yolu router nesnesini oluşturacak fabrikayı hazırlamak ve container konfigürasyonuna bunu kullanmasını söylemektir. Diyelim ki bu amaçla bir metot yazdık `App\Core\RouterFactory::createRouter()`:

```php
namespace App\Core;

use Nette\Application\Routers\RouteList;

class RouterFactory
{
	public static function createRouter(): RouteList
	{
		$router = new RouteList;
		$router->addRoute(/* ... */);
		return $router;
	}
}
```

Daha sonra [yapılandırmaya |dependency-injection:services] yazıyoruz:

```neon
services:
	- App\Core\RouterFactory::createRouter
```

Veritabanı bağlantısı vb. gibi tüm bağımlılıklar, [otomatik |dependency-injection:autowiring] bağlantı kullanılarak fabrika yöntemine parametreleri olarak aktarılır:

```php
public static function createRouter(Nette\Database\Connection $db): RouteList
{
	// ...
}
```


SimpleRouter .[#toc-simplerouter]
=================================

Route Collection'dan çok daha basit bir yönlendirici [SimpleRouter'dır |api:Nette\Application\Routers\SimpleRouter]. Belirli bir URL formatına ihtiyaç duyulmadığında, `mod_rewrite` (veya alternatifleri) mevcut olmadığında veya henüz kullanıcı dostu URL'lerle uğraşmak istemediğimizde kullanılabilir.

Adresleri kabaca bu biçimde oluşturur:

```
http://example.com/?presenter=Product&action=detail&id=123
```

`SimpleRouter` kurucusunun parametresi varsayılan bir sunumcu ve eylemdir, yani örneğin `http://example.com/` adresini ek parametreler olmadan açarsak yürütülecek eylemdir.

```php
// varsayılan olarak sunucu 'Anasayfa' ve eylem 'varsayılan'
$router = new Nette\Application\Routers\SimpleRouter('Home:default');
```

SimpleRouter'ı doğrudan [yapılandırmada |dependency-injection:services] tanımlamanızı öneririz:

```neon
services:
	- Nette\Application\Routers\SimpleRouter('Home:default')
```


SEO ve Kanonizasyon .[#toc-seo-and-canonization]
================================================

Çerçeve, farklı URL'lerde içeriğin tekrarlanmasını önleyerek SEO'yu (arama motoru optimizasyonu) artırır. Birden fazla adres aynı hedefe bağlanırsa, örneğin `/index` ve `/index.html`, çerçeve ilkini birincil (kanonik) olarak belirler ve diğerlerini HTTP kodu 301 kullanarak ona yönlendirir. Bu sayede arama motorları sayfaları iki kez indekslemeyecek ve sayfa sıralamalarını bozmayacaktır. .

Bu işlem kanonizasyon olarak adlandırılır. Kanonik URL, yönlendirici tarafından, yani OneWay bayrağı olmadan [koleksiyondaki |#route-collection] ilk eşleşen rota tarafından oluşturulan URL'dir. Bu nedenle, koleksiyonda önce **birincil rotaları** listeleriz.

Kanonizasyon, [kanonizasyon |presenters#Canonization] bölümünde daha çok sunum yapan kişi tarafından gerçekleştirilir.


HTTPS .[#toc-https]
===================

HTTPS protokolünü kullanmak için, hosting üzerinde etkinleştirmek ve sunucuyu yapılandırmak gerekir.

Tüm sitenin HTTPS'ye yeniden yönlendirilmesi sunucu düzeyinde, örneğin uygulamamızın kök dizinindeki .htaccess dosyası kullanılarak HTTP kodu 301 ile gerçekleştirilmelidir. Ayarlar barındırmaya bağlı olarak farklılık gösterebilir ve şuna benzer:

```
<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 bir URL oluşturur, bu nedenle başka bir şey ayarlamaya gerek yoktur.

Ancak, istisnai olarak farklı protokoller altında çalışmak için farklı rotalara ihtiyacımız varsa, bunu rota maskesine koyacağız:

```php
// Bir HTTP adresi oluşturacaktır
$router->addRoute('http://%host%/<presenter>/<action>', /* ... */);

// Bir HTTPS adresi oluşturacaktır
$router->addRoute('https://%host%/<presenter>/<action>', /* ... */);
```


Yönlendirici Hata Ayıklama .[#toc-debugging-router]
===================================================

[Tracy Bar |tracy:] 'da görüntülenen yönlendirme çubuğu, rotaların bir listesini ve ayrıca yönlendiricinin URL'den elde ettiği parametreleri görüntüleyen kullanışlı bir araçtır.

Sembolü ✓ olan yeşil çubuk mevcut URL ile eşleşen rotayı temsil eder, sembolü ≈ olan mavi çubuklar ise yeşil onları geçmeseydi URL ile eşleşecek rotaları gösterir. Mevcut sunucuyu ve eylemi daha fazla görüyoruz.

[* routing-debugger.webp *]

Aynı zamanda, [kanonikleştirme |#SEO and Canonization] nedeniyle beklenmedik bir yönlendirme varsa, yönlendiricinin URL'yi başlangıçta nasıl anladığını ve neden yönlendirdiğini görmek için *redirect* çubuğuna bakmak yararlıdır.

.[note]
Yönlendiricide hata ayıklarken, tarayıcıda Geliştirici Araçları'nı açmanız (Ctrl+Shift+I veya Cmd+Option+I) ve yönlendirmelerin depolanmaması için Ağ panelindeki önbelleği devre dışı bırakmanız önerilir.


Performans .[#toc-performance]
==============================

Rota sayısı yönlendiricinin hızını etkiler. Sayıları kesinlikle birkaç düzineyi geçmemelidir. Siteniz aşırı karmaşık bir URL yapısına sahipse, [özel |#custom router] bir yönlendirici yazabilirsiniz.

Yönlendiricinin veritabanı gibi bir bağımlılığı yoksa ve fabrikasının argümanı yoksa, derlenmiş halini doğrudan bir DI konteynerine serileştirebilir ve böylece uygulamayı biraz daha hızlı hale getirebiliriz.

```neon
routing:
	cache: true
```


Özel Yönlendirici .[#toc-custom-router]
=======================================

Aşağıdaki satırlar çok ileri düzey kullanıcılar için tasarlanmıştır. Kendi yönlendiricinizi oluşturabilir ve doğal olarak rota koleksiyonunuza ekleyebilirsiniz. Yönlendirici, [api:Nette\Routing\Router] arayüzünün iki yöntemli bir uygulamasıdır:

```php
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` yöntemi, yalnızca URL'nin değil, başlıkların vb. de alınabildiği geçerli [$httpRequest'i |http:request], sunum yapan kişinin adını ve parametrelerini içeren bir diziye dönüştürür. Eğer isteği işleyemezse null döndürür.
İsteği işlerken, en azından sunum yapan kişiyi ve eylemi döndürmeliyiz. Sunucu adı eksiksizdir ve tüm modülleri içerir:

```php
[
	'presenter' => 'Front:Home',
	'action' => 'default',
]
```

Öte yandan `constructUrl` yöntemi, parametre dizisinden mutlak bir URL oluşturur. Geçerli URL olan `$refUrl` parametresindeki bilgileri kullanabilir.

Rota koleksiyonuna özel yönlendirici eklemek için `add()` adresini kullanın:

```php
$router = new Nette\Application\Routers\RouteList;
$router->add($myRouter);
$router->addRoute(/* ... */);
// ...
```


Ayrılmış Kullanım .[#toc-separated-usage]
=========================================

Ayrı kullanımla, yönlendiricinin yeteneklerinin Nette Uygulaması ve sunucuları kullanmayan bir uygulamada kullanılmasını kastediyoruz. Bu bölümde gösterdiğimiz hemen hemen her şey, aşağıdaki farklarla birlikte bu uygulama için de geçerlidir:

- sınıfını kullandığımız rota koleksiyonları için [api:Nette\Routing\RouteList]
- basit bir yönlendirici sınıfı olarak [api:Nette\Routing\SimpleRouter]
- `Presenter:action` çifti olmadığı için [Gelişmiş gösterimini kullanıyoruz|#Advanced notation]

Bu yüzden yine örneğin bir yönlendirici oluşturacak bir yöntem oluşturacağız:

```php
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;
	}
}
```

Önerdiğimiz gibi bir DI konteyneri kullanıyorsanız, yöntemi yapılandırmaya tekrar ekleyin ve ardından yönlendiriciyi konteynerden HTTP isteği ile birlikte alın:

```php
$router = $container->getByType(Nette\Routing\Router::class);
$httpRequest = $container->getByType(Nette\Http\IRequest::class);
```

Ya da doğrudan nesneler oluşturacağız:

```php
$router = App\Core\RouterFactory::createRouter();
$httpRequest = (new Nette\Http\RequestFactory)->fromGlobals();
```

Şimdi yönlendiricinin çalışmasına izin vermeliyiz:

```php
$params = $router->match($httpRequest);
if ($params === null) {
	// eşleşen rota bulunamadı, 404 hatası göndereceğiz
	exit;
}

// alınan parametreleri işliyoruz
$controller = $params['controller'];
// ...
```

Ve tam tersi, bağlantıyı oluşturmak için yönlendiriciyi kullanacağız:

```php
$params = ['controller' => 'ArticleController', 'id' => 123];
$url = $router->constructUrl($params, $httpRequest->getUrl());
```


{{composer: nette/router}}

Yönlendirme

Yönlendirici, URL'lerle ilgili her şeyden sorumludur, böylece artık bunları düşünmek zorunda kalmazsınız. Biz göstereceğiz:

  • URL'lerin istediğiniz gibi görünmesi için yönlendiricinin nasıl ayarlanacağı
  • SEO yönlendirmesi hakkında birkaç not
  • ve size kendi yönlendiricinizi nasıl yazacağınızı göstereceğiz

Daha insani URL'ler (veya havalı veya güzel URL'ler) daha kullanılabilir, daha akılda kalıcıdır ve SEO'ya olumlu katkıda bulunur. Nette bunu göz önünde bulundurur ve geliştiricilerin isteklerini tam olarak karşılar. Uygulamanız için URL yapınızı tam olarak istediğiniz şekilde tasarlayabilirsiniz. Hatta herhangi bir kod veya şablon değişikliği olmadan yapılabildiği için uygulama hazır olduktan sonra bile tasarlayabilirsiniz. Tek bir yerde, yönlendiricide zarif bir şekilde tanımlanır ve tüm sunumcularda ek açıklamalar şeklinde dağınık değildir.

Nette'deki yönlendirici özeldir çünkü çift yönlüdür, hem HTTP istek URL'lerinin kodunu çözebilir hem de bağlantılar oluşturabilir. Bu nedenle Nette Uygulamasında hayati bir rol oynar, çünkü mevcut isteği hangi sunumcu ve eylemin yürüteceğine karar verir ve ayrıca şablonda URL oluşturma vb. için kullanılır.

Ancak, yönlendirici bu kullanımla sınırlı değildir, sunum yapanların hiç kullanılmadığı uygulamalarda, REST API'leri vb. için kullanabilirsiniz. Ayrılmış kullanım bölümünde daha fazlası.

Rota Koleksiyonu

Uygulamadaki URL adreslerini tanımlamanın en hoş yolu Nette\Application\Routers\RouteList sınıfıdır. Tanım, basit bir API kullanarak sözde rotaların bir listesinden, yani URL adreslerinin maskelerinden ve bunlarla ilişkili sunucu ve eylemlerden oluşur. Rotalara isim vermek zorunda değiliz.

$router = new Nette\Application\Routers\RouteList;
$router->addRoute('rss.xml', 'Feed:rss');
$router->addRoute('article/<id>', 'Article:view');
// ...

Örnek, tarayıcıda https://any-domain.com/rss.xml eylemi ile Feed sunucusunun görüntüleneceğini, https://domain.com/article/12 eylemi ile Article 'un görüntüleneceğini vb. söylüyor. Uygun bir rota bulunamazsa, Nette Application, kullanıcıya 404 Not Found hata sayfası olarak görünen bir BadRequestException istisnası atarak yanıt verir.

Rotaların Sırası

Rotaların listelenme sırası çok önemlidir çünkü yukarıdan aşağıya doğru sırayla değerlendirilirler. Kural, rotaları özelden genele doğru beyan etmemizdir:

// YANLIŞ: 'rss.xml' ilk rota ile eşleşir ve bunu <slug> olarak yanlış anlar
$router->addRoute('<slug>', 'Article:view');
$router->addRoute('rss.xml', 'Feed:rss');

// İYİ
$router->addRoute('rss.xml', 'Feed:rss');
$router->addRoute('<slug>', 'Article:view');

Bağlantılar oluşturulurken rotalar da yukarıdan aşağıya doğru değerlendirilir:

// YANLIŞ: 'Feed:rss' için 'admin/feed/rss' şeklinde bir bağlantı oluşturur
$router->addRoute('admin/<presenter>/<action>', 'Admin:default');
$router->addRoute('rss.xml', 'Feed:rss');

// İYİ
$router->addRoute('rss.xml', 'Feed:rss');
$router->addRoute('admin/<presenter>/<action>', 'Admin:default');

Doğru bir liste oluşturmanın biraz beceri gerektirdiğini sizden saklamayacağız. İşin içine girene kadar, yönlendirme paneli faydalı bir araç olacaktır.

Maske ve Parametreler

Maske, site kökünü temel alan göreli yolu tanımlar. En basit maske statik bir URL'dir:

$router->addRoute('products', 'Products:default');

Genellikle maskeler parametreler olarak adlandırılan parametreler içerir. Bunlar açılı parantezler içine alınır (örn. <year>) ve hedef sunucuya, örneğin renderShow(int $year) yöntemine veya $year kalıcı parametresine aktarılır:

$router->addRoute('chronicle/<year>', 'History:show');

Örnek, tarayıcıda https://any-domain.com/chronicle/2020 sunumcusunun ve year: 2020 parametreli show eyleminin görüntüleneceğini söylüyor.

Parametreler için doğrudan maske içinde varsayılan bir değer belirleyebiliriz ve böylece isteğe bağlı hale gelir:

$router->addRoute('chronicle/<year=2020>', 'History:show');

Rota şimdi https://any-domain.com/chronicle/ parametresiyle birlikte History:show adresini tekrar görüntüleyecektir.

Elbette, sunum yapan kişinin adı ve eylem de bir parametre olabilir. Örneğin:

$router->addRoute('<presenter>/<action>', 'Home:default');

Bu rota, örneğin /article/edit veya /catalog/list şeklinde bir URL'yi kabul eder ve bunları Article:edit veya Catalog:list sunucularına ve eylemlerine çevirir.

Ayrıca presenter ve action parametrelerineHome ve default varsayılan değerlerini verir ve bu nedenle bunlar isteğe bağlıdır. Böylece rota /article URL'sini de kabul eder ve bunu Article:default olarak çevirir. Ya da tam tersi, Product:default adresine bir bağlantı /product yolunu oluşturur, varsayılan Home:default adresine bir bağlantı / yolunu oluşturur.

Maske yalnızca site köküne dayalı göreli yolu değil, aynı zamanda eğik çizgi ile başladığında mutlak yolu, hatta iki eğik çizgi ile başladığında tüm mutlak URL'yi de tanımlayabilir:

// uygulama belgesi kök dizinine göreli yol
$router->addRoute('<presenter>/<action>', /* ... */);

// mutlak yol, sunucu ana bilgisayar adına göreli
$router->addRoute('/<presenter>/<action>', /* ... */);

// ana bilgisayar adı dahil mutlak URL (ancak şema göreli)
$router->addRoute('//<lang>.example.com/<presenter>/<action>', /* ... */);

// şema dahil mutlak URL
$router->addRoute('https://<lang>.example.com/<presenter>/<action>', /* ... */);

Doğrulama İfadeleri

Düzenli ifade kullanılarak her parametre için bir doğrulama koşulu belirtilebilir. Örneğin, \d+ regexp kullanarak id adresini yalnızca sayısal olacak şekilde ayarlayalım:

$router->addRoute('<presenter>/<action>[/<id \d+>]', /* ... */);

Tüm parametreler için varsayılan düzenli ifade [^/]+yani eğik çizgi dışındaki her şey. Bir parametrenin eğik çizgiyle de eşleşmesi gerekiyorsa, düzenli ifadeyi .+ olarak ayarlarız.

// https://example.com/a/b/c adresini kabul eder, yol 'a/b/c' şeklindedir
$router->addRoute('<path .+>', /* ... */);

İsteğe Bağlı Diziler

Köşeli parantezler maskenin isteğe bağlı kısımlarını belirtir. Parametreleri içerenler de dahil olmak üzere maskenin herhangi bir kısmı isteğe bağlı olarak ayarlanabilir:

$router->addRoute('[<lang [a-z]{2}>/]<name>', /* ... */);

// Kabul edilen URL'ler:      Parametreler:
//   /en/download        lang => en, name => download
//   /download           lang => null, name => download

Elbette, bir parametre isteğe bağlı bir dizinin parçası olduğunda, o da isteğe bağlı hale gelir. Varsayılan bir değeri yoksa, null olacaktır.

İsteğe bağlı bölümler de etki alanında olabilir:

$router->addRoute('//[<lang=en>.]example.com/<presenter>/<action>', /* ... */);

Diziler serbestçe iç içe geçirilebilir ve birleştirilebilir:

$router->addRoute(
	'[<lang [a-z]{2}>[-<sublang>]/]<name>[/page-<page=0>]',
	'Home:default',
);

// Kabul edilen URL'ler:
//   /en/hello
//   /en-us/hello
//   /hello
//   /hello/page-12

URL oluşturucu URL'yi mümkün olduğunca kısa tutmaya çalışır, bu nedenle atlanabilecek şeyler atlanır. Bu nedenle, örneğin, bir rota index[.html] bir yol oluşturur /index. Sol köşeli ayraçtan sonra bir ünlem işareti yazarak bu davranışı tersine çevirebilirsiniz:

// hem /hello hem de /hello.html kabul eder, /hello oluşturur
$router->addRoute('<name>[.html]', /* ... */);

// hem /hello hem de /hello.html kabul eder, /hello.html oluşturur
$router->addRoute('<name>[!.html]', /* ... */);

Köşeli parantezler olmadan isteğe bağlı parametreler (yani varsayılan değere sahip parametreler) bu şekilde sarılmış gibi davranır:

$router->addRoute('<presenter=Home>/<action=default>/<id=>', /* ... */);

// eşittir:
$router->addRoute('[<presenter=Home>/[<action=default>/[<id>]]]', /* ... */);

En sağdaki eğik çizginin nasıl oluşturulduğunu değiştirmek için, yani /home/ yerine bir /home almak için, rotayı bu şekilde ayarlayın:

$router->addRoute('[<presenter=Home>[/<action=default>[/<id>]]]', /* ... */);

Wildcards

Mutlak yol maskesinde, örneğin geliştirme ve üretim ortamında farklılık gösterebilecek maskeye bir etki alanı yazma ihtiyacından kaçınmak için aşağıdaki joker karakterleri kullanabiliriz:

  • %tld% = üst düzey alan adı, örneğin com veya org
  • %sld% = ikinci seviye alan adı, örn. example
  • %domain% = alt alan adları olmayan alan adı, örn. example.com
  • %host% = tüm ana bilgisayar, ö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', /* ... */);

Gelişmiş Notasyon

Genellikle Presenter:action şeklinde yazılan bir rotanın hedefi, tek tek parametreleri ve bunların varsayılan değerlerini tanımlayan bir dizi kullanılarak da ifade edilebilir:

$router->addRoute('<presenter>/<action>[/<id \d+>]', [
	'presenter' => 'Home',
	'action' => 'default',
]);

Daha ayrıntılı bir belirtim için, varsayılan değerlere ek olarak, doğrulama düzenli ifadesi gibi diğer parametre özelliklerinin de ayarlanabildiği daha da genişletilmiş bir form kullanılabilir (bkz. id parametresi):

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 maskesine dahil edilmemişse, URL'de bir soru işaretinden sonra belirtilen sorgu parametreleri kullanılsa bile değerlerinin değiştirilemeyeceğine dikkat etmek önemlidir.

Filtreler ve Çeviriler

Kaynak kodunu İngilizce yazmak iyi bir uygulamadır, ancak web sitenizin URL'sinin farklı bir dile çevrilmesi gerekiyorsa ne olacak? Gibi basit rotalar:

$router->addRoute('<presenter>/<action>', 'Home:default');

/product/123 veya /cart gibi İngilizce URL'ler oluşturacaktır. URL'deki sunucuların ve eylemlerin Almanca'ya çevrilmesini istiyorsak (örneğin /produkt/123 veya /einkaufswagen), bir çeviri sözlüğü kullanabiliriz. Bunu eklemek için, ikinci parametrenin „daha konuşkan“ bir varyantına zaten ihtiyacımız var:

use Nette\Routing\Route;

$router->addRoute('<presenter>/<action>', [
	'presenter' => [
		Route::Value => 'Home',
		Route::FilterTable => [
			// URL'deki dize => presenter
			'produkt' => 'Product',
			'einkaufswagen' => 'Cart',
			'katalog' => 'Catalog',
		],
	],
	'action' => [
		Route::Value => 'default',
		Route::FilterTable => [
			'liste' => 'list',
		],
	],
]);

Aynı sunum yapan kişi için birden fazla sözlük anahtarı kullanılabilir. Bunun için çeşitli takma adlar oluşturacaklardır. Son anahtar kanonik varyant olarak kabul edilir (yani oluşturulan URL'de yer alacak olan).

Çeviri tablosu bu şekilde herhangi bir parametreye uygulanabilir. Ancak, çeviri mevcut değilse, orijinal değer alınır. Bu davranışı Route::FilterStrict => true ekleyerek değiştirebiliriz ve değer sözlükte yoksa rota URL'yi reddedecektir.

Bir dizi biçimindeki çeviri sözlüğüne ek olarak, kendi çeviri işlevlerini ayarlamak da mümkündür:

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 işlevi, URL'deki parametre ile daha sonra sunum yapan kişiye aktarılan dize arasında dönüşüm yapar, FilterOut işlevi ise dönüşümü ters yönde sağlar.

presenter, action ve module parametreleri, URL'de kullanılan PascalCase resp. camelCase stili ile kebab-case arasında dönüşüm yapan önceden tanımlanmış filtrelere sahiptir. Parametrelerin varsayılan değeri dönüştürülmüş formda zaten yazılmıştır, Bu nedenle, örneğin, bir sunum yapan kişi söz konusu olduğunda şunları yazarız <presenter=ProductEdit> yerine <presenter=product-edit>.

Genel Filtreler

Belirli parametreler için filtrelerin yanı sıra, herhangi bir şekilde değiştirebilecekleri tüm parametrelerin ilişkisel bir dizisini alan ve ardından geri dönen genel filtreler de tanımlayabilirsiniz. Genel filtreler null tuşu altında tanımlanır.

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 size rotanın davranışını kesinlikle herhangi bir şekilde ayarlama olanağı verir. Örneğin bunları, parametreleri diğer parametrelere göre değiştirmek için kullanabiliriz. Örneğin, çeviri <presenter> ve <action> parametresinin geçerli değerine göre <lang>.

Bir parametrede özel bir filtre tanımlanmışsa ve aynı zamanda genel bir filtre varsa, özel FilterIn genelden önce çalıştırılır ve bunun tersi olarak genel FilterOut özelden önce çalıştırılır. Böylece, genel filtrenin içinde presenter ve action parametrelerinin değerleri PascalCase ve camelCase stilinde yazılır.

OneWay Bayrağı

Tek yönlü rotalar, uygulamanın artık üretmediği ancak hala kabul ettiği eski URL'lerin işlevselliğini korumak için kullanılır. Bunları OneWay ile 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, sunucu otomatik olarak yeni URL'ye yönlendirir, böylece arama motorları bu sayfaları iki kez dizine eklemez (bkz. SEO ve kanonizasyon).

Geri Çağırmalarla Dinamik Yönlendirme

Geri aramalarla dinamik yönlendirme, belirtilen yol ziyaret edildiğinde yürütülecek olan işlevleri (geri aramalar) doğrudan yollara atamanıza olanak tanır. Bu esnek özellik, uygulamanız için hızlı ve verimli bir şekilde çeşitli uç noktalar oluşturmanızı sağlar:

$router->addRoute('test', function () {
	echo 'You are at the /test address';
});

Maskede, geri aramanıza otomatik olarak aktarılacak parametreler de tanımlayabilirsiniz:

$router->addRoute('<lang cs|en>', function (string $lang) {
	echo match ($lang) {
		'cs' => 'Welcome to the Czech version of our website!',
		'en' => 'Welcome to the English version of our website!',
	};
});

Modüller

Bir modüle ait daha fazla rotamız varsa, bunları gruplamak için withModule() adresini kullanabiliriz:

$router = new RouteList;
$router->withModule('Forum') // aşağıdaki yönlendiriciler Forum modülünün bir parçasıdır
	->addRoute('rss', 'Feed:rss') // Sunucu Forum:Feed
	->addRoute('<presenter>/<action>')

	->withModule('Admin') // aşağıdaki yönlendiriciler Forum:Admin modülünün bir parçasıdır
		->addRoute('sign:in', 'Sign:in');

Bir alternatif de module parametresini kullanmaktır:

// URL manage/dashboard/default presenter Admin:Dashboard ile eşleşir
$router->addRoute('manage/<presenter>/<action>', [
	'module' => 'Admin',
]);

Alt Alanlar

Rota koleksiyonları alt alan adlarına göre gruplandırılabilir:

$router = new RouteList;
$router->withDomain('example.com')
	->addRoute('rss', 'Feed:rss')
	->addRoute('<presenter>/<action>');

Alan adınızda joker karakter ler de kullanabilirsiniz:

$router = new RouteList;
$router->withDomain('example.%tld%')
	// ...

Yol Öneki

Rota koleksiyonları URL'deki yola göre gruplandırılabilir:

$router = new RouteList;
$router->withPath('eshop')
	->addRoute('rss', 'Feed:rss') // /eshop/rss URL'si ile eşleşir
	->addRoute('<presenter>/<action>'); // /eshop/<presenter>/<action> URL'si ile eşleşir

Kombinasyonlar

Yukarıdaki kullanım birleştirilebilir:

$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 sorgu parametreleri de içerebilir (URL'de soru işaretinden sonraki parametreler). Bir doğrulama ifadesi tanımlayamazlar, ancak sunum yapan kişiye iletildikleri adı değiştirebilirler:

// uygulamada 'cat' sorgu parametresini 'categoryId' olarak kullan
$router->addRoute('product ? id=<productId> & cat=<categoryId>', /* ... */);

Foo Parametreleri

Şimdi daha derine iniyoruz. Foo parametreleri temel olarak düzenli bir ifadeyle eşleşmeye izin veren isimsiz parametrelerdir. Aşağıdaki rota /index, /index.html, /index.htm ve /index.php ile eşleşir:

$router->addRoute('index<? \.html?|\.php|>', /* ... */);

URL oluşturmak için kullanılacak bir dizeyi açıkça tanımlamak da mümkündür. Dize, soru işaretinden hemen sonra yerleştirilmelidir. Aşağıdaki rota bir öncekine benzer, ancak /index yerine /index.html oluşturur, çünkü .html dizesi „oluşturulan değer“ olarak ayarlanmıştır.

$router->addRoute('index<?.html \.html?|\.php|>', /* ... */);

Entegrasyon

Yönlendiricimizi uygulamaya bağlamak için DI konteynerine bunu söylemeliyiz. Bunun en kolay yolu router nesnesini oluşturacak fabrikayı hazırlamak ve container konfigürasyonuna bunu kullanmasını söylemektir. Diyelim ki bu amaçla bir metot yazdık App\Core\RouterFactory::createRouter():

namespace App\Core;

use Nette\Application\Routers\RouteList;

class RouterFactory
{
	public static function createRouter(): RouteList
	{
		$router = new RouteList;
		$router->addRoute(/* ... */);
		return $router;
	}
}

Daha sonra yapılandırmaya yazıyoruz:

services:
	- App\Core\RouterFactory::createRouter

Veritabanı bağlantısı vb. gibi tüm bağımlılıklar, otomatik bağlantı kullanılarak fabrika yöntemine parametreleri olarak aktarılır:

public static function createRouter(Nette\Database\Connection $db): RouteList
{
	// ...
}

SimpleRouter

Route Collection'dan çok daha basit bir yönlendirici SimpleRouter'dır. Belirli bir URL formatına ihtiyaç duyulmadığında, mod_rewrite (veya alternatifleri) mevcut olmadığında veya henüz kullanıcı dostu URL'lerle uğraşmak istemediğimizde kullanılabilir.

Adresleri kabaca bu biçimde oluşturur:

http://example.com/?presenter=Product&action=detail&id=123

SimpleRouter kurucusunun parametresi varsayılan bir sunumcu ve eylemdir, yani örneğin http://example.com/ adresini ek parametreler olmadan açarsak yürütülecek eylemdir.

// varsayılan olarak sunucu 'Anasayfa' ve eylem 'varsayılan'
$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 Kanonizasyon

Çerçeve, farklı URL'lerde içeriğin tekrarlanmasını önleyerek SEO'yu (arama motoru optimizasyonu) artırır. Birden fazla adres aynı hedefe bağlanırsa, örneğin /index ve /index.html, çerçeve ilkini birincil (kanonik) olarak belirler ve diğerlerini HTTP kodu 301 kullanarak ona yönlendirir. Bu sayede arama motorları sayfaları iki kez indekslemeyecek ve sayfa sıralamalarını bozmayacaktır. .

Bu işlem kanonizasyon olarak adlandırılır. Kanonik URL, yönlendirici tarafından, yani OneWay bayrağı olmadan koleksiyondaki ilk eşleşen rota tarafından oluşturulan URL'dir. Bu nedenle, koleksiyonda önce birincil rotaları listeleriz.

Kanonizasyon, kanonizasyon bölümünde daha çok sunum yapan kişi tarafından gerçekleştirilir.

HTTPS

HTTPS protokolünü kullanmak için, hosting üzerinde etkinleştirmek ve sunucuyu yapılandırmak gerekir.

Tüm sitenin HTTPS'ye yeniden yönlendirilmesi sunucu düzeyinde, örneğin uygulamamızın kök dizinindeki .htaccess dosyası kullanılarak HTTP kodu 301 ile gerçekleştirilmelidir. Ayarlar barındırmaya bağlı olarak farklılık gösterebilir ve şuna benzer:

<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 bir URL oluşturur, bu nedenle başka bir şey ayarlamaya gerek yoktur.

Ancak, istisnai olarak farklı protokoller altında çalışmak için farklı rotalara ihtiyacımız varsa, bunu rota maskesine koyacağız:

// Bir HTTP adresi oluşturacaktır
$router->addRoute('http://%host%/<presenter>/<action>', /* ... */);

// Bir HTTPS adresi oluşturacaktır
$router->addRoute('https://%host%/<presenter>/<action>', /* ... */);

Yönlendirici Hata Ayıklama

Tracy Bar 'da görüntülenen yönlendirme çubuğu, rotaların bir listesini ve ayrıca yönlendiricinin URL'den elde ettiği parametreleri görüntüleyen kullanışlı bir araçtır.

Sembolü ✓ olan yeşil çubuk mevcut URL ile eşleşen rotayı temsil eder, sembolü ≈ olan mavi çubuklar ise yeşil onları geçmeseydi URL ile eşleşecek rotaları gösterir. Mevcut sunucuyu ve eylemi daha fazla görüyoruz.

Aynı zamanda, kanonikleştirme nedeniyle beklenmedik bir yönlendirme varsa, yönlendiricinin URL'yi başlangıçta nasıl anladığını ve neden yönlendirdiğini görmek için redirect çubuğuna bakmak yararlıdır.

Yönlendiricide hata ayıklarken, tarayıcıda Geliştirici Araçları'nı açmanız (Ctrl+Shift+I veya Cmd+Option+I) ve yönlendirmelerin depolanmaması için Ağ panelindeki önbelleği devre dışı bırakmanız önerilir.

Performans

Rota sayısı yönlendiricinin hızını etkiler. Sayıları kesinlikle birkaç düzineyi geçmemelidir. Siteniz aşırı karmaşık bir URL yapısına sahipse, özel bir yönlendirici yazabilirsiniz.

Yönlendiricinin veritabanı gibi bir bağımlılığı yoksa ve fabrikasının argümanı yoksa, derlenmiş halini doğrudan bir DI konteynerine serileştirebilir ve böylece uygulamayı biraz daha hızlı hale getirebiliriz.

routing:
	cache: true

Özel Yönlendirici

Aşağıdaki satırlar çok ileri düzey kullanıcılar için tasarlanmıştır. Kendi yönlendiricinizi oluşturabilir ve doğal olarak rota koleksiyonunuza ekleyebilirsiniz. Yönlendirici, Nette\Routing\Router arayüzünün iki yöntemli 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 yöntemi, yalnızca URL'nin değil, başlıkların vb. de alınabildiği geçerli $httpRequest'i, sunum yapan kişinin adını ve parametrelerini içeren bir diziye dönüştürür. Eğer isteği işleyemezse null döndürür. İsteği işlerken, en azından sunum yapan kişiyi ve eylemi döndürmeliyiz. Sunucu adı eksiksizdir ve tüm modülleri içerir:

[
	'presenter' => 'Front:Home',
	'action' => 'default',
]

Öte yandan constructUrl yöntemi, parametre dizisinden mutlak bir URL oluşturur. Geçerli URL olan $refUrl parametresindeki bilgileri kullanabilir.

Rota koleksiyonuna özel yönlendirici eklemek için add() adresini kullanın:

$router = new Nette\Application\Routers\RouteList;
$router->add($myRouter);
$router->addRoute(/* ... */);
// ...

Ayrılmış Kullanım

Ayrı kullanımla, yönlendiricinin yeteneklerinin Nette Uygulaması ve sunucuları kullanmayan bir uygulamada kullanılmasını kastediyoruz. Bu bölümde gösterdiğimiz hemen hemen her şey, aşağıdaki farklarla birlikte bu uygulama için de geçerlidir:

Bu yüzden yine örneğin bir yönlendirici oluşturacak bir yöntem oluşturacağız:

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;
	}
}

Önerdiğimiz gibi bir DI konteyneri kullanıyorsanız, yöntemi yapılandırmaya tekrar ekleyin ve ardından yönlendiriciyi konteynerden HTTP isteği ile birlikte alın:

$router = $container->getByType(Nette\Routing\Router::class);
$httpRequest = $container->getByType(Nette\Http\IRequest::class);

Ya da doğrudan nesneler oluşturacağız:

$router = App\Core\RouterFactory::createRouter();
$httpRequest = (new Nette\Http\RequestFactory)->fromGlobals();

Şimdi yönlendiricinin çalışmasına izin vermeliyiz:

$params = $router->match($httpRequest);
if ($params === null) {
	// eşleşen rota bulunamadı, 404 hatası göndereceğiz
	exit;
}

// alınan parametreleri işliyoruz
$controller = $params['controller'];
// ...

Ve tam tersi, bağlantıyı oluşturmak için yönlendiriciyi kullanacağız:

$params = ['controller' => 'ArticleController', 'id' => 123];
$url = $router->constructUrl($params, $httpRequest->getUrl());