Създаване и редактиране на публикации
Това е страхотно! Имаме супер готин нов блог, хората усилено дискутират в коментарите и най-накрая имаме малко време за още програмиране. Въпреки че 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('Публикацията не е намерена');
}
$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 за публикуване. Приложението е напълно независимо и всеки може да добави нова публикация. Но почакайте, това вероятно не е съвсем наред, че всеки – и имам предвид наистина всеки с достъп до интернет – може да добавя нови публикации. Необходима е някаква защита, така че само влезлият потребител да може да добави нова публикация. Ще разгледаме това в следващата глава.