Bejegyzés oldala

Most létrehozunk egy másik blogoldalt, amely egy konkrét bejegyzést fog megjeleníteni.

Létre kell hoznunk egy új render metódust, amely lekér egy konkrét cikket, és átadja a sablonnak. Ennek a metódusnak a HomePresenter-ben való elhelyezése nem túl szép, mivel egy cikkről beszélünk, nem a kezdőlapról. Hozzunk létre tehát egy PostPresenter-t az app/Presentation/Post/-ban. Ennek a presenternek is csatlakoznia kell az adatbázishoz, ezért itt is írunk egy konstruktort, amely adatbázis-kapcsolatot igényel.

A PostPresenter tehát így nézhet ki:

<?php
namespace App\Presentation\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);
	}
}

Nem szabad elfelejtenünk megadni a helyes App\Presentation\Post névteret, amely a presenter leképezés beállításainak van alárendelve.

A renderShow metódus egy argumentumot igényel – egy konkrét cikk azonosítóját, amelyet meg kell jeleníteni. Ezután betölti ezt a cikket az adatbázisból, és átadja a sablonnak.

A Home/default.latte sablonba beillesztünk egy linket a Post:show akcióra.

...
<h2><a href="{link Post:show $post->id}">{$post->title}</a></h2>
...

A {link} tag egy URL címet generál, amely a Post:show akcióra mutat. Átadja a bejegyzés azonosítóját is argumentumként.

Ugyanezt rövidebben is leírhatjuk egy n:attribútum segítségével:

...
<h2><a n:href="Post:show $post->id">{$post->title}</a></h2>
...

Az n:href attribútum a {link} tag megfelelője.

A Post:show akcióhoz azonban még nem létezik sablon. Kipróbálhatjuk megnyitni a linket ehhez a bejegyzéshez. A Tracy hibát fog megjeleníteni, mert a Post/show.latte sablon még nem létezik. Ha más hibaüzenetet lát, valószínűleg engedélyeznie kell a mod_rewrite-ot a webszerveren.

Hozzunk létre tehát egy Post/show.latte sablont ezzel a tartalommal:

{block content}

<p><a n:href="Home:default">← vissza a bejegyzések listájához</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>

Most nézzük át a sablon egyes részeit.

Az első sor a “content” nevű blokk definíciójával kezdődik, ugyanúgy, mint a kezdőlapon. Ez a blokk ismét a fő sablonban lesz megjelenítve. Ahogy láthatja, hiányzik a {/block} záró tag. Ez ugyanis nem kötelező.

A következő sorban egy link található vissza a blogbejegyzések listájához, így a felhasználó egyszerűen mozoghat a cikkek listája és egy konkrét cikk között. Mivel az n:href attribútumot használjuk, a Nette maga gondoskodik a linkek generálásáról. A link a Home presenter default akciójára mutat (írhatjuk úgy is, hogy n:href="Home:", mert a default nevű akció elhagyható, automatikusan kiegészül).

A harmadik sor formázza a dátum kiírását a már ismert szűrő segítségével.

A negyedik sor a blog címsorát jeleníti meg a <h1> HTML tagben. Ez a tag tartalmaz egy attribútumot, amelyet talán nem ismer (n:block="title"). Kitalálja, mit csinál? Ha figyelmesen olvasta az előző részt, akkor már tudja, hogy ez egy n:atribut. Ez egy másik példa rájuk, amely ekvivalens ezzel:

{block title}<h1>{$post->title}</h1>{/block}

Egyszerűen fogalmazva, ez a blokk újradefiniálja a title nevű blokkot. Ez a blokk már definiálva van a fő layout sablonban (/app/Presentation/@layout.latte:11), és ahogy az OOP metódusok felülírásánál, ugyanúgy ez a blokk a fő sablonban felülíródik. Tehát az oldal <title>-je most a megjelenített bejegyzés címsorát tartalmazza, és ehhez csak egy egyszerű n:block="title" attribútumot kellett használnunk. Nagyszerű, ugye?

A sablon ötödik és utolsó sora egy konkrét bejegyzés teljes tartalmát jeleníti meg.

Bejegyzésazonosító ellenőrzése

Mi történik, ha valaki megváltoztatja az azonosítót az URL-ben, és beilleszt egy nem létező id-t? Egy szép “oldal nem található” típusú hibát kellene felajánlanunk a felhasználónak. Módosítsuk tehát egy kicsit a render metódust a PostPresenter-ben:

public function renderShow(int $id): void
{
	$post = $this->database
		->table('posts')
		->get($id);
	if (!$post) {
		$this->error('Az oldal nem található');
	}

	$this->template->post = $post;
}

Ha a bejegyzés nem található, a $this->error(...) hívásával egy 404-es hibaoldalt jelenítünk meg érthető üzenettel. Figyeljen arra, hogy fejlesztői módban (localhost) ezt a hibaoldalt nem fogja látni. Helyette a Tracy jelenik meg a kivétel részleteivel, ami elég előnyös a fejlesztéshez. Ha mindkét módot meg akarjuk jeleníteni, csak meg kell változtatnunk a setDebugMode metódus argumentumát a Bootstrap.php fájlban.

Összegzés

Van egy adatbázisunk bejegyzésekkel és egy webalkalmazásunk, amelynek két nézete van – az első az összes bejegyzés áttekintését mutatja, a második pedig egy konkrét bejegyzést.