URL Bağlantıları Oluşturma

Nette'de bağlantı oluşturmak parmakla göstermek kadar kolaydır. Sadece işaret etmeniz yeterlidir ve framework tüm işi sizin için yapar. Şunları göstereceğiz:

  • şablonlarda ve başka yerlerde bağlantılar nasıl oluşturulur
  • mevcut sayfaya bir bağlantı nasıl ayırt edilir
  • geçersiz bağlantılarla ne yapılmalı

Çift yönlü yönlendirme sayesinde, şablonlarınıza veya kodunuza daha sonra değişebilecek veya karmaşık bir şekilde birleştirilmesi gereken uygulamanızın URL adreslerini asla sabit kodlamanız gerekmeyecektir. Bağlantıda presenter'ı ve eylemi belirtmeniz, olası parametreleri iletmeniz yeterlidir ve framework URL'yi kendisi oluşturacaktır. Aslında, bir fonksiyonu çağırmaya çok benzer. Bunu seveceksiniz.

Presenter şablonunda

En sık olarak şablonlarda bağlantılar oluştururuz ve n:href niteliği harika bir yardımcıdır:

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

HTML niteliği href yerine n:niteliği n:href kullandığımıza dikkat edin. Değeri, href niteliğinde olduğu gibi bir URL değil, presenter'ın ve eylemin adıdır.

Bir bağlantıya tıklamak, basitleştirilmiş bir ifadeyle, ProductPresenter::renderShow() metodunu çağırmak gibidir. Ve eğer imzasında parametreler varsa, onu argümanlarla çağırabiliriz:

<a n:href="Product:show $product->id, $product->slug">ürün detayı</a>

Adlandırılmış parametreleri iletmek de mümkündür. Aşağıdaki bağlantı, lang parametresini cs değeriyle iletir:

<a n:href="Product:show $product->id, lang: cs">ürün detayı</a>

Eğer ProductPresenter::renderShow() metodu imzasında $lang içermiyorsa, parametrenin değerini $lang = $this->getParameter('lang') kullanarak veya özellikten öğrenebilir.

