Страница за индивидуално вписване

Нека да добавим още една страница към нашия блог, за да покажем съдържанието на един конкретен запис в блога.

Трябва да създадем нов метод за визуализация, който да вземе един конкретен запис в блога и да го предаде на шаблона. Това визуализиране в HomePresenter не е много приятно, защото става дума за запис в блог, а не за начална страница. Така че нека създадем нов клас PostPresenter и да го поставим в app/UI/Post/. Тя ще се нуждае от връзка с база данни, така че поставете отново кода за инжектиране на зависимости* там.

PostPresenter трябва да изглежда по следния начин:

<?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);
	}
}

Трябва да зададем правилното пространство от имена App\UI\Post за нашия презентатор. Това зависи от картографирането на водещия.

Методът renderShow изисква един аргумент – ID на публикацията на водещия. След това той зарежда тази публикация от базата данни и предава резултата на шаблона.

В шаблона Home/default.latte добавяме връзка към действието Post:show:

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

Тагът {link} генерира URL адрес, който насочва към действието Post:show. Този таг също така предава идентификатора на публикацията като аргумент.

Можем да напишем същото накратко, като използваме n:attribute:

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

Атрибутът n:href е подобен на тага {link}.

Шаблонът за действието Post:show все още не съществува. Можем да отворим връзка към тази публикация. Tracy ще покаже грешка, че app/UI/Post/show.latte не съществува. Ако видите друг отчет за грешка, вероятно трябва да активирате mod_rewrite на уеб сървъра си.

Затова ще създадем Post/show.latte с това съдържание:

{block content}

<p><a n:href="Home:default">← вернуться к списку постов</a></p>

<div class="date">{$post->created_at|date:'j.m.Y'}</div>

<h1 n:block="title">{$post->title}</h1>

<div class="post">{$post->content}</div>

Обмислете някои точки.

Първият ред започва дефиницията на именния блок, наречен content, който видяхме по-рано. Той ще се появи в шаблона на разположението.

Вторият ред съдържа обратна връзка към списъка с публикации в блога, така че потребителят да може да навигира плавно напред-назад из нашия блог. Отново използваме атрибута n:href, така че Nette ще се погрижи да генерира URL адреса вместо нас. Връзката сочи към действието default на водещия Home (може да напишете просто n:href="Home:", тъй като действието default може да бъде пропуснато).

Третият ред форматира времевия печат на публикацията, като използва филтъра date, както вече знаем.

Четвъртият ред показва заглавието на записа в блога като заглавие <h1>. Има една част, която може би не познавате, а именно n:block="title". Можете ли да познаете какво прави? Ако сте прочели внимателно предишните части, споменахме n: атрибуты. Ето още един пример. Това е равносилно на:

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

Просто казано, той заменя блок, наречен title. Блокът е дефиниран в шаблона за оформление (/app/UI/@layout.latte:11) и, както в случая на пренаписване на ООП, се пренаписва тук. Следователно <title> страници ще съдържа заглавието на показаната публикация. Премахнахме заглавието на страницата и всичко, от което се нуждаехме, беше n:block="title". Чудесно, нали?

Петият и последен ред на шаблона показва пълното съдържание на публикацията ви.

Проверка на ID на публикацията

Какво ще стане, ако някой промени URL адреса и вмъкне несъществуващ postId? Трябва да предоставим на потребителя хубава страница за грешка “Страницата не е намерена”. Нека да актуализираме метода render във файла PostPresenter.php:

public function renderShow(int $id): void
{
	$post = $this->database
		->table('posts')
		->get($id);
	if (!$post) {
		$this->error('Страница не найдена!');
	}

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

Ако публикацията не може да бъде намерена, при извикване на $this->error(...) ще се покаже страница 404 с хубаво и ясно съобщение. Обърнете внимание, че в режим на разработка няма да видите страницата за грешки. Вместо това Трейси ще покаже изключение с пълна информация, което е доста удобно за разработка. Можете да проверите и двата режима, като просто промените стойността, подадена на setDebugMode в Bootstrap.php.

За да обобщим

Имаме база данни с вписвания в блога и уеб приложение с два изгледа: първият показва обобщение на всички скорошни вписвания, а вторият – едно конкретно вписване.