Створення та редагування дописів
Це чудово! У нас є супер крутий новий блог, люди активно обговорюють у коментарях, і у нас нарешті є трохи часу на подальше програмування. Хоча Adminer — чудовий інструмент, він не зовсім ідеальний для написання нових дописів у блозі. Мабуть, настав час створити просту форму для додавання нових дописів безпосередньо з застосунку. Давайте зробимо це.
Почнемо з проектування користувацького інтерфейсу:
- На головній сторінці додамо посилання “Написати новий допис”.
- Це посилання відобразить форму із заголовком та текстовим полем для вмісту допису.
- Коли ми натиснемо кнопку Зберегти, допис збережеться в базу даних.
Пізніше ми також додамо вхід і дозволимо додавати дописи лише залогіненим користувачам. Але це пізніше. Який код нам потрібно написати зараз, щоб усе працювало?
- Створимо новий presenter з формою для додавання дописів.
- Визначимо callback, який запуститься після успішного надсилання форми та збереже новий допис у базу даних.
- Створимо новий шаблон, на якому буде ця форма.
- Додамо посилання на форму в шаблон головної сторінки.
Новий presenter
Новий presenter назвемо EditPresenter
і збережемо в app/Presentation/Edit/
.
Йому також потрібно підключитися до бази даних, тому ми знову напишемо
конструктор, який вимагатиме підключення до бази даних:
<?php
namespace App\Presentation\Edit;
use Nette;
use Nette\Application\UI\Form;
final class EditPresenter extends Nette\Application\UI\Presenter
{
public function __construct(
private Nette\Database\Explorer $database,
) {
}
}
Форма для збереження дописів
Форми та компоненти ми вже пояснювали при створенні коментарів. Якщо це все ще незрозуміло, перегляньте створення форм та компонентів, ми поки що зачекаємо тут ;)
Тепер додамо цей метод до presenter'а 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);
}
Лише короткий підсумок: цей метод отримує дані з форми, вставляє їх у базу даних, створює повідомлення для користувача про успішне збереження допису та перенаправляє на сторінку з новим дописом, щоб ми одразу побачили, як він виглядає.
Сторінка для створення нового допису
Тепер створимо шаблон Edit/create.latte
:
{block content}
<h1>Новий допис</h1>
{control postForm}
Все вже має бути зрозуміло. Останній рядок відображає форму, яку ми створили.
Ми могли б створити також відповідний метод renderCreate
, але це не
обов'язково. Нам не потрібно отримувати жодних даних з бази даних і
передавати їх у шаблон, тому цей метод був би порожнім. У таких випадках
метод може взагалі не існувати.
Посилання на створення дописів
Ви, мабуть, уже знаєте, як додати посилання на EditPresenter
та його
дію create
. Спробуйте зробити це.
Достатньо додати до файлу app/Presentation/Home/default.latte
:
<a n:href="Edit:create">Написати новий допис</a>
Редагування дописів
Тепер додамо також можливість редагування допису. Це буде дуже
просто. У нас вже є готова форма postForm
, і ми можемо
використовувати її також для редагування.
Додамо нову сторінку edit
до presenter'а EditPresenter
:
public function renderEdit(int $id): void
{
$post = $this->database
->table('posts')
->get($id);
if (!$post) {
$this->error('Допис не знайдено'); // Translate string
}
$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/Presentation/Post/show.latte
:
<a n:href="Edit:edit $post->id">Редагувати допис</a>
Підсумок
Блог тепер функціонує, відвідувачі активно коментують його, і нам більше не потрібен Adminer для публікації. Застосунок повністю незалежний, і будь-хто може додати новий допис. Зачекайте, це, мабуть, не зовсім правильно, що будь-хто — і я маю на увазі справді будь-кого з доступом до Інтернету — може додавати нові дописи. Потрібна якась безпека, щоб новий допис міг додати лише залогінений користувач. Про це ми поговоримо в наступному розділі.