Страница отдельной записи
Давайте добавим в наш блог еще одну страницу, на которой будет отображаться содержимое одной конкретной записи блога.
Нам нужно создать новый метод render, который будет получать одну
конкретную запись блога и передавать её в шаблон. Иметь это
представление в HomePresenter
не очень приятно, потому что речь идёт о
записи в блоге, а не о главной странице. Итак, давайте создадим новый
класс PostPresenter
и поместим его в app/Presentation/Post/
. Ему
потребуется соединение с базой данных, поэтому снова поместите туда
код внедрения зависимости.
PostPresenter
должен выглядеть следующим образом:
Мы должны установить правильное пространство имен
App\Presentation\Post
для нашего презентера. Это зависит от presenter mapping.
Метод renderShow
требует один аргумент — ID отображаемого поста.
Затем он загружает этот пост из базы данных и передает результат в
шаблон.
В шаблоне Home/default.latte
мы добавляем ссылку на действие
Post:show
:
Тег {link}
генерирует адрес URL, который указывает на действие
Post:show
. Этот тег также передает ID поста в качестве аргумента.
То же самое мы можем написать коротко, используя n:attribute:
Атрибут n:href
аналогичен тегу {link}
.
Шаблон для действия Post:show
ещё не существует. Мы можем открыть
ссылку на этот пост. Tracy покажет ошибку о том, что
app/Presentation/Post/show.latte
не существует. Если вы видите любой другой
отчёт об ошибке, вероятно, вам нужно включить mod_rewrite в вашем
веб-сервере.
Поэтому мы создадим Post/show.latte
с таким содержанием:
Рассмотрим некоторые моменты.
Первая строка начинает определение именованного блока под
названием content
, которые мы видели ранее. Он будет отображаться в
шаблоне макета.
Вторая строка содержит обратную ссылку на список постов блога, чтобы
пользователь мог плавно перемещаться по нашему блогу вперед и назад.
Мы снова используем атрибут n:href
, поэтому Nette позаботится о
генерации URL для нас. Ссылка указывает на действие default
презентера Home
(можно просто написать n:href="Home:"
, так как
действие default
может быть опущено).
Третья строка форматирует временную метку публикации с помощью
фильтра date
, как мы уже знаем.
Четвертая строка отображает заголовок записи блога в виде
заголовка <h1>
. Есть часть, с которой вы, возможно, не знакомы,
это n:block="title"
. Можете ли вы догадаться, что она делает? Если вы
внимательно читали предыдущие части, мы упоминали n: атрибуты
.
Вот ещё один пример. Это эквивалентно:
Проще говоря, он переопределяет блок под названием title
.
Блок определен в шаблоне макета (/app/Presentation/@layout.latte:11
) и, как
и в случае с переопределением ООП, он переопределяется здесь. Поэтому
<title>
страницы будет содержать заголовок отображаемого
поста. Мы переопределили заголовок страницы, и всё, что нам было нужно,
это n:block="title"
. Здорово, да?
Пятая и последняя строка шаблона отображает полное содержание вашего поста.
Проверка идентификатора поста
Что произойдет, если кто-то изменит URL и вставит несуществующий
id
? Мы должны предоставить пользователю красивую страницу
ошибки «страница не найдена». Давайте обновим метод render
в файле
PostPresenter.php
:
Если пост не может быть найден, вызов $this->error(...)
покажет
страницу 404 с красивым и понятным сообщением. Обратите внимание, что в
режиме разработки вы не увидите страницу ошибки. Вместо этого Tracy
покажет исключение с полной информацией, что довольно удобно для
разработки. Вы можете проверить оба режима, просто изменив значение,
передаваемое в setDebugMode
в Bootstrap.php
.
Подведём итог
У нас есть база данных с записями блога и веб-приложение с двумя представлениями: первое отображает сводку всех последних записей, а второе — одну конкретную запись.