Megjegyzések
A blogot beüzemeltük, írtunk néhány nagyon jó blogbejegyzést és közzétettük őket az Adminer-en keresztül. Az emberek olvassák a blogot, és nagyon lelkesek az ötleteink iránt. Naponta sok dicsérő e-mailt kapunk. De mire jó ez a sok dicséret, ha csak e-mailben kaptuk meg, így senki más nem tudja elolvasni? Nem lenne jobb, ha az emberek közvetlenül a blogon tudnának hozzászólni, hogy mindenki más is olvashassa, milyen nagyszerűek vagyunk?
Tegyük az összes cikket kommentelhetővé.
Új táblázat létrehozása
Indítsa el újra az Adminer programot, és hozzon létre egy új táblát comments
néven ezekkel az
oszlopokkal:
id
int, check autoincrement (AI)post_id
, idegen kulcs, amely aposts
táblára hivatkozik.name
varchar, hossza 255email
varchar, hossza 255content
textcreated_at
timestamp
Így kell kinéznie:
Ne felejtsd el használni az InnoDB tábla tárolását, és nyomd meg a Mentés gombot.
CREATE TABLE `comments` (
`id` int NOT NULL AUTO_INCREMENT PRIMARY KEY,
`post_id` int(11) NOT NULL,
`name` varchar(250) NOT NULL,
`email` varchar(250) NOT NULL,
`content` text NOT NULL,
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (`post_id`) REFERENCES `posts` (`id`)
) ENGINE=InnoDB CHARSET=utf8;
Formanyomtatvány a hozzászóláshoz
Először is létre kell hoznunk egy űrlapot, amely lehetővé teszi a felhasználók számára, hogy hozzászóljanak az oldalunkhoz. A Nette Framework fantasztikusan támogatja az űrlapokat. Ezeket egy prezenterben lehet konfigurálni és egy sablonban megjeleníteni.
A Nette Framework rendelkezik a komponensek fogalmával. A komponens egy újrafelhasználható osztály vagy
kódrészlet, amely egy másik komponenshez csatolható. Még a prezenter is egy komponens. Minden komponens a komponens gyár
segítségével jön létre. Definiáljuk tehát a PostPresenter
oldalon a comments form factory-t .
protected function createComponentCommentForm(): Form
{
$form = new Form; // jelentése: Nette\Application\UI\Form
$form->addText('name', 'Az Ön neve:')
->setRequired();
$form->addEmail('email', 'Email:');
$form->addTextArea('content', 'Megjegyzés:')
->setRequired();
$form->addSubmit('send', 'Publish comment');
return $form;
}
Magyarázzuk el egy kicsit. Az első sor létrehoz egy új példányt a Form
komponensből. A következő
metódusok HTML-bemeneteket csatolnak az űrlap definíciójához. ->addText
a következő formában jelenik meg
<input type=text name=name>
, a <label>Your name:</label>
. Ahogy már most
kitalálhattad, a ->addTextArea
csatol egy <textarea>
és a ->addSubmit
hozzáad egy <input type=submit>
. Több ilyen módszer is van, de most csak ennyit kell tudnod. Többet megtudhatsz a dokumentációban.
Miután az űrlapkomponens definiálva van egy prezenterben, megjeleníthetjük (megjeleníthetjük) egy sablonban. Ehhez
helyezze a {control}
címkét a poszt részlet sablonjának végére, a Post/show.latte
. Mivel a
komponens neve commentForm
(a createComponentCommentForm
metódus nevéből származik), a címke így
fog kinézni
...
<h2>Post new comment</h2>
{control commentForm}
Most, ha megnézzük valamelyik bejegyzés részletét, egy új űrlapot fogunk találni a hozzászólások írásához.
Mentés az adatbázisba
Próbált már adatokat elküldeni? Bizonyára észrevette, hogy az űrlap nem hajt végre semmilyen műveletet. Csak ott van, jól néz ki, de nem csinál semmit. Egy callback metódust kell hozzá csatolnunk, amely elmenti a beküldött adatokat.
Helyezzük a következő sort a return
sor elé a commentForm
komponens gyárában:
$form->onSuccess[] = $this->commentFormSucceeded(...);
Ez azt jelenti, hogy “az űrlap sikeres elküldése után hívja meg az aktuális prezenter commentFormSucceeded
metódusát”. Ez a metódus még nem létezik, ezért hozzuk létre.
private function commentFormSucceeded(\stdClass $data): void
{
$id = $this->getParameter('id');
$this->database->table('comments')->insert([
'post_id' => $id,
'name' => $data->name,
'email' => $data->email,
'content' => $data->content,
]);
$this->flashMessage('Thank you for your comment', 'success');
$this->redirect('this');
}
Rögtön a commentForm
komponensgyár után kell elhelyeznünk.
Az új metódusnak egy argumentuma van, ami a beküldendő űrlap példánya, amelyet a komponensgyár hozott létre.
A benyújtott értékeket a $data
címen kapjuk meg. Ezután pedig beszúrjuk az adatokat az comments
adatbázis táblába.
Még két metódushívást kell elmagyarázni. A redirect szó szerint átirányít az aktuális oldalra. Ezt minden
alkalommal meg kell tennünk, amikor az űrlapot elküldtük, érvényes, és a callback művelet megtette, amit kellett volna.
Továbbá, ha az űrlap elküldése után átirányítod az oldalt, nem fogod látni a jól ismert
Would you like to submit the post data again?
üzenetet, amelyet néha láthatsz a böngészőben.
(Általánosságban elmondható, hogy egy űrlap POST
módszerrel történő elküldése után mindig át kell
irányítania a felhasználót a GET
műveletre).
A flashMessage
arra szolgál, hogy tájékoztassa a felhasználót valamilyen művelet eredményéről. Mivel
átirányítunk, az üzenetet nem lehet közvetlenül a sablonhoz átadni és megjeleníteni. Ezért van ez a metódus, amely
tárolja és a következő oldalbetöltéskor elérhetővé teszi. A flash üzeneteket az alapértelmezett
app/UI/@layout.latte
fájlban rendereljük, és ez így néz ki:
<div n:foreach="$flashes as $flash" n:class="flash, $flash->type">
{$flash->message}
</div>
Mint már tudjuk, automatikusan átkerülnek a sablonba, így nem kell sokat gondolkodni rajta, egyszerűen csak működik. További részletekért nézd meg a dokumentációt.
A megjegyzések megjelenítése
Ez az egyik olyan dolog, amit egyszerűen imádni fogsz. A Nette adatbázisnak van ez a menő funkciója, amit úgy hívnak, hogy Explorer. Emlékszel, hogy a táblákat InnoDB-ként hoztuk létre? Az Adminer létrehozta az úgynevezett idegen kulcsokat, amelyek rengeteg munkát takarítanak meg nekünk.
A Nette Database Explorer az idegen kulcsokat használja a táblák közötti kapcsolatok feloldására, és a kapcsolatok ismeretében automatikusan lekérdezéseket tud létrehozni számodra.
Mint emlékezhetsz, a $post
változót átadtuk a sablonban a PostPresenter::renderShow()
, és most
szeretnénk végigmenni az összes olyan megjegyzésen, amelynek a post_id
oszlopa megegyezik a mi
$post->id
-unkkal . Ezt a $post->related('comments')
meghívásával teheti meg. Ez ilyen
egyszerű. Nézze meg a kapott kódot.
public function renderShow(int $id): void
{
...
$this->template->post = $post;
$this->template->comments = $post->related('comments')->order('created_at');
}
És a sablont:
...
<h2>Comments</h2>
<div class="comments">
{foreach $comments as $comment}
<p><b><a href="mailto:{$comment->email}" n:tag-if="$comment->email">
{$comment->name}
</a></b> said:</p>
<div>{$comment->content}</div>
{/foreach}
</div>
...
Figyeljük meg a speciális n:tag-if
attribútumot. Már tudod, hogyan működik a n: attributes
.
Nos, ha az attribútum elé a tag-
attribútumot írja, az csak a címkéket fogja körbeölelni, a tartalmukat nem.
Ez lehetővé teszi, hogy a hozzászóló nevét linkké alakítsa, ha megadta az e-mail címét. Ez a két sor azonos
eredményt ad:
<strong n:tag-if="$important"> Hello there! </strong>
{if $important}<strong>{/if} Hello there! {if $important}</strong>{/if}