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

Какво страхотно време. Имаме супер готин нов блог, хората спорят в коментарите и най-накрая имаме време за програмиране. Въпреки че обичаме 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>

За да обобщим

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