Parametreler bir dizide saklanıyorsa, ... operatörü (Latte 2.x'te (expand) operatörü) ile genişletilebilirler:

{var $args = [$product->id, lang => cs]}
<a n:href="Product:show ...$args">ürün detayı</a>

Bağlantılarda sözde kalıcı parametreler de otomatik olarak iletilir.

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

Adres: {link Home:default}

Kodda

Presenter'da bir bağlantı oluşturmak için link() metodu kullanılır:

$url = $this->link('Product:show', $product->id);

Parametreler, adlandırılmış parametrelerin de belirtilebildiği bir dizi kullanılarak da iletilebilir:

$url = $this->link('Product:show', [$product->id, 'lang' => 'cs']);

Bağlantılar presenter olmadan da oluşturulabilir, bunun için LinkGenerator ve onun link() metodu vardır.

Presenter'a Bağlantılar

Bağlantının hedefi bir presenter ve eylem ise, şu sözdizimine sahiptir:

[//] [[[[:]module:]presenter:]action | this] [#fragment]

Format, tüm Latte etiketleri ve bağlantılarla çalışan tüm presenter metotları tarafından desteklenir, yani n:href, {link}, {plink}, link(), lazyLink(), isLinkCurrent(), redirect(), redirectPermanent(), forward(), canonicalize() ve ayrıca LinkGenerator. Dolayısıyla, örneklerde n:href kullanılmış olsa bile, fonksiyonlardan herhangi biri orada olabilirdi.

Temel form bu nedenle Presenter:action şeklindedir:

<a n:href="Home:default">ana sayfa</a>

Mevcut presenter'ın bir eylemine bağlantı veriyorsak, adını atlayabiliriz:

<a n:href="default">ana sayfa</a>

Hedef eylem default ise, onu atlayabiliriz, ancak iki nokta üst üste kalmalıdır:

<a n:href="Home:">ana sayfa</a>

Bağlantılar ayrıca diğer modüllere de yönlendirebilir. Burada bağlantılar, iç içe geçmiş alt modüle göreceli veya mutlak olarak ayırt edilir. Prensip, diskteki yollara benzer, yalnızca eğik çizgiler yerine iki nokta üst üste kullanılır. Mevcut presenter'ın Front modülünün bir parçası olduğunu varsayalım, o zaman şunu yazarız:

<a n:href="Shop:Product:show">Front:Shop:Product:show bağlantısı</a>
<a n:href=":Admin:Product:show">Admin:Product:show bağlantısı</a>

Özel bir durum, hedef olarak this belirttiğimiz kendine bağlantıdır.

<a n:href="this">yenile</a>

Izgara işareti # sonrasındaki bir parça (fragment) aracılığıyla sayfanın belirli bir bölümüne bağlantı verebiliriz:

<a n:href="Home:#main">Home:default ve #main parçasına bağlantı</a>

Mutlak Yollar

link() veya n:href kullanılarak oluşturulan bağlantılar her zaman mutlak yollardır (yani / karakteriyle başlarlar), ancak https://domain gibi protokol ve alan adı içeren mutlak URL'ler değildir.

Mutlak bir URL oluşturmak için başına iki eğik çizgi ekleyin (örn. n:href="//Home:"). Veya presenter'ı yalnızca mutlak bağlantılar oluşturacak şekilde $this->absoluteUrls = true ayarlayarak değiştirebilirsiniz.

Mevcut Sayfaya Bağlantı

this hedefi mevcut sayfaya bir bağlantı oluşturur:

<a n:href="this">yenile</a>

Aynı zamanda, action<Action>() veya render<View>() metotlarının imzasında belirtilen tüm parametreler de, action<Action>() tanımlanmamışsa iletilir. Dolayısıyla, Product:show sayfasındaysak ve id: 123 ise, this bağlantısı bu parametreyi de iletecektir.

Elbette parametreleri doğrudan belirtmek de mümkündür:

<a n:href="this refresh: 1">yenile</a>

isLinkCurrent() fonksiyonu, bağlantı hedefinin mevcut sayfayla aynı olup olmadığını kontrol eder. Bu, örneğin şablonda bağlantıları ayırt etmek vb. için kullanılabilir.

Parametreler link() metoduyla aynıdır, ancak ek olarak belirli bir eylem yerine, söz konusu presenter'ın herhangi bir eylemi anlamına gelen * joker karakterini belirtmek mümkündür.

{if !isLinkCurrent('Admin:login')}
	<a n:href="Admin:login">Giriş Yap</a>
{/if}

<li n:class="isLinkCurrent('Product:*') ? active">
	<a n:href="Product:">...</a>
</li>

Tek bir öğede n:href ile birlikte kullanıldığında, kısaltılmış bir form kullanılabilir:

<a n:class="isLinkCurrent() ? active" n:href="Home:">...</a>

* joker karakteri yalnızca eylem yerine kullanılabilir, presenter yerine kullanılamaz.

Belirli bir modülde veya alt modülünde olup olmadığımızı kontrol etmek için isModuleCurrent(moduleName) metodunu kullanırız.

<li n:class="isModuleCurrent('Forum:Users') ? active">
	<a n:href="Product:">...</a>
</li>

Sinyale Bağlantılar

Bağlantının hedefi yalnızca bir presenter ve eylem olmak zorunda değildir, aynı zamanda bir sinyal de olabilir (handle<Signal>() metodunu çağırırlar). O zaman sözdizimi aşağıdaki gibidir:

[//] [sub-component:]signal! [#fragment]

Sinyal bu nedenle bir ünlem işaretiyle ayırt edilir:

<a n:href="click!">sinyal</a>

Bir alt bileşenin (veya alt-alt bileşenin) sinyaline bir bağlantı oluşturmak da mümkündür:

<a n:href="componentName:click!">sinyal</a>

Bileşendeki Bağlantılar

Bileşenler bağımsız, yeniden kullanılabilir birimler olduğundan ve çevreleyen presenter'larla herhangi bir bağlantısı olmaması gerektiğinden, bağlantılar burada biraz farklı çalışır. Latte niteliği n:href ve {link} etiketi ile link() gibi bileşen metotları ve diğerleri, bağlantı hedefini her zaman sinyal adı olarak kabul eder. Bu nedenle ünlem işareti belirtmek bile gerekli değildir:

<a n:href="click">sinyal, eylem değil</a>

Bileşen şablonunda presenter'lara bağlantı vermek isteseydik, bunun için {plink} etiketini kullanırdık:

<a href={plink Home:default}>giriş</a>

veya kodda

$this->getPresenter()->link('Home:default')

Takma Adlar (Alias)

Bazen Presenter:eylem çiftine kolayca hatırlanabilir bir takma ad atamak yararlı olabilir. Örneğin, Front:Home:default giriş sayfasını basitçe home olarak veya Admin:Dashboard:default sayfasını admin olarak adlandırmak.

Takma adlar, yapılandırmada application › aliases anahtarı altında tanımlanır:

application:
    aliases:
        home: Front:Home:default
        admin: Admin:Dashboard:default
        sign: Front:Sign:in

Bağlantılarda, örneğin bir at işareti kullanılarak yazılırlar:

<a n:href="@admin">yönetim</a>

redirect() ve benzeri gibi bağlantılarla çalışan tüm metotlarda da desteklenirler.

Geçersiz Bağlantılar

Geçersiz bir bağlantı oluşturmamız olabilir – ya var olmayan bir presenter'a yönlendirdiği için, ya hedef metodun imzasında kabul ettiğinden daha fazla parametre ilettiği için ya da hedef eylem için bir URL oluşturulamadığı için. Geçersiz bağlantılarla nasıl başa çıkılacağını statik değişken Presenter::$invalidLinkMode belirler. Bu, şu değerlerin bir kombinasyonunu alabilir (sabitler):

  • Presenter::InvalidLinkSilent – sessiz mod, URL olarak # karakteri döndürülür
  • Presenter::InvalidLinkWarning – E_USER_WARNING uyarısı atılır, bu üretim modunda günlüğe kaydedilir, ancak betiğin çalışmasını kesintiye uğratmaz
  • Presenter::InvalidLinkTextual – görsel uyarı, hatayı doğrudan bağlantıya yazar
  • Presenter::InvalidLinkException – InvalidLinkException istisnası atılır

Varsayılan ayar, üretim modunda InvalidLinkWarning ve geliştirme modunda InvalidLinkWarning | InvalidLinkTextual şeklindedir. Üretim ortamındaki InvalidLinkWarning, betiğin kesintiye uğramasına neden olmaz, ancak uyarı günlüğe kaydedilir. Geliştirme ortamında, Tracy tarafından yakalanır ve bir mavi ekran görüntüler. InvalidLinkTextual, #error: karakterleriyle başlayan bir hata mesajını URL olarak döndürerek çalışır. Bu tür bağlantıların ilk bakışta belirgin olmasını sağlamak için CSS'imize ekleriz:

a[href^="#error:"] {
	background: red;
	color: white;
}

Geliştirme ortamında uyarıların üretilmesini istemiyorsak, sessiz modu doğrudan yapılandırmada ayarlayabiliriz.

application:
	silentLinks: true

LinkGenerator

link() metodunun sunduğu benzer konforla, ancak presenter olmadan bağlantılar nasıl oluşturulur? Bunun için Nette\Application\LinkGenerator vardır.

LinkGenerator, kurucu aracılığıyla size iletilmesini isteyebileceğiniz ve ardından link() metoduyla bağlantılar oluşturabileceğiniz bir servistir.

Presenter'lara kıyasla burada bir fark vardır. LinkGenerator tüm bağlantıları doğrudan mutlak URL'ler olarak oluşturur. Ayrıca, “mevcut presenter” diye bir şey yoktur, bu nedenle hedef olarak yalnızca link('default') eylem adını belirtmek veya modüllere göreceli yollar belirtmek mümkün değildir.

Geçersiz bağlantılar her zaman Nette\Application\UI\InvalidLinkException atar.

versiyon: 4.0