Gönderi Sayfası
Şimdi belirli bir gönderiyi gösterecek başka bir blog sayfası oluşturacağız.
Belirli bir makaleyi alacak ve onu şablona aktaracak yeni bir render metodu oluşturmalıyız. Bu metodu
HomePresenter'da bulundurmak pek hoş değil, çünkü makaleden bahsediyoruz, ana sayfadan değil. Bu yüzden
app/Presentation/Post/ içinde PostPresenter oluşturalım. Bu presenter'ın da veritabanına
bağlanması gerekiyor, bu yüzden burada yine veritabanı bağlantısı gerektirecek bir yapıcı yazacağız.
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 ayarlarına
tabi olan doğru App\Presentation\Post ad alanını belirtmeyi unutmamalıyız.
renderShow metodu bir argüman gerektirir – gösterilecek olan belirli bir makalenin ID'si. Ardından bu
makaleyi veritabanından yükler ve şablona aktarır.
Home/default.latte şablonuna Post:show eylemine bir bağlantı ekleyeceğiz.
...
<h2><a href="{link Post:show $post->id}">{$post->title}</a></h2>
...
{link} etiketi, Post:show eylemine yönlendiren bir URL adresi oluşturur. Ayrıca gönderi ID'sini
argüman olarak aktarır.
Aynısını n:nitelik kullanarak kısaca yazabiliriz:
...
<h2><a n:href="Post:show $post->id">{$post->title}</a></h2>
...
n:href niteliği, {link} etiketine benzer.
Ancak Post:show eylemi için henüz bir şablon yok. Bu gönderiye olan bağlantıyı açmayı deneyebiliriz. Tracy, Post/show.latte şablonu henüz mevcut olmadığı için bir hata
gösterecektir. Farklı bir hata mesajı görüyorsanız, muhtemelen web sunucusunda mod_rewrite'ı etkinleştirmeniz
gerekecektir.
Bu nedenle, şu içerikle Post/show.latte şablonunu oluşturacağız:
{block content}
<p><a n:href="Home:default">← gönderi listesine geri 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 bireysel kısımlarını gözden geçirelim.
İlk satır, ana sayfada olduğu gibi “content” adlı bloğun tanımını başlatır. Bu blok yine ana şablonda
gösterilecektir. Gördüğünüz gibi, bitiş etiketi {/block} eksik. Bu isteğe bağlıdır.
Bir sonraki satırda, blog makalelerinin listesine geri dönen bir bağlantı bulunur, böylece kullanıcı makale listesi ile
belirli bir makale arasında kolayca gezinebilir. n:href niteliğini kullandığımız için, Nette bağlantıların
oluşturulmasını kendi başına halleder. Bağlantı, Home presenter'ının default eylemine
yönlendirir (ayrıca n:href="Home:" yazabiliriz, çünkü default adlı eylem atlanabilir, otomatik
olarak tamamlanır).
Üçüncü satır, zaten bildiğimiz bir filtre kullanarak tarih çıktısını biçimlendirir.
Dördüncü satır, blogun başlığını <h1> HTML etiketinde gösterir. Bu etiket,
bilmeyebileceğiniz bir nitelik içerir (n:block="title"). Ne yaptığını tahmin edebilir misiniz? Önceki
bölümü dikkatlice okuduysanız, bunun bir n:attribute olduğunu zaten biliyorsunuzdur. Bu, şuna eşdeğer olan
başka bir örnektir:
{block title}<h1>{$post->title}</h1>{/block}
Basitçe söylemek gerekirse, bu blok title adlı bloğu yeniden tanımlar. Bu blok zaten ana layout
şablonunda (/app/Presentation/@layout.latte:11) tanımlanmıştır ve OOP'deki metotları geçersiz kılmada olduğu
gibi, bu blok ana şablonda tamamen aynı şekilde geçersiz kılınır. Böylece sayfanın <title>'ı şimdi
görüntülenen gönderinin başlığını içerir ve bunun için yalnızca basit bir n:block="title" niteliği
kullanmamız yeterliydi. Harika, değil mi?
Şablonun beşinci ve son satırı, belirli bir gönderinin tüm içeriğini gösterir.
Gönderi ID'sini Kontrol Etme
Birisi URL'deki ID'yi değiştirir ve var olmayan bir id girerse ne olur? Kullanıcıya güzel bir “sayfa
bulunamadı” türünde bir hata sunmalıyız. Bu nedenle PostPresenter'daki render metodunu biraz
değiştireceğiz:
public function renderShow(int $id): void
{
$post = $this->database
->table('posts')
->get($id);
if (!$post) {
$this->error('Sayfa bulunamadı');
}
$this->template->post = $post;
}
Gönderi bulunamazsa, $this->error(...) çağrısı anlaşılır bir mesajla 404 hata sayfasını gösterir.
Geliştirme modunda (localhost) bu hata sayfasını görmeyeceğinize dikkat edin. Bunun yerine, Tracy istisnanın
ayrıntılarıyla birlikte gösterilir, bu da geliştirme için oldukça avantajlıdır. Her iki modu da göstermek istiyorsak,
Bootstrap.php dosyasındaki setDebugMode metodunun argümanını değiştirmemiz yeterlidir.
Özet
Gönderileri olan bir veritabanımız ve iki görünümü olan bir web uygulamamız var – ilki tüm gönderilerin bir özetini gösterir ve ikincisi belirli bir gönderiyi gösterir.