Stran z eno objavo
Dodajmo še eno stran na naš blog, ki bo prikazovala vsebino ene posamezne objave.
Ustvariti moramo novo metodo izrisa, ki bo pobrala eno določeno objavo na blogu in jo posredovala predlogi. Imeti ta pogled
v naslovu HomePresenter
ni lepo, saj gre za blogovsko objavo in ne za domačo stran. Zato ustvarimo nov razred
PostPresenter
in ga postavimo v app/UI/Post/
. Potreboval bo povezavo s podatkovno bazo, zato tja
ponovno postavimo kodo database injection.
Razred PostPresenter
naj bo videti takole:
<?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);
}
}
Nastaviti moramo pravilen imenski prostor App\UI\Post
za našega predstavnika. To je odvisno od preslikave predstavnika.
Metoda renderShow
zahteva en argument – ID prispevka, ki ga je treba prikazati. Nato objavo naloži iz
podatkovne zbirke in rezultat posreduje predlogi.
V predlogi Home/default.latte
dodamo povezavo do akcije Post:show
:
...
<h2><a href="{link Post:show $post->id}">{$post->title}</a></h2>
...
Oznaka {link}
ustvari naslov URL, ki kaže na akcijo Post:show
. Ta oznaka kot argument posreduje tudi
ID objave.
Enako lahko na kratko zapišemo z uporabo atributa n:attribute:
...
<h2><a n:href="Post:show $post->id">{$post->title}</a></h2>
...
Atribut n:href
je podoben oznaki {link}
.
Predloga za akcijo Post:show
še ne obstaja. Odpremo lahko povezavo do tega prispevka. Tracy bo prikazal napako, zakaj Post/show.latte
ne obstaja. Če se prikaže
katero koli drugo poročilo o napaki, morate v spletnem strežniku verjetno vklopiti mod_rewrite.
Tako bomo ustvarili spletno stran Post/show.latte
s to vsebino:
{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>
Oglejmo si posamezne dele.
V prvi vrstici se začne opredelitev poimenovanega bloka z imenom „content“, ki smo ga videli prej. Prikazan bo
v šabloni za postavitev. Kot lahko vidite, manjka končna oznaka {/block}
. Ta je neobvezna.
Druga vrstica zagotavlja povratno povezavo na seznam blogovskih objav, tako da se lahko uporabnik nemoteno pomika naprej in
nazaj po našem blogu. Ponovno uporabimo atribut n:href
, zato bo Nette poskrbel za generiranje naslova URL namesto
nas. Povezava kaže na akcijo default
predstavnika Home
(lahko zapišete tudi
n:href="Home:"
, saj lahko akcijo default
izpustite).
Tretja vrstica oblikuje časovni žig objave s filtrom, kot že vemo.
Četrta vrstica prikaže naslov prispevka na blogu kot <h1>
naslov. Obstaja del, ki vam morda ni
znan, in sicer n:block="title"
. Ali lahko uganete, kaj počne? Če ste pozorno prebrali prejšnje dele, smo omenili
n: attributes
. To je še en primer. Enakovreden je:
{block title}<h1>{$post->title}</h1>{/block}
Preprosto povedano, na novo definira blok z imenom title
. Blok je opredeljen v šabloni za
postavitev (/app/UI/@layout.latte:11
) in tako kot pri OOP overriding, je tudi tukaj prepisan. Zato se na strani
<title>
bo vsebovala naslov prikazane objave. Prekrili smo naslov strani in vse, kar smo potrebovali, je bilo
n:block="title"
. Super, kajne?
V peti in zadnji vrstici predloge je prikazana celotna vsebina vašega prispevka.
Preverjanje ID objave
Kaj se zgodi, če nekdo spremeni naslov URL in vstavi id
, ki ne obstaja? Uporabniku moramo zagotoviti lepo napako
„stran ni bila najdena“. Posodobimo metodo upodabljanja v 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;
}
Če objave ni mogoče najti, bo klic $this->error(...)
prikazal stran 404 z lepim in razumljivim sporočilom.
Upoštevajte, da v razvojnem okolju (na prenosnem računalniku) ne boste videli strani z napako. Namesto tega bo Tracy prikazal
izjemo z vsemi podrobnostmi, kar je precej priročno za razvoj. Preverite lahko oba načina, samo spremenite vrednost, ki jo
posredujete setDebugMode
v Bootstrap.php
.
Povzetek
Imamo podatkovno zbirko z objavami na blogu in spletno aplikacijo z dvema pogledoma – prvi prikazuje povzetek vseh zadnjih objav, drugi pa eno določeno objavo.