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.