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