Nette Documentation Preview

syntax
Crearea și editarea posturilor
******************************

Ce timp minunat! Avem un nou blog super tare, oamenii se ceartă în comentarii și în sfârșit avem timp pentru mai multă programare. Deși ne place Adminer, nu este atât de confortabil să scriem articole de blog în el. Poate că este momentul potrivit pentru a adăuga un formular simplu pentru adăugarea de noi postări direct din aplicația noastră. Haideți să o facem.

Să începem prin a proiecta interfața de utilizare:

1. Pe pagina principală, să adăugăm un link "Scrieți o nouă postare".
2. Se va afișa un formular cu titlu și textarea pentru conținut.
3. Când faceți clic pe un buton "Save", va salva postarea de pe blog.

Mai târziu vom adăuga și autentificarea și vom permite doar utilizatorilor autentificați să adauge postări noi. Dar să facem asta mai târziu. Ce cod va trebui să scriem pentru a face să funcționeze acest lucru?

1. Creați un nou prezentator cu un formular pentru adăugarea de postări.
2. Definiți un callback care va fi declanșat după trimiterea cu succes a formularului și care va salva noua postare în baza de date.
3. Creați un nou șablon pentru formular.
4. Adăugați un link către formular în șablonul paginii principale.


Noul prezentator .[#toc-new-presenter]
======================================

Numiți noul prezentator `EditPresenter` și salvați-l în `app/UI/Edit/`. De asemenea, acesta trebuie să se conecteze la baza de date, așa că și aici vom scrie un constructor care va necesita o conexiune la baza de date:

```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,
	) {
	}
}
```


Formular pentru salvarea postărilor .[#toc-form-for-saving-posts]
=================================================================

Formularele și componentele au fost deja abordate atunci când am adăugat suport pentru comentarii. Dacă sunteți confuz în legătură cu subiectul, mergeți să verificați din nou [cum funcționează formularele și componentele |comments#form-for-commenting], noi vom aștepta aici ;)

Acum adăugați această metodă la `EditPresenter`:

```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;
}
```


Salvarea unei noi postări din formular .[#toc-saving-new-post-from-form]
========================================================================

Continuați prin adăugarea unei metode de gestionare.

```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);
}
```

Doar o scurtă explicație: aceasta preia valorile din formular, le inserează în baza de date, creează un mesaj pentru utilizator că postarea a fost salvată cu succes și redirecționează către pagina în care este publicată acea postare, astfel încât să puteți vedea cum arată.


Pagina pentru crearea unei postări noi .[#toc-page-for-creating-a-new-post]
===========================================================================

Să creăm doar șablonul `Edit/create.latte`:

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

{control postForm}
```

Totul ar trebui să fie clar până acum. Ultima linie arată formularul pe care urmează să îl creăm.

Am putea, de asemenea, să creăm o metodă `renderCreate` corespunzătoare, dar nu este necesar. Nu avem nevoie să obținem date din baza de date și să le transmitem șablonului, așa că acea metodă ar fi goală. În astfel de cazuri, este posibil ca metoda să nu existe deloc.


Legătură pentru crearea de mesaje .[#toc-link-for-creating-posts]
=================================================================

Probabil că știți deja cum să adăugați un link la `EditPresenter` și la acțiunea sa `create`. Încercați-o.

Trebuie doar să adăugați la fișierul `app/UI/Home/default.latte`:

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


Editarea posturilor .[#toc-editing-posts]
=========================================

Să adăugăm, de asemenea, posibilitatea de a edita posturile existente. Va fi destul de simplu - avem deja `postForm` și îl putem folosi și pentru editare.

Vom adăuga o nouă pagină `edit` la `EditPresenter`:

```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());
}
```

Și vom crea șablonul `Edit/edit.latte`:

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

{control postForm}
```

Și actualizați metoda `postFormSucceeded`, care va putea fie să adauge o nouă postare (așa cum se întâmplă acum), fie să le editeze pe cele existente:

```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);
}
```

Atunci când este furnizat parametrul `id`, înseamnă că se editează o postare. În acest caz, vom verifica dacă postul există cu adevărat și, dacă da, îl vom actualiza în baza de date. În cazul în care parametrul `id` nu este furnizat, înseamnă că se va adăuga o nouă postare.

Dar de unde provine `id`? Este parametrul transmis metodei `renderEdit`.

Acum puteți adăuga un link la șablonul `app/UI/Post/show.latte`:

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


Rezumat .[#toc-summary]
=======================

Blogul funcționează, oamenii comentează rapid și nu ne mai bazăm pe Adminer pentru adăugarea de noi articole. Este complet independent și chiar și oamenii normali pot posta acolo. Dar stați puțin, probabil că nu este în regulă, că oricine, adică chiar oricine de pe internet, poate posta pe blogul nostru. Este necesară o formă de autentificare, astfel încât doar utilizatorii conectați să poată posta. Vom adăuga acest lucru în capitolul următor.

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

Crearea și editarea posturilor

Ce timp minunat! Avem un nou blog super tare, oamenii se ceartă în comentarii și în sfârșit avem timp pentru mai multă programare. Deși ne place Adminer, nu este atât de confortabil să scriem articole de blog în el. Poate că este momentul potrivit pentru a adăuga un formular simplu pentru adăugarea de noi postări direct din aplicația noastră. Haideți să o facem.

Să începem prin a proiecta interfața de utilizare:

  1. Pe pagina principală, să adăugăm un link „Scrieți o nouă postare“.
  2. Se va afișa un formular cu titlu și textarea pentru conținut.
  3. Când faceți clic pe un buton „Save“, va salva postarea de pe blog.

Mai târziu vom adăuga și autentificarea și vom permite doar utilizatorilor autentificați să adauge postări noi. Dar să facem asta mai târziu. Ce cod va trebui să scriem pentru a face să funcționeze acest lucru?

  1. Creați un nou prezentator cu un formular pentru adăugarea de postări.
  2. Definiți un callback care va fi declanșat după trimiterea cu succes a formularului și care va salva noua postare în baza de date.
  3. Creați un nou șablon pentru formular.
  4. Adăugați un link către formular în șablonul paginii principale.

Noul prezentator

Numiți noul prezentator EditPresenter și salvați-l în app/UI/Edit/. De asemenea, acesta trebuie să se conecteze la baza de date, așa că și aici vom scrie un constructor care va necesita o conexiune la baza de date:

<?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,
	) {
	}
}

Formular pentru salvarea postărilor

Formularele și componentele au fost deja abordate atunci când am adăugat suport pentru comentarii. Dacă sunteți confuz în legătură cu subiectul, mergeți să verificați din nou cum funcționează formularele și componentele, noi vom aștepta aici ;)

Acum adăugați această metodă la EditPresenter:

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;
}

