Nette Documentation Preview

syntax
Gönderi Oluşturma ve Düzenleme
******************************

Harika! Süper havalı yeni bir blogumuz var, insanlar yorumlarda hararetle tartışıyor ve nihayet biraz daha programlama yapacak zamanımız oldu. Adminer mükemmel bir araç olsa da, yeni blog gönderileri yazmak için pek konforlu değil. Belki de yeni gönderileri doğrudan uygulamadan eklemek için basit bir form oluşturmanın tam zamanıdır. Hadi yapalım.

Kullanıcı arayüzünü tasarlayarak başlayalım:

1. Ana sayfaya "Yeni gönderi yaz" bağlantısı ekleyelim.
2. Bu bağlantı, bir başlık alanı ve gönderi içeriği için bir textarea içeren bir form gösterecek.
3. Kaydet düğmesine tıkladığımızda gönderi veritabanına kaydedilecek.

Sonradan kimlik doğrulama da ekleyeceğiz ve yalnızca giriş yapmış kullanıcıların yeni gönderi eklemesine izin vereceğiz. Ama bunu sonra yapalım. Her şeyin çalışması için şimdi hangi kodu yazmamız gerekiyor?

1. Gönderi eklemek için bir formu olan yeni bir presenter oluşturmak.
2. Formun başarıyla gönderilmesinden sonra tetiklenecek ve yeni gönderiyi veritabanına kaydedecek bir callback tanımlamak.
3. Form için yeni bir şablon oluşturmak.
4. Ana sayfa şablonuna forma giden bir bağlantı eklemek.


Yeni Presenter
==============

Yeni presenter'a `EditPresenter` adını verelim ve onu `app/Presentation/Edit/EditPresenter.php` dosyasına kaydedelim. Onun da veritabanına bağlanması gerekiyor, dolayısıyla burada yine veritabanı bağlantısı isteyen bir yapıcı yazıyoruz:

```php .{file:app/Presentation/Edit/EditPresenter.php}
<?php
namespace App\Presentation\Edit;

use Nette;
use Nette\Application\UI\Form;

final class EditPresenter extends Nette\Application\UI\Presenter
{
	public function __construct(
		private Nette\Database\Explorer $database,
	) {
	}
}
```


Gönderileri Kaydetmek İçin Form
===============================

