Stránka s příspěvkem
Nyní si vytvoříme další stránku blogu, která bude zobrazovat jeden konkrétní příspěvek.
Musíme si vytvořit novou render metodu, která získá jeden konkrétní článek a předá jej do šablony. Mít tuto metodu
v HomePresenter
není moc hezké, protože se bavíme o článku a ne úvodní stránce. Vytvořme si tedy
PostPresenter
v app/UI/Post/
. Tento presenter se také potřebuje připojit k databázi, takže zde
opět napíšeme konstruktor, který bude vyžadovat databázové připojení.
PostPresenter
by mohl tedy vypadat takto:
<?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);
}
}
Nesmíme zapomenout uvést správný namespace App\UI\Post
, který podléhá nastavení mapování presenterů.
Metoda renderShow
vyžaduje jeden argument – ID jednoho konkrétního článku, který má být zobrazen. Poté
tento článek načte z databáze a předá ho do šablony.
Do šablony Home/default.latte
vložíme odkaz na akci Post:show
.
...
<h2><a href="{link Post:show $post->id}">{$post->title}</a></h2>
...
Značka {link}
generuje URL adresu, která směřuje na akci Post:show
. Také předává ID
příspěvku jako argument.
Totéž můžeme zapsat zkráceně pomocí n:atributu:
...
<h2><a n:href="Post:show $post->id">{$post->title}</a></h2>
...
Atribut n:href
je obdobou tagu {link}
.
Pro akci Post:show
však ještě neexistuje šablona. Můžeme si vyzkoušet otevřít odkaz na tento
příspěvek. Tracy zobrazí error, protože šablona Post/show.latte
ještě neexistuje. Pokud vidíte jiné chybové hlášení, tak pravděpodobně budete muset zapnout mod_rewrite
na
webserveru.
Vytvoříme tedy šablonu Post/show.latte
s tímto obsahem:
{block content}
<p><a n:href="Home:default">← zpět na výpis příspěvků</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>
Nyní si projdeme jednotlivé části šablony.
První řádka začíná definici bloku s názvem „content“ stejně jako tomu bylo na úvodní stránce. Tento blok bude
opět zobrazen v hlavní šabloně. Jak vidíte, chybí koncová značka {/block}
. Ta je totiž nepovinná.
Na další řádce je odkaz zpět na výpis článků blogu, takže se uživatel může jednoduše pohybovat mezi výpisem
článků a jedním konkrétním. Protože používáme atribut n:href
, tak se Nette samo postará o generování
odkazů. Odkaz směřuje na akci default
presenteru Home
(můžeme napsat také
n:href="Home:"
, protože akce s názvem default
může být vynechána, doplní se automaticky).
Třetí řádka formátuje výpis data pomocí filtru, který už známe.
Čtvrtá řádka zobrazuje titulek blogu v HTML tagu <h1>
. Tento tag obsahuje atribut, který
možná neznáte (n:block="title"
). Uhodnete, co dělá? Pokud jste četli předchozí část pozorně, tak již
víte, že se jedná o n:atribut
. Toto je jejich další příklad, který je ekvivalentní k:
{block title}<h1>{$post->title}</h1>{/block}
Jednoduše řečeno, tento blok předefinovává blok s názvem title
. Tento blok je již definován v hlavní
layout šabloně (/app/UI/@layout.latte:11
) a tak jako u překrývání metod v OOP, úplně stejně se
tento blok v hlavní šabloně překryje. Takže <title>
stránky nyní obsahuje titulek zobrazeného
příspěvku a stačilo nám k tomu použít pouze jednoho jednoduchého atributu n:block="title"
.
Skvělé, že?
Pátá a poslední řádka šablony zobrazuje celý obsah jednoho konkrétního příspěvku.
Kontrola ID příspěvku
Co se stane, když někdo změní ID v URL a vloží nějaké neexistující id
? Měli bychom uživateli
nabídnout pěknou chybu typu „stránka nebyla nalezena“. Pozměníme tedy trošku render metodu v
PostPresenter
:
public function renderShow(int $id): void
{
$post = $this->database
->table('posts')
->get($id);
if (!$post) {
$this->error('Stránka nebyla nalezena');
}
$this->template->post = $post;
}
Pokud nemůže být příspěvek nalezen, zavoláním $this->error(...)
zobrazíme chybovou stránku 404 se
srozumitelnou hláškou. Pozor na to, že ve vývojářském módu (localhost) tuto chybovou stránku neuvidíte. Místo toho se
ukáže Tracy s detaily o výjimce, což je docela výhodné pro vývoj. Chceme-li si nechat zobrazit oba módy, stačí pouze
změnit argument metody setDebugMode
v souboru Bootstrap.php
.
Shrnutí
Máme databázi s příspěvky a webovou aplikaci, která má dva pohledy – první zobrazuje přehled všech příspěvků a druhá zobrazuje jeden konkrétní příspěvek.