Tworzenie i edycja postów
To świetnie! Mamy super fajnego nowego bloga, ludzie zawzięcie dyskutują w komentarzach, a my mamy wreszcie trochę czasu na dalsze programowanie. Chociaż Adminer jest świetnym narzędziem, nie jest do końca idealny do pisania nowych postów na blogu. Najwyraźniej nadszedł właściwy czas na stworzenie prostego formularza do dodawania nowych postów bezpośrednio z aplikacji. Zróbmy to.
Zacznijmy od zaprojektowania interfejsu użytkownika:
- Na stronie głównej dodamy link “Napisz nowy post”.
- Ten link wyświetli formularz z tytułem i polem tekstowym na treść posta.
- Gdy klikniemy przycisk Zapisz, post zostanie zapisany w bazie danych.
Później dodamy również logowanie i dodawanie postów umożliwimy tylko zalogowanym użytkownikom. Ale to później. Jaki kod musimy napisać teraz, aby wszystko działało?
- Stworzymy nowy presenter z formularzem do dodawania postów.
- Zdefiniujemy callback, który uruchomi się po pomyślnym wysłaniu formularza i który zapisze nowy post do bazy danych.
- Stworzymy nowy szablon, na którym będzie ten formularz.
- Dodamy link do formularza w szablonie strony głównej.
Nowy presenter
Nowy presenter nazwiemy EditPresenter
i zapiszemy w app/Presentation/Edit/
. Musi on również
połączyć się z bazą danych, więc ponownie napiszemy konstruktor, który będzie wymagał połączenia z bazą danych:
<?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,
) {
}
}
Formularz do zapisywania postów
Formularze i komponenty wyjaśniliśmy już przy tworzeniu komentarzy. Jeśli nadal nie jest to jasne, przejdź do tworzenia formularzy i komponentów, my tu poczekamy ;)
Teraz dodajmy tę metodę do presentera EditPresenter
:
protected function createComponentPostForm(): Form
{
$form = new Form;
$form->addText('title', 'Tytuł:')
->setRequired();
$form->addTextArea('content', 'Treść:')
->setRequired();
$form->addSubmit('send', 'Zapisz i opublikuj');
$form->onSuccess[] = $this->postFormSucceeded(...);
return $form;
}
Zapisywanie nowego postu z formularza
Kontynuujemy dodaniem metody, która przetworzy dane z formularza:
private function postFormSucceeded(array $data): void
{
$post = $this->database
->table('posts')
->insert($data);
$this->flashMessage("Post został pomyślnie opublikowany.", 'success');
$this->redirect('Post:show', $post->id);
}
Tylko szybkie podsumowanie: ta metoda pobiera dane z formularza, wstawia je do bazy danych, tworzy wiadomość dla użytkownika o pomyślnym zapisaniu posta i przekierowuje na stronę z nowym postem, dzięki czemu od razu zobaczymy, jak wygląda.
Strona do tworzenia nowego postu
Stwórzmy teraz szablon Edit/create.latte
:
{block content}
<h1>Nowy post</h1>
{control postForm}
Wszystko powinno być już jasne. Ostatnia linia renderuje formularz, który stworzyliśmy w poprzednim kroku.
Moglibyśmy również stworzyć odpowiednią metodę renderCreate()
, ale nie jest to konieczne. Nie potrzebujemy
pobierać żadnych danych z bazy danych i przekazywać ich do szablonu, więc ta metoda byłaby pusta. W takich przypadkach
metoda w ogóle nie musi istnieć.
Link do tworzenia postów
Prawdopodobnie już wiesz, jak dodać link do EditPresenter
i jego akcji create
. Spróbuj to
zrobić.
Wystarczy do pliku app/Presentation/Home/default.latte
dodać:
<a n:href="Edit:create">Napisz nowy post</a>
Edycja postów
Teraz dodamy również możliwość edycji posta. Będzie to bardzo proste. Mamy już gotowy formularz postForm
i możemy go użyć również do edycji.
Dodamy nową stronę edit
do presentera EditPresenter
:
public function renderEdit(int $id): void
{
$post = $this->database
->table('posts')
->get($id);
if (!$post) {
$this->error('Post not found');
}
$this->getComponent('postForm')
->setDefaults($post->toArray());
}
I stworzymy kolejny szablon Edit/edit.latte
:
{block content}
<h1>Edytuj post</h1>
{control postForm}
Zmodyfikujemy metodę postFormSucceeded()
, która będzie mogła zarówno dodać nowy artykuł (tak jak robi to
teraz), jak i edytować już istniejący artykuł:
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('Post został pomyślnie opublikowany.', 'success');
$this->redirect('Post:show', $post->id);
}
Jeśli parametr id
jest dostępny, oznacza to, że będziemy edytować post. W tym przypadku sprawdzimy, czy
żądany post naprawdę istnieje, a jeśli tak, zaktualizujemy go w bazie danych. Jeśli parametr id
nie jest
dostępny, oznacza to, że powinien zostać dodany nowy post.
Skąd jednak weźmie się ten parametr id
? Jest to parametr, który został przekazany do metody
renderEdit
.
Teraz możemy dodać link do szablonu app/Presentation/Post/show.latte
:
<a n:href="Edit:edit $post->id">Edytuj post</a>
Podsumowanie
Blog jest teraz funkcjonalny, odwiedzający aktywnie go komentują, a my już nie potrzebujemy Adminera do publikacji. Aplikacja jest w pełni niezależna i każdy może dodać nowy post. Chwila, to chyba nie jest do końca w porządku, że ktokolwiek – i mam na myśli naprawdę ktokolwiek z dostępem do internetu – może dodawać nowe posty. Potrzebne jest jakieś zabezpieczenie, aby nowy post mógł dodać tylko zalogowany użytkownik. Zajmiemy się tym w następnym rozdziale.