Nette Documentation Preview

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

Ne harika bir zaman. Süper havalı yeni bir blogumuz var, insanlar yorumlarda tartışıyor ve nihayet daha fazla programlama için biraz zamanımız var. Adminer'i sevmemize rağmen, blog yazıları yazmak o kadar da rahat değil. Belki de doğrudan uygulamamızdan yeni yazılar eklemek için basit bir form eklemenin tam zamanıdır. Hadi yapalım.

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

1. Ana sayfaya bir "Yeni yazı yaz" bağlantısı ekleyelim.
2. Başlık ve içerik için textarea içeren bir form gösterecektir.
3. Kaydet düğmesine tıkladığınızda, blog gönderisini kaydedecektir.

Daha sonra kimlik doğrulama da ekleyeceğiz ve yalnızca oturum açmış kullanıcıların yeni gönderiler eklemesine izin vereceğiz. Ama bunu daha sonra yapalım. Çalışması için hangi kodu yazmamız gerekecek?

1. Gönderi eklemek için bir form içeren yeni bir sunucu oluşturun.
2. Formun başarılı bir şekilde gönderilmesinden sonra tetiklenecek ve yeni gönderiyi veritabanına kaydedecek bir geri arama tanımlayın.
3. Form için yeni bir şablon oluşturun.
4. Ana sayfa şablonuna form için bir bağlantı ekleyin.


Yeni Sunucu .[#toc-new-presenter]
=================================

Yeni sunucuya `EditPresenter` adını verin ve `app/UI/Edit/` adresine kaydedin. Ayrıca veritabanına bağlanması gerekir, bu nedenle burada yine bir veritabanı bağlantısı gerektirecek bir kurucu yazıyoruz:

```php .{file:app/UI/Edit/EditPresenter.php}
<?php
namespace App\UI\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 Kaydetme Formu .[#toc-form-for-saving-posts]
========================================================

Formlar ve bileşenler, yorumlar için destek eklediğimizde zaten ele alındı. Konu hakkında kafanız karıştıysa, formların [ve bileşenlerin nasıl çalıştığını |comments#form-for-commenting] tekrar kontrol edin, biz burada bekleyeceğiz ;)

Şimdi bu yöntemi `EditPresenter` adresine ekleyin:

```php .{file:app/UI/Edit/EditPresenter.php}
protected function createComponentPostForm(): Form
{
	$form = new Form;
	$form->addText('title', 'Title:')
		->setRequired();
	$form->addTextArea('content', 'Content:')
		->setRequired();

	$form->addSubmit('send', 'Save and publish');
	$form->onSuccess[] = $this->postFormSucceeded(...);

	return $form;
}
```


Yeni Gönderiyi Formdan Kaydetme .[#toc-saving-new-post-from-form]
=================================================================

Bir işleyici yöntemi ekleyerek devam edin.

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

	$this->flashMessage('Post was published', 'success');
	$this->redirect('Post:show', $post->id);
}
```

Kısa bir açıklama: formdan değerleri alır, bunları veritabanına ekler, kullanıcı için gönderinin başarıyla kaydedildiğine dair bir mesaj oluşturur ve nasıl göründüğünü görebilmeniz için gönderinin yayınlandığı sayfaya yönlendirir.


Yeni Gönderi Oluşturma Sayfası .[#toc-page-for-creating-a-new-post]
===================================================================

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

```latte .{file:app/UI/Edit/create.latte}
{block content}
<h1>New post</h1>

{control postForm}
```

Şimdiye kadar her şey netleşmiş olmalı. Son satır, oluşturmak üzere olduğumuz formu göstermektedir.

Buna karşılık gelen bir `renderCreate` yöntemi de oluşturabiliriz, ancak bu gerekli değildir. Veritabanından herhangi bir veri almamız ve bunu şablona aktarmamız gerekmez, bu nedenle bu yöntem boş olacaktır. Bu gibi durumlarda, yöntem hiç mevcut olmayabilir.


Gönderi Oluşturma Bağlantısı .[#toc-link-for-creating-posts]
============================================================

Muhtemelen `EditPresenter` adresine ve `create` eylemine nasıl bağlantı ekleyeceğinizi zaten biliyorsunuzdur. Deneyin bakalım.

Sadece `app/UI/Home/default.latte` dosyasına ekleyin:

```latte
<a n:href="Edit:create">Write new post</a>
```


Gönderileri Düzenleme .[#toc-editing-posts]
===========================================

Mevcut gönderileri düzenleme özelliğini de ekleyelim. Oldukça basit olacak - zaten `postForm` adresimiz var ve bunu düzenleme için de kullanabiliriz.

`EditPresenter` adresine yeni bir `edit` sayfası ekleyeceğiz:

```php .{file:app/UI/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 `Edit/edit.latte` şablonunu oluşturun:

```latte .{file:app/UI/Edit/edit.latte}
{block content}
<h1>Edit post</h1>

{control postForm}
```

Ve yeni bir gönderi ekleyebilecek (şimdi olduğu gibi) veya mevcut olanları düzenleyebilecek olan `postFormSucceeded` yöntemini güncelleyin:

```php .{file:app/UI/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('Post was published', 'success');
	$this->redirect('Post:show', $post->id);
}
```

`id` parametresi sağlandığında, bir gönderinin düzenlenmekte olduğu anlamına gelir. Böyle bir durumda, gönderinin gerçekten var olup olmadığını kontrol edeceğiz ve eğer varsa, veritabanında güncelleyeceğiz. `id` parametresi sağlanmazsa, yeni bir yazı ekleneceği anlamına gelir.

Peki `id` nereden geliyor? `renderEdit` yöntemine aktarılan parametredir.

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

```latte
<a n:href="Edit:edit $post->id">Edit this post</a>
```


Özet .[#toc-summary]
====================

Blog çalışıyor, insanlar hızla yorum yapıyor ve artık yeni yazılar eklemek için Adminer'a güvenmiyoruz. Tamamen bağımsız ve normal insanlar bile buraya gönderi yapabiliyor. Ama durun, bu muhtemelen doğru değil, herkes, yani gerçekten internetteki herkes blogumuza gönderi ekleyebilir. Yalnızca oturum açmış kullanıcıların gönderi yapabilmesi için bir tür kimlik doğrulama gereklidir. Bunu bir sonraki bölümde ekleyeceğiz.

{{priority: -1}}
{{sitename: Nette Quickstart}}

Gönderi Oluşturma ve Düzenleme

Ne harika bir zaman. Süper havalı yeni bir blogumuz var, insanlar yorumlarda tartışıyor ve nihayet daha fazla programlama için biraz zamanımız var. Adminer'i sevmemize rağmen, blog yazıları yazmak o kadar da rahat değil. Belki de doğrudan uygulamamızdan yeni yazılar eklemek için basit bir form eklemenin tam zamanıdır. Hadi yapalım.

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

  1. Ana sayfaya bir „Yeni yazı yaz“ bağlantısı ekleyelim.
  2. Başlık ve içerik için textarea içeren bir form gösterecektir.
  3. Kaydet düğmesine tıkladığınızda, blog gönderisini kaydedecektir.

Daha sonra kimlik doğrulama da ekleyeceğiz ve yalnızca oturum açmış kullanıcıların yeni gönderiler eklemesine izin vereceğiz. Ama bunu daha sonra yapalım. Çalışması için hangi kodu yazmamız gerekecek?

  1. Gönderi eklemek için bir form içeren yeni bir sunucu oluşturun.
  2. Formun başarılı bir şekilde gönderilmesinden sonra tetiklenecek ve yeni gönderiyi veritabanına kaydedecek bir geri arama tanımlayın.
  3. Form için yeni bir şablon oluşturun.
  4. Ana sayfa şablonuna form için bir bağlantı ekleyin.

Yeni Sunucu

Yeni sunucuya EditPresenter adını verin ve app/UI/Edit/ adresine kaydedin. Ayrıca veritabanına bağlanması gerekir, bu nedenle burada yine bir veritabanı bağlantısı gerektirecek bir kurucu yazıyoruz:

<?php
namespace App\UI\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 Kaydetme Formu

Formlar ve bileşenler, yorumlar için destek eklediğimizde zaten ele alındı. Konu hakkında kafanız karıştıysa, formların ve bileşenlerin nasıl çalıştığını tekrar kontrol edin, biz burada bekleyeceğiz ;)

Şimdi bu yöntemi EditPresenter adresine ekleyin:

protected function createComponentPostForm(): Form
{
	$form = new Form;
	$form->addText('title', 'Title:')
		->setRequired();
	$form->addTextArea('content', 'Content:')
		->setRequired();

	$form->addSubmit('send', 'Save and publish');
	$form->onSuccess[] = $this->postFormSucceeded(...);

	return $form;
}

Yeni Gönderiyi Formdan Kaydetme

Bir işleyici yöntemi ekleyerek devam edin.

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

	$this->flashMessage('Post was published', 'success');
	$this->redirect('Post:show', $post->id);
}

Kısa bir açıklama: formdan değerleri alır, bunları veritabanına ekler, kullanıcı için gönderinin başarıyla kaydedildiğine dair bir mesaj oluşturur ve nasıl göründüğünü görebilmeniz için gönderinin yayınlandığı sayfaya yönlendirir.

Yeni Gönderi Oluşturma Sayfası

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

{block content}
<h1>New post</h1>

{control postForm}

Şimdiye kadar her şey netleşmiş olmalı. Son satır, oluşturmak üzere olduğumuz formu göstermektedir.

Buna karşılık gelen bir renderCreate yöntemi de oluşturabiliriz, ancak bu gerekli değildir. Veritabanından herhangi bir veri almamız ve bunu şablona aktarmamız gerekmez, bu nedenle bu yöntem boş olacaktır. Bu gibi durumlarda, yöntem hiç mevcut olmayabilir.

Muhtemelen EditPresenter adresine ve create eylemine nasıl bağlantı ekleyeceğinizi zaten biliyorsunuzdur. Deneyin bakalım.

Sadece app/UI/Home/default.latte dosyasına ekleyin:

<a n:href="Edit:create">Write new post</a>

Gönderileri Düzenleme

Mevcut gönderileri düzenleme özelliğini de ekleyelim. Oldukça basit olacak – zaten postForm adresimiz var ve bunu düzenleme için de kullanabiliriz.

EditPresenter adresine 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 Edit/edit.latte şablonunu oluşturun:

{block content}
<h1>Edit post</h1>

{control postForm}

Ve yeni bir gönderi ekleyebilecek (şimdi olduğu gibi) veya mevcut olanları düzenleyebilecek olan postFormSucceeded yöntemini güncelleyin:

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('Post was published', 'success');
	$this->redirect('Post:show', $post->id);
}

id parametresi sağlandığında, bir gönderinin düzenlenmekte olduğu anlamına gelir. Böyle bir durumda, gönderinin gerçekten var olup olmadığını kontrol edeceğiz ve eğer varsa, veritabanında güncelleyeceğiz. id parametresi sağlanmazsa, yeni bir yazı ekleneceği anlamına gelir.

Peki id nereden geliyor? renderEdit yöntemine aktarılan parametredir.

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

<a n:href="Edit:edit $post->id">Edit this post</a>

Özet

Blog çalışıyor, insanlar hızla yorum yapıyor ve artık yeni yazılar eklemek için Adminer'a güvenmiyoruz. Tamamen bağımsız ve normal insanlar bile buraya gönderi yapabiliyor. Ama durun, bu muhtemelen doğru değil, herkes, yani gerçekten internetteki herkes blogumuza gönderi ekleyebilir. Yalnızca oturum açmış kullanıcıların gönderi yapabilmesi için bir tür kimlik doğrulama gereklidir. Bunu bir sonraki bölümde ekleyeceğiz.