Tek Gönderi Sayfası
Blogumuza, belirli bir gönderinin içeriğini gösterecek bir sayfa daha ekleyelim.
Belirli bir gönderiyi alıp şablona aktaracak yeni bir render metodu oluşturmamız gerekiyor. Bu metodu
HomePresenter içine koymak pek derli toplu olmaz; çünkü konu ana sayfa değil tek bir gönderi. Öyleyse yeni bir
PostPresenter sınıfı oluşturup onu app/Presentation/Post/ dizinine koyalım. Bu presenter'ın da bir
veritabanı bağlantısına ihtiyacı olacak, dolayısıyla veritabanı bağlantısını isteyecek yapıcıyı ekleyeceğiz.
PostPresenter şöyle görünebilir:
<?php
namespace App\Presentation\Post;
use Nette;
use Nette\Application\UI\Form;
final class PostPresenter extends Nette\Application\UI\Presenter
{
public function __construct(
private Nette\Database\Explorer $database,
) {
}
public function renderShow(int $id): void
{
$this->template->post = $this->database
->table('posts')
->get($id);
}
}
Presenter eşlemesi
yapılandırmasına bağlı olan doğru App\Presentation\Post isim alanını belirtmeyi unutmamalıyız.
renderShow metodu bir argüman ister: gösterilecek gönderinin ID'si. Sonra gönderiyi veritabanından yükler ve
şablona aktarır.
Home/default.latte şablonuna Post:show eylemine bir bağlantı ekliyoruz:
...
<h2><a href="{link Post:show $post->id}">{$post->title}</a></h2>
...
{link} etiketi, Post:show eylemine işaret eden bir URL adresi üretir. Ayrıca gönderi ID'sini
argüman olarak aktarır.
Aynı şey bir n:attribute ile derli toplu biçimde yazılabilir:
...
<h2><a n:href="Post:show $post->id">{$post->title}</a></h2>
...
n:href niteliği {link} etiketine benzer.
Ancak Post:show eyleminin şablonu henüz yok. Bu gönderiye giden bağlantıyı açmayı deneyebiliriz. Tracy, Post/show.latte şablonu henüz var olmadığı için bir hata
gösterecek. Farklı bir hata mesajı görüyorsanız, büyük olasılıkla web sunucunuzda mod_rewrite modülünü
etkinleştirmeniz gerekiyor.
Öyleyse Post/show.latte dosyasını şu içerikle oluşturacağız:
{block content}
<p><a n:href="Home:default">← gönderi listesine dön</a></p>
<div class="date">{$post->created_at|date:'F j, Y'}</div>
<h1 n:block="title">{$post->title}</h1>
<div class="post">{$post->content}</div>
Şimdi şablonun tek tek parçalarını gözden geçirelim.
İlk satır, tıpkı ana sayfadaki gibi “content” adlı bir bloğun tanımını başlatır. Bu blok yine ana yerleşim
şablonunun içinde görüntülenecek. Gördüğünüz gibi kapanış {/block} etiketi yok. O isteğe
bağlıdır.
İkinci satır, blog gönderilerinin listesine geri dönmeyi sağlayan bir bağlantı sunar; böylece kullanıcı gönderi
listesiyle belirli bir gönderi arasında kolayca gezinebilir. Yine n:href niteliğini kullanıyoruz, dolayısıyla
URL üretmeyi Nette üstlenecek. Bağlantı, Home presenter'ının default eylemine işaret eder
(n:href="Home:" de yazabilirdiniz; çünkü default eylem adı atlanabilir, otomatik eklenir).
Üçüncü satır, tarihi zaten bildiğimiz bir filtreyle biçimlendirir.
Dördüncü satır, blog gönderisinin başlığını bir <h1> HTML etiketinin içinde gösterir. Bu
etiket, tanımayabileceğiniz bir nitelik içerir (n:block="title"). Ne yaptığını tahmin edebilir misiniz?
Önceki bölümü dikkatle okuduysanız onun bir n:attribute olduğunu zaten biliyorsunuz. Bu, şuna eşdeğer bir
başka örnektir:
{block title}<h1>{$post->title}</h1>{/block}
Basitçe söylemek gerekirse, bu blok title adlı bloğu yeniden tanımlar. Bu blok, ana layout şablonunda
(/app/Presentation/@layout.latte:11) zaten tanımlıdır ve tıpkı OOP'deki metot geçersiz kılma gibi, bu blok ana
şablondakini geçersiz kılar. Bu yüzden sayfanın <title> etiketi artık gösterilen gönderinin
başlığını içerecek ve tek gereken bu basit n:block="title" niteliğiydi. Harika, değil mi?
Şablonun beşinci ve son satırı, belirli gönderinin içeriğinin tamamını gösterir.
Gönderi ID'sini Denetleme
Biri URL'deki ID'yi değiştirip var olmayan bir id koyarsa ne olur? Kullanıcıya güzel bir “sayfa
bulunamadı” hatası göstermeliyiz. PostPresenter içindeki render metodunu biraz değiştirelim:
public function renderShow(int $id): void
{
$post = $this->database
->table('posts')
->get($id);
if (!$post) {
$this->error('Post not found');
}
$this->template->post = $post;
}
Gönderi bulunamazsa, $this->error(...) çağrısı anlaşılır bir mesaj içeren bir 404 sayfası
gösterecek. Geliştirme ortamında (localhost'ta) bu hata sayfasını görmeyeceğinizi unutmayın. Bunun yerine Tracy,
istisnayı tüm ayrıntılarıyla gösterecek; bu da geliştirme için epey elverişlidir. İki kipi de sınamak isterseniz,
Bootstrap.php dosyasında setDebugMode metoduna verilen argümanı değiştirmeniz yeter.
Özet
Gönderileri içeren bir veritabanımız ve iki view'lı bir web uygulamamız var; ilki tüm gönderilere genel bakış gösteriyor, ikincisi belirli bir gönderiyi gösteriyor.