Formlar ve bileşenler, yorum desteğini eklerken zaten ele alınmıştı. Hâlâ belirsizse, [formların ve bileşenlerin nasıl çalıştığını |comments#Yorum Formu] gidip gözden geçirin, biz burada bekleriz ;)

Şimdi bu metodu `EditPresenter` içine ekleyin:

```php .{file:app/Presentation/Edit/EditPresenter.php}
protected function createComponentPostForm(): Form
{
	$form = new Form;
	$form->addText('title', 'Başlık:')
		->setRequired();
	$form->addTextArea('content', 'İçerik:')
		->setRequired();

	$form->addSubmit('send', 'Kaydet ve yayımla');
	$form->onSuccess[] = $this->postFormSucceeded(...);

	return $form;
}
```


Yeni Gönderiyi Formdan Kaydetme
===============================

İşleyici metodunu ekleyerek devam edelim:

```php .{file:app/Presentation/Edit/EditPresenter.php}
private function postFormSucceeded(array $data): void
{
	$post = $this->database
		->table('posts')
		->insert($data);

	$this->flashMessage('Gönderi başarıyla yayımlandı.', 'success');
	$this->redirect('Post:show', $post->id);
}
```

Kısaca açıklayalım: değerleri formdan alır, veritabanına ekler, kullanıcı için gönderinin başarıyla kaydedildiğine dair bir mesaj oluşturur ve o gönderinin yayımlandığı sayfaya yönlendirir; böylece nasıl göründüğünü görebilirsiniz.


Yeni Gönderi Oluşturma Sayfası
==============================

Şimdi `Edit/create.latte` şablonunu oluşturalım:

```latte .{file:app/Presentation/Edit/create.latte}
{block content}
<h1>Yeni gönderi</h1>

{control postForm}
```

Bu noktada her şey açık olmalı. Son satır, az önce oluşturduğumuz formu render eder.

Buna karşılık gelen bir `renderCreate()` metodu da oluşturabilirdik, ama gerekli değil. Veritabanından herhangi bir veri almamız ya da onu şablona aktarmamız gerekmiyor, dolayısıyla metot boş olurdu. Böyle durumlarda metodun hiç var olmasına gerek yoktur.


Gönderi Oluşturma Bağlantısı
============================

`EditPresenter` ve onun `create` eylemine nasıl bağlantı ekleneceğini muhtemelen zaten biliyorsunuz. Deneyin.

`app/Presentation/Home/default.latte` dosyasına yalnızca şunu ekleyin:

```latte
<a n:href="Edit:create">Yeni gönderi yaz</a>
```


Gönderileri Düzenleme
=====================

Şimdi var olan gönderileri düzenleme yeteneğini ekleyelim. Çok basit olacak. `postForm` formumuz zaten var ve onu düzenleme için de kullanabiliriz.

`EditPresenter` içine yeni bir `edit` sayfası ekleyeceğiz:

```php .{file:app/Presentation/Edit/EditPresenter.php}
public function renderEdit(int $id): void
{
	$post = $this->database
		->table('posts')
		->get($id);

	if (!$post) {
		$this->error('Post not found');
	}

	$this->getComponent('postForm')
		->setDefaults($post->toArray());
}
```

Ve buna karşılık gelen `Edit/edit.latte` şablonunu oluşturalım:

```latte .{file:app/Presentation/Edit/edit.latte}
{block content}
<h1>Gönderiyi düzenle</h1>

{control postForm}
```

Ve `postFormSucceeded` metodunu güncelleyelim; böylece hem yeni gönderi ekleyebilecek (şimdi yaptığı gibi) hem de var olanları düzenleyebilecek:

```php .{file:app/Presentation/Edit/EditPresenter.php}
private function postFormSucceeded(array $data): void
{
	$id = $this->getParameter('id');

	if ($id) {
		$post = $this->database
			->table('posts')
			->get($id);
		$post->update($data);

	} else {
		$post = $this->database
			->table('posts')
			->insert($data);
	}

	$this->flashMessage('Gönderi başarıyla yayımlandı.', 'success');
	$this->redirect('Post:show', $post->id);
}
```

`id` parametresi verildiğinde, bu bir gönderinin düzenlendiği anlamına gelir. Böyle bir durumda gönderinin gerçekten var olduğunu denetleriz ve varsa onu veritabanında güncelleriz. `id` verilmediyse, bu yeni bir gönderinin ekleneceği anlamına gelir.

Peki `id` nereden geliyor? O, `renderEdit` metoduna aktarılan parametredir.

Artık `app/Presentation/Post/show.latte` şablonuna bir bağlantı ekleyebilirsiniz:

```latte
<a n:href="Edit:edit $post->id">Bu gönderiyi düzenle</a>
```


Özet
====

Blog çalışıyor, insanlar hızla yorum yapıyor ve yeni gönderi eklemek için artık Adminer'a bağımlı değiliz. Tümüyle bağımsız ve sıradan insanlar bile oraya gönderi yazabiliyor. Ama durun, herkesin, yani İnternet'teki gerçekten herkesin blogumuza gönderi yazabilmesi muhtemelen doğru değil. Yalnızca giriş yapmış kullanıcıların gönderi yazabilmesi için bir tür kimlik doğrulama gerekiyor. Bunu bir sonraki bölümde ekleyeceğiz.

{{priority: -1}}

Gönderi Oluşturma ve Düzenleme

Harika! Süper havalı yeni bir blogumuz var, insanlar yorumlarda hararetle tartışıyor ve nihayet biraz daha programlama yapacak zamanımız oldu. Adminer mükemmel bir araç olsa da, yeni blog gönderileri yazmak için pek konforlu değil. Belki de yeni gönderileri doğrudan uygulamadan eklemek için basit bir form oluşturmanın tam zamanıdır. Hadi yapalım.

Kullanıcı arayüzünü tasarlayarak başlayalım:

  1. Ana sayfaya „Yeni gönderi yaz“ bağlantısı ekleyelim.
  2. Bu bağlantı, bir başlık alanı ve gönderi içeriği için bir textarea içeren bir form gösterecek.
  3. Kaydet düğmesine tıkladığımızda gönderi veritabanına kaydedilecek.

Sonradan kimlik doğrulama da ekleyeceğiz ve yalnızca giriş yapmış kullanıcıların yeni gönderi eklemesine izin vereceğiz. Ama bunu sonra yapalım. Her şeyin çalışması için şimdi hangi kodu yazmamız gerekiyor?

  1. Gönderi eklemek için bir formu olan yeni bir presenter oluşturmak.
  2. Formun başarıyla gönderilmesinden sonra tetiklenecek ve yeni gönderiyi veritabanına kaydedecek bir callback tanımlamak.
  3. Form için yeni bir şablon oluşturmak.
  4. Ana sayfa şablonuna forma giden bir bağlantı eklemek.

Yeni Presenter

Yeni presenter'a EditPresenter adını verelim ve onu app/Presentation/Edit/EditPresenter.php dosyasına kaydedelim. Onun da veritabanına bağlanması gerekiyor, dolayısıyla burada yine veritabanı bağlantısı isteyen bir yapıcı yazıyoruz:

<?php
namespace App\Presentation\Edit;

use Nette;
use Nette\Application\UI\Form;

final class EditPresenter extends Nette\Application\UI\Presenter
{
	public function __construct(
		private Nette\Database\Explorer $database,
	) {
	}
}

Gönderileri Kaydetmek İçin Form

Formlar ve bileşenler, yorum desteğini eklerken zaten ele alınmıştı. Hâlâ belirsizse, formların ve bileşenlerin nasıl çalıştığını gidip gözden geçirin, biz burada bekleriz ;)

