Pagină cu o singură postare
Să adăugăm încă o pagină la blogul nostru, care va afișa conținutul unei anumite postări de pe blog.
Trebuie să creăm o nouă metodă de redare, care va prelua o anumită postare de pe blog și o va transmite șablonului.
A avea această vizualizare în HomePresenter
nu este plăcută, deoarece este vorba despre un articol de blog, nu
despre pagina de start. Așadar, să creăm o nouă clasă PostPresenter
și să o plasăm în
app/UI/Post/
. Aceasta va avea nevoie de o conexiune la baza de date, așa că puneți din nou codul de injecție
în baza de date acolo.
Clasa PostPresenter
ar trebui să arate astfel:
<?php
namespace App\UI\Post;
use Nette;
use Nette\Application\UI\Form;
final class PostPresenter extends Nette\Application\UI\Presenter
{
public function __construct(
private Nette\Database\Explorer $database,
) {
}
public function renderShow(int $id): void
{
$this->template->post = $this->database
->table('posts')
->get($id);
}
}
Trebuie să setăm un namespace corect App\UI\Post
pentru prezentatorul nostru. Depinde de cartografierea prezentatorului.
Metoda renderShow
are nevoie de un singur argument – ID-ul postului care urmează să fie afișat. Apoi,
aceasta încarcă postul din baza de date și transmite rezultatul către șablon.
În șablonul Home/default.latte
adăugăm un link către acțiunea Post:show
:
...
<h2><a href="{link Post:show $post->id}">{$post->title}</a></h2>
...
Eticheta {link}
generează o adresă URL care trimite la acțiunea Post:show
. Această etichetă
transmite, de asemenea, ID-ul mesajului ca argument.
Același lucru îl putem scrie pe scurt folosind n:attribute:
...
<h2><a n:href="Post:show $post->id">{$post->title}</a></h2>
...
Atributul n:href
este similar cu eticheta {link}
.
Șablonul pentru acțiunea Post:show
nu există încă. Putem deschide un link către această postare. Tracy va afișa o eroare, de ce Post/show.latte
nu există. Dacă vedeți
orice alt raport de eroare, probabil că trebuie să activați mod_rewrite în serverul dvs. web.
Deci, vom crea Post/show.latte
cu acest conținut:
{block content}
<p><a n:href="Home:default">← back to posts list</a></p>
<div class="date">{$post->created_at|date:'F j, Y'}</div>
<h1 n:block="title">{$post->title}</h1>
<div class="post">{$post->content}</div>
Să ne uităm la părțile individuale.
Prima linie începe definiția unui bloc cu nume numit “conținut”, pe care l-am văzut mai devreme. Acesta va fi
afișat într-un șablon de prezentare. După cum puteți vedea, lipsește eticheta de sfârșit {/block}
.
Aceasta este opțională.
A doua linie oferă un backlink către lista de articole de pe blog, astfel încât utilizatorul să poată naviga fără
probleme înainte și înapoi pe blogul nostru. Utilizăm din nou atributul n:href
, prin urmare Nette se va ocupa de
generarea URL-ului pentru noi. Legătura indică acțiunea default
din prezentatorul Home
(ați putea
scrie și n:href="Home:"
, deoarece acțiunea default
poate fi omisă).
A treia linie formatează data și ora publicării cu un filtru, așa cum știm deja.
A patra linie afișează titlul postării de pe blog sub forma unui fișier <h1>
titlu. Există
o parte cu care poate nu sunteți familiarizați, și anume n:block="title"
. Puteți ghici ce face? Dacă ați citit
cu atenție părțile anterioare, am menționat n: attributes
. Acesta este un alt exemplu. Este echivalent cu:
{block title}<h1>{$post->title}</h1>{/block}
Cu alte cuvinte, se redefinește un bloc numit title
. Blocul este definit în șablonul de
machetare (/app/UI/@layout.latte:11
) și, ca în cazul suprapunerii OOP, este suprapus aici. Prin urmare, pagina
<title>
va conține titlul articolului afișat. Am suprascris titlul paginii și tot ce aveam nevoie era
n:block="title"
. Grozav, nu?
A cincea și ultima linie a șablonului afișează conținutul complet al postării.
Verificarea ID-ului postului
Ce se întâmplă dacă cineva modifică URL-ul și inserează id
care nu există? Ar trebui să oferim
utilizatorului o eroare frumoasă de tipul “pagina nu a fost găsită”. Să actualizăm metoda de redare din
PostPresenter
:
public function renderShow(int $id): void
{
$post = $this->database
->table('posts')
->get($id);
if (!$post) {
$this->error('Post not found');
}
$this->template->post = $post;
}
Dacă postul nu poate fi găsit, apelarea $this->error(...)
va afișa o pagină 404 cu un mesaj frumos și
ușor de înțeles. Rețineți că, în mediul de dezvoltare (pe laptop), nu veți vedea pagina de eroare. În schimb, Tracy va
afișa excepția cu detalii complete, ceea ce este destul de convenabil pentru dezvoltare. Puteți verifica ambele moduri, doar
schimbați valoarea transmisă la setDebugMode
în Bootstrap.php
.
Rezumat
Avem o bază de date cu postări pe blog și o aplicație web cu două vizualizări – prima afișează rezumatul tuturor postărilor recente, iar cea de-a doua afișează o anumită postare.