Nette Documentation Preview

syntax
Създаване и редактиране на публикации
*************************************

Какво страхотно време. Имаме супер готин нов блог, хората спорят в коментарите и най-накрая имаме време за програмиране. Въпреки че обичаме Adminer, писането на статии за блогове в него не е много удобно. Сега може би е подходящ момент да добавим прост формуляр за добавяне на нови публикации директно от нашето приложение. Да го направим.

Нека започнем с проектирането на потребителския интерфейс:

1. На началната страница нека добавим връзка "Напиши нова публикация".
2. ще се покаже формуляр със заглавие и текстова област за съдържанието.
3. Когато щракнете върху Запази, публикацията в блога ще бъде запазена.

По-късно ще добавим и удостоверяване на автентичността и ще позволим само на влезлите в системата потребители да добавят нови публикации. Какъв код трябва да напишем, за да работи?

1. Създайте нов презентатор с формуляр за добавяне на публикации.
2. дефинирайте обратна връзка, която ще се задейства след успешно изпращане на формуляра и която ще запази новата публикация в базата данни.
3. Създайте нов шаблон за формуляра.
4. Добавете връзка към формуляра в шаблона на началната страница.


Нов водещ .[#toc-new-presenter]
===============================

Дайте име на новия презентатор `EditPresenter` и го запишете на `app/UI/Edit/`. Той също така трябва да се свърже с базата данни, така че тук отново ще напишем конструктор, който ще изисква свързване с базата данни:

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


Форма за запазване на съобщения .[#toc-form-for-saving-posts]
=============================================================

Формите и компонентите вече бяха разгледани при добавянето на поддръжка на коментари. Ако сте объркани от темата, вижте отново [как работят формите и компонентите |comments#Form-for-Commenting], ние ще почакаме тук ;)

Сега добавете този метод в `EditPresenter`:

```php .{file:app/UI/Edit/EditPresenter.php}
protected function createComponentPostForm(): Form
{
	$form = new Form;
	$form->addText('title', 'Заголовок:')
		->setRequired();
	$form->addTextArea('content', 'Содержание:')
		->setRequired();

	$form->addSubmit('send', 'Сохранить и опубликовать');
	$form->onSuccess[] = $this->postFormSucceeded(...);

	return $form;
}
```


Запазване на нова публикация от формуляр .[#toc-saving-new-post-from-form]
==========================================================================

Нека да добавим метод за обработка:

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

	$this->flashMessage('Пост опубликован!', 'success');
	$this->redirect('Post:show', $post->id);
}
```

Малко обяснение: този метод извлича стойностите от формуляра, вмъква ги в базата данни, създава съобщение за потребителя, че публикацията е била успешно публикувана, и пренасочва към страницата, на която е публикувана публикацията, за да можете да видите как изглежда тя.


Страница за създаване на нова публикация .[#toc-page-for-creating-a-new-post]
=============================================================================

Нека просто създадем шаблон (`app/UI/Edit/create.latte`):

```latte .{file:app/UI/Edit/create.latte}
{block content}
<h1>Новый пост</h1>

{control postForm}
```

Всичко вече трябва да е ясно. Последният ред показва формата, която ще създадем.

Бихме могли да създадем и съответен метод `renderCreate`, но това не е необходимо. Не е необходимо да извличаме данни от базата данни и да ги предаваме на шаблона, така че този метод ще бъде празен. В такива случаи методът може изобщо да не съществува.


Връзка за създаване на публикации .[#toc-link-for-creating-posts]
=================================================================

Вероятно вече знаете как да добавите връзка към `EditPresenter` и нейното действие `create`. Опитайте.

Просто добавете към файла `app/UI/Home/default.latte`:

```latte
<a n:href="Edit:create">Создать пост</a>
```


Редактиране на публикации .[#toc-editing-posts]
===============================================

Нека добавим и възможност за редактиране на съществуващи публикации. Това ще бъде съвсем просто - вече имаме `postForm`, а можем да го използваме и за редактиране.

Ще добавим нова страница `edit` към `EditPresenter`:

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

	if (!$post) {
		$this->error('Пост не найден');
	}

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

И създайте шаблон `Edit/edit.latte`:

```latte .{file:app/UI/Edit/edit.latte}
{block content}
<h1>Редактирование поста</h1>

{control postForm}
```

И актуализирайте метода `postFormSucceeded`, който ще може да добавя нова публикация (както сега) или да редактира съществуващите:

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

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

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

	$this->flashMessage('Пост опубликован', 'success');
	$this->redirect('Post:show', $post->id);
}
```

Ако е посочен `postId`, това означава, че публикацията се редактира. В този случай ще проверим дали публикацията действително съществува и ако е така, ще я актуализираме в базата данни. Ако не е посочен `postId`, това означава, че ще бъде добавена нова публикация.

Но откъде идва `postId`? Това е параметърът, който се предава на метода `renderEdit`.

Сега можете да добавите връзка за промяна на публикацията в шаблона `app/UI/Post/show.latte`:

```latte
<a n:href="Edit:edit $post->id">Изменить пост</a>
```


За да обобщим .[#toc-summary]
=============================

Блогът работи, хората бързо коментират и вече не разчитаме на администратора да добавя нови публикации. Блогът е напълно независим и в него могат да публикуват дори обикновени хора. Но чакайте, вероятно не е нормално всеки, имам предвид наистина всеки в интернет, да може да пише в нашия блог. Изисква се някаква форма на удостоверяване, така че само регистрираните потребители да могат да публикуват. Това ще добавим в следващата глава.

{{priority: -1}}
{{sitename: Быстрый старт с Nette}}

Създаване и редактиране на публикации

Какво страхотно време. Имаме супер готин нов блог, хората спорят в коментарите и най-накрая имаме време за програмиране. Въпреки че обичаме Adminer, писането на статии за блогове в него не е много удобно. Сега може би е подходящ момент да добавим прост формуляр за добавяне на нови публикации директно от нашето приложение. Да го направим.

Нека започнем с проектирането на потребителския интерфейс:

  1. На началната страница нека добавим връзка „Напиши нова публикация“.
  2. ще се покаже формуляр със заглавие и текстова област за съдържанието.
  3. Когато щракнете върху Запази, публикацията в блога ще бъде запазена.

По-късно ще добавим и удостоверяване на автентичността и ще позволим само на влезлите в системата потребители да добавят нови публикации. Какъв код трябва да напишем, за да работи?

  1. Създайте нов презентатор с формуляр за добавяне на публикации.
  2. дефинирайте обратна връзка, която ще се задейства след успешно изпращане на формуляра и която ще запази новата публикация в базата данни.
  3. Създайте нов шаблон за формуляра.
  4. Добавете връзка към формуляра в шаблона на началната страница.

Нов водещ

Дайте име на новия презентатор EditPresenter и го запишете на app/UI/Edit/. Той също така трябва да се свърже с базата данни, така че тук отново ще напишем конструктор, който ще изисква свързване с базата данни:

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

Форма за запазване на съобщения

Формите и компонентите вече бяха разгледани при добавянето на поддръжка на коментари. Ако сте объркани от темата, вижте отново как работят формите и компонентите, ние ще почакаме тук ;)

Сега добавете този метод в EditPresenter:

protected function createComponentPostForm(): Form
{
	$form = new Form;
	$form->addText('title', 'Заголовок:')
		->setRequired();
	$form->addTextArea('content', 'Содержание:')
		->setRequired();

	$form->addSubmit('send', 'Сохранить и опубликовать');
	$form->onSuccess[] = $this->postFormSucceeded(...);

	return $form;
}

Запазване на нова публикация от формуляр

Нека да добавим метод за обработка:

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

	$this->flashMessage('Пост опубликован!', 'success');
	$this->redirect('Post:show', $post->id);
}

Малко обяснение: този метод извлича стойностите от формуляра, вмъква ги в базата данни, създава съобщение за потребителя, че публикацията е била успешно публикувана, и пренасочва към страницата, на която е публикувана публикацията, за да можете да видите как изглежда тя.

Страница за създаване на нова публикация

Нека просто създадем шаблон (app/UI/Edit/create.latte):

{block content}
<h1>Новый пост</h1>

{control postForm}

Всичко вече трябва да е ясно. Последният ред показва формата, която ще създадем.

Бихме могли да създадем и съответен метод renderCreate, но това не е необходимо. Не е необходимо да извличаме данни от базата данни и да ги предаваме на шаблона, така че този метод ще бъде празен. В такива случаи методът може изобщо да не съществува.

Вероятно вече знаете как да добавите връзка към EditPresenter и нейното действие create. Опитайте.

Просто добавете към файла app/UI/Home/default.latte:

<a n:href="Edit:create">Создать пост</a>

Редактиране на публикации

Нека добавим и възможност за редактиране на съществуващи публикации. Това ще бъде съвсем просто – вече имаме postForm, а можем да го използваме и за редактиране.

Ще добавим нова страница edit към EditPresenter:

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

	if (!$post) {
		$this->error('Пост не найден');
	}

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

И създайте шаблон Edit/edit.latte:

{block content}
<h1>Редактирование поста</h1>

{control postForm}

И актуализирайте метода postFormSucceeded, който ще може да добавя нова публикация (както сега) или да редактира съществуващите:

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

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

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

	$this->flashMessage('Пост опубликован', 'success');
	$this->redirect('Post:show', $post->id);
}

Ако е посочен postId, това означава, че публикацията се редактира. В този случай ще проверим дали публикацията действително съществува и ако е така, ще я актуализираме в базата данни. Ако не е посочен postId, това означава, че ще бъде добавена нова публикация.

Но откъде идва postId? Това е параметърът, който се предава на метода renderEdit.

Сега можете да добавите връзка за промяна на публикацията в шаблона app/UI/Post/show.latte:

<a n:href="Edit:edit $post->id">Изменить пост</a>

За да обобщим

Блогът работи, хората бързо коментират и вече не разчитаме на администратора да добавя нови публикации. Блогът е напълно независим и в него могат да публикуват дори обикновени хора. Но чакайте, вероятно не е нормално всеки, имам предвид наистина всеки в интернет, да може да пише в нашия блог. Изисква се някаква форма на удостоверяване, така че само регистрираните потребители да могат да публикуват. Това ще добавим в следващата глава.