Şimdi bu metodu EditPresenter içine ekleyin:

protected function createComponentPostForm(): Form
{
	$form = new Form;
	$form->addText('title', 'Başlık:')
		->setRequired();
	$form->addTextArea('content', 'İçerik:')
		->setRequired();

	$form->addSubmit('send', 'Kaydet ve yayımla');
	$form->onSuccess[] = $this->postFormSucceeded(...);

	return $form;
}

Yeni Gönderiyi Formdan Kaydetme

İşleyici metodunu ekleyerek devam edelim:

private function postFormSucceeded(array $data): void
{
	$post = $this->database
		->table('posts')
		->insert($data);

	$this->flashMessage('Gönderi başarıyla yayımlandı.', 'success');
	$this->redirect('Post:show', $post->id);
}

Kısaca açıklayalım: değerleri formdan alır, veritabanına ekler, kullanıcı için gönderinin başarıyla kaydedildiğine dair bir mesaj oluşturur ve o gönderinin yayımlandığı sayfaya yönlendirir; böylece nasıl göründüğünü görebilirsiniz.

Yeni Gönderi Oluşturma Sayfası

Şimdi Edit/create.latte şablonunu oluşturalım:

{block content}
<h1>Yeni gönderi</h1>

{control postForm}

Bu noktada her şey açık olmalı. Son satır, az önce oluşturduğumuz formu render eder.

Buna karşılık gelen bir renderCreate() metodu da oluşturabilirdik, ama gerekli değil. Veritabanından herhangi bir veri almamız ya da onu şablona aktarmamız gerekmiyor, dolayısıyla metot boş olurdu. Böyle durumlarda metodun hiç var olmasına gerek yoktur.

Gönderi Oluşturma Bağlantısı

EditPresenter ve onun create eylemine nasıl bağlantı ekleneceğini muhtemelen zaten biliyorsunuz. Deneyin.

app/Presentation/Home/default.latte dosyasına yalnızca şunu ekleyin:

<a n:href="Edit:create">Yeni gönderi yaz</a>

Gönderileri Düzenleme

Şimdi var olan gönderileri düzenleme yeteneğini ekleyelim. Çok basit olacak. postForm formumuz zaten var ve onu düzenleme için de kullanabiliriz.

EditPresenter içine yeni bir edit sayfası ekleyeceğiz:

public function renderEdit(int $id): void
{
	$post = $this->database
		->table('posts')
		->get($id);

	if (!$post) {
		$this->error('Post not found');
	}

	$this->getComponent('postForm')
		->setDefaults($post->toArray());
}

Ve buna karşılık gelen Edit/edit.latte şablonunu oluşturalım:

{block content}
<h1>Gönderiyi düzenle</h1>

{control postForm}

Ve postFormSucceeded metodunu güncelleyelim; böylece hem yeni gönderi ekleyebilecek (şimdi yaptığı gibi) hem de var olanları düzenleyebilecek:

private function postFormSucceeded(array $data): void
{
	$id = $this->getParameter('id');

	if ($id) {
		$post = $this->database
			->table('posts')
			->get($id);
		$post->update($data);

	} else {
		$post = $this->database
			->table('posts')
			->insert($data);
	}

	$this->flashMessage('Gönderi başarıyla yayımlandı.', 'success');
	$this->redirect('Post:show', $post->id);
}

id parametresi verildiğinde, bu bir gönderinin düzenlendiği anlamına gelir. Böyle bir durumda gönderinin gerçekten var olduğunu denetleriz ve varsa onu veritabanında güncelleriz. id verilmediyse, bu yeni bir gönderinin ekleneceği anlamına gelir.

Peki id nereden geliyor? O, renderEdit metoduna aktarılan parametredir.

Artık app/Presentation/Post/show.latte şablonuna bir bağlantı ekleyebilirsiniz:

<a n:href="Edit:edit $post->id">Bu gönderiyi düzenle</a>

Özet

Blog çalışıyor, insanlar hızla yorum yapıyor ve yeni gönderi eklemek için artık Adminer'a bağımlı değiliz. Tümüyle bağımsız ve sıradan insanlar bile oraya gönderi yazabiliyor. Ama durun, herkesin, yani İnternet'teki gerçekten herkesin blogumuza gönderi yazabilmesi muhtemelen doğru değil. Yalnızca giriş yapmış kullanıcıların gönderi yazabilmesi için bir tür kimlik doğrulama gerekiyor. Bunu bir sonraki bölümde ekleyeceğiz.