Salvarea unei noi postări din formular

Continuați prin adăugarea unei metode de gestionare.

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);
}

Doar o scurtă explicație: aceasta preia valorile din formular, le inserează în baza de date, creează un mesaj pentru utilizator că postarea a fost salvată cu succes și redirecționează către pagina în care este publicată acea postare, astfel încât să puteți vedea cum arată.

Pagina pentru crearea unei postări noi

Să creăm doar șablonul Edit/create.latte:

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

{control postForm}

Totul ar trebui să fie clar până acum. Ultima linie arată formularul pe care urmează să îl creăm.

Am putea, de asemenea, să creăm o metodă renderCreate corespunzătoare, dar nu este necesar. Nu avem nevoie să obținem date din baza de date și să le transmitem șablonului, așa că acea metodă ar fi goală. În astfel de cazuri, este posibil ca metoda să nu existe deloc.

Probabil că știți deja cum să adăugați un link la EditPresenter și la acțiunea sa create. Încercați-o.

Trebuie doar să adăugați la fișierul app/UI/Home/default.latte:

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

Editarea posturilor

Să adăugăm, de asemenea, posibilitatea de a edita posturile existente. Va fi destul de simplu – avem deja postForm și îl putem folosi și pentru editare.

Vom adăuga o nouă pagină edit la EditPresenter:

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());
}

Și vom crea șablonul Edit/edit.latte:

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

{control postForm}

Și actualizați metoda postFormSucceeded, care va putea fie să adauge o nouă postare (așa cum se întâmplă acum), fie să le editeze pe cele existente:

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);
}

Atunci când este furnizat parametrul id, înseamnă că se editează o postare. În acest caz, vom verifica dacă postul există cu adevărat și, dacă da, îl vom actualiza în baza de date. În cazul în care parametrul id nu este furnizat, înseamnă că se va adăuga o nouă postare.

Dar de unde provine id? Este parametrul transmis metodei renderEdit.

Acum puteți adăuga un link la șablonul app/UI/Post/show.latte:

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

Rezumat

Blogul funcționează, oamenii comentează rapid și nu ne mai bazăm pe Adminer pentru adăugarea de noi articole. Este complet independent și chiar și oamenii normali pot posta acolo. Dar stați puțin, probabil că nu este în regulă, că oricine, adică chiar oricine de pe internet, poate posta pe blogul nostru. Este necesară o formă de autentificare, astfel încât doar utilizatorii conectați să poată posta. Vom adăuga acest lucru în capitolul următor.