Создание и редактирование постов
Какое замечательное время. У нас появился новый суперкрутой блог, люди спорят в комментариях, и у нас наконец-то появилось время для программирования. Хотя нам нравится Adminer, писать в нем статьи для блога не очень удобно. Возможно, сейчас самое время добавить простую форму для добавления новых постов прямо из нашего приложения. Давайте сделаем это.
Начнём с разработки пользовательского интерфейса:
- На главной странице добавим ссылку «Написать новый пост».
- Она отобразит форму с заголовком и текстовой областью для содержимого.
- Когда вы нажмете кнопку «Сохранить», она сохранит запись в блоге.
Позже мы также добавим аутентификацию и разрешим добавлять новые сообщения только вошедшим в систему пользователям. Какой код нам нужно написать, чтобы он работал?
- Создайте новый презентер с формой для добавления постов.
- Определите обратный вызов, который будет срабатывать после успешной отправки формы и который сохранит новое сообщение в базе данных.
- Создайте новый шаблон для формы.
- Добавьте ссылку на форму в шаблон главной страницы.
Новый презентер
Назовите новый презентер 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 $id): void
{
$post = $this->database
->table('posts')
->get($id);
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
{
$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('Пост опубликован', 'success');
$this->redirect('Post:show', $post->id);
}
Если указан параметр id
, это означает, что пост редактируется. В
этом случае мы проверим, действительно ли пост существует, и если да, то
обновим его в базе данных. Если id
не указан, это означает, что
будет добавлен новый пост.
Но откуда берется id
? Это параметр, передаваемый методу
renderEdit
.
Теперь вы можете добавить ссылку для изменения поста в шаблон
app/UI/Post/show.latte
:
<a n:href="Edit:edit $post->id">Изменить пост</a>
Подведём итог
Блог работает, люди быстро комментируют, и мы больше не полагаемся на Админа для добавления новых постов. Блог полностью независим, и даже обычные люди могут размещать там свои сообщения. Но подождите, это, наверное, не нормально, что любой, я имею в виду действительно любой человек в Интернете, может написать в нашем блоге. Требуется определенная форма аутентификации, чтобы только вошедшие в систему пользователи могли размещать сообщения. Мы добавим это в следующей главе.