Yorumlar
Blog faaliyete geçti, çok iyi blog yazıları yazdık ve bunları Adminer üzerinden yayınladık. İnsanlar blogu okuyor ve fikirlerimiz hakkında çok tutkulular. Her gün övgü dolu pek çok e-posta alıyoruz. Ancak tüm bu övgüler sadece e-postada kaldığında ve başka kimse okuyamadığında ne işe yarıyor? İnsanlar doğrudan bloga yorum yapabilse ve böylece herkes ne kadar harika olduğumuzu okuyabilse daha iyi olmaz mıydı?
Tüm makaleleri yorumlanabilir hale getirelim.
Yeni Tablo Oluşturma
Adminer'ı tekrar çalıştırın ve bu sütunlarla comments
adında yeni bir tablo oluşturun:
id
int, otomatik artırmayı (AI) kontrol edinpost_id
,posts
tablosuna referans veren bir yabancı anahtarname
varchar, uzunluk 255email
varchar, uzunluk 255content
metincreated_at
zaman damgası
Bu şekilde görünmelidir:
InnoDB tablo depolamasını kullanmayı unutmayın ve Kaydet'e basın.
CREATE TABLE `comments` (
`id` int NOT NULL AUTO_INCREMENT PRIMARY KEY,
`post_id` int(11) NOT NULL,
`name` varchar(250) NOT NULL,
`email` varchar(250) NOT NULL,
`content` text NOT NULL,
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (`post_id`) REFERENCES `posts` (`id`)
) ENGINE=InnoDB CHARSET=utf8;
Yorum Yapma Formu
İlk olarak, kullanıcıların sayfamıza yorum yapmasına izin verecek bir form oluşturmamız gerekiyor. Nette Framework formlar için harika bir desteğe sahiptir. Bir sunumcuda yapılandırılabilir ve bir şablonda işlenebilirler.
Nette Framework bileşenler kavramına sahiptir. Bir bileşen, başka bir bileşene eklenebilen yeniden
kullanılabilir bir sınıf veya kod parçasıdır. Sunucu bile bir bileşendir. Her bileşen, bileşen fabrikası kullanılarak
oluşturulur. Öyleyse PostPresenter
adresinde yorum formu fabrikasını tanımlayalım.
protected function createComponentCommentForm(): Form
{
$form = new Form; // Nette\Application\UI\Form anlamına gelir
$form->addText('name', 'Your name:')
->setRequired();
$form->addEmail('email', 'Email:');
$form->addTextArea('content', 'Comment:')
->setRequired();
$form->addSubmit('send', 'Publish comment');
return $form;
}
Bunu biraz açıklayalım. İlk satır Form
bileşeninin yeni bir örneğini oluşturuyor. Aşağıdaki yöntemler
HTML girdilerini form tanımına ekliyor. ->addText
şu şekilde render edilecek
<input type=text name=name>
ile <label>Your name:</label>
. Şu anda zaten tahmin etmiş
olabileceğiniz gibi, ->addTextArea
bir <textarea>
ve ->addSubmit
bir
<input type=submit>
. Bunun gibi daha fazla yöntem var, ancak şu anda bilmeniz gereken tek şey bu. Belgelerden daha fazlasını öğrenebilirsiniz.
Form bileşeni bir sunucuda tanımlandıktan sonra, onu bir şablonda oluşturabiliriz (görüntüleyebiliriz). Bunu yapmak
için, {control}
etiketini yazı ayrıntısı şablonunun sonuna, Post/show.latte
içine yerleştirin.
Bileşenin adı commentForm
olduğundan ( createComponentCommentForm
yönteminin adından
türetilmiştir), etiket aşağıdaki gibi görünecektir
...
<h2>Post new comment</h2>
{control commentForm}
Şimdi bazı gönderilerin detaylarını kontrol ederseniz, yorum göndermek için yeni bir form olacaktır.
Veritabanına Kaydetme
Bazı verileri göndermeyi denediniz mi? Formun herhangi bir işlem yapmadığını fark etmiş olabilirsiniz. Sadece orada duruyor, havalı görünüyor ve hiçbir şey yapmıyor. Gönderilen verileri kaydedecek bir geri arama yöntemi eklememiz gerekiyor.
commentForm
bileşen fabrikasında return
satırından önce aşağıdaki satırı yerleştirin:
$form->onSuccess[] = $this->commentFormSucceeded(...);
“Form başarıyla gönderildikten sonra, geçerli sunum yapan kişinin commentFormSucceeded
yöntemini
çağır” anlamına gelir. Bu yöntem henüz mevcut değil, bu yüzden onu oluşturalım.
private function commentFormSucceeded(\stdClass $data): void
{
$id = $this->getParameter('id');
$this->database->table('comments')->insert([
'post_id' => $id,
'name' => $data->name,
'email' => $data->email,
'content' => $data->content,
]);
$this->flashMessage('Thank you for your comment', 'success');
$this->redirect('this');
}
Bunu commentForm
bileşen fabrikasından hemen sonra yerleştirmelisiniz.
new metodunun bir argümanı vardır; bu argüman, bileşen fabrikası tarafından oluşturulan, gönderilen formun
örneğidir. Gönderilen değerleri $data
adresinden alıyoruz. Ve sonra verileri comments
veritabanı
tablosuna ekliyoruz.
Açıklanması gereken iki yöntem çağrısı daha vardır. Yönlendirme, kelimenin tam anlamıyla geçerli sayfaya
yönlendirir. Form gönderildiğinde, geçerli olduğunda ve geri arama işlemi yapması gerekeni yaptığında bunu her seferinde
yapmalısınız. Ayrıca, formu gönderdikten sonra sayfayı yeniden yönlendirdiğinizde, bazen tarayıcıda görebileceğiniz
iyi bilinen Would you like to submit the post data again?
mesajını görmezsiniz. (Genel olarak, POST
yöntemiyle bir form gönderdikten sonra, kullanıcıyı her zaman bir GET
eylemine yönlendirmelisiniz).
flashMessage
, kullanıcıyı bir işlemin sonucu hakkında bilgilendirmek içindir. Yönlendirme yaptığımız
için, mesaj doğrudan şablona aktarılamaz ve işlenemez. Bu yüzden, onu saklayacak ve bir sonraki sayfa yüklemesinde
kullanılabilir hale getirecek bu yöntem vardır. Flash mesajları varsayılan app/UI/@layout.latte
dosyasında
oluşturulur ve aşağıdaki gibi görünür:
<div n:foreach="$flashes as $flash" n:class="flash, $flash->type">
{$flash->message}
</div>
Zaten bildiğimiz gibi, bunlar şablona otomatik olarak aktarılır, bu yüzden çok fazla düşünmenize gerek yoktur, sadece çalışır. Daha fazla ayrıntı için belgeleri kontrol edin.
Yorumların Oluşturulması
Bu çok seveceğiniz şeylerden biri. Nette Database Explorer adında harika bir özelliğe sahip. Tabloları InnoDB olarak oluşturduğumuzu hatırlıyor musunuz? Adminer, bizi bir ton işten kurtaracak sözde yabancı anahtarları oluşturdu.
Nette Database Explorer, tablolar arasındaki ilişkileri çözmek için yabancı anahtarları kullanır ve ilişkileri bilerek sizin için otomatik olarak sorgular oluşturabilir.
Hatırlayabileceğiniz gibi, $post
değişkenini PostPresenter::renderShow()
adresindeki şablona
aktardık ve şimdi post_id
sütunu $post->id
sütunumuza eşit olan tüm yorumları yinelemek
istiyoruz. Bunu $post->related('comments')
adresini çağırarak yapabilirsiniz. Bu kadar basit. Ortaya çıkan
koda bakın.
public function renderShow(int $id): void
{
...
$this->template->post = $post;
$this->template->comments = $post->related('comments')->order('created_at');
}
Ve şablon:
...
<h2>Comments</h2>
<div class="comments">
{foreach $comments as $comment}
<p><b><a href="mailto:{$comment->email}" n:tag-if="$comment->email">
{$comment->name}
</a></b> said:</p>
<div>{$comment->content}</div>
{/foreach}
</div>
...
Özel n:tag-if
niteliğine dikkat edin. n: attributes
'un nasıl çalıştığını zaten
biliyorsunuz. Eğer özniteliğin başına tag-
eklerseniz, sadece etiketlerin etrafına sarılır, içeriklerine
değil. Bu, yorumcunun e-posta adresini verdiyse adını bir bağlantı haline getirmenize olanak tanır. Bu iki satırın
sonuçları aynıdır:
<strong n:tag-if="$important"> Hello there! </strong>
{if $important}<strong>{/if} Hello there! {if $important}</strong>{/if}