Страница записи

Страница записи

Давайте добавим еще одну страницу в наше приложение, на которой будет отображаться содержимое одной конкретной записи.

Нам нужно создать новый метод, который будет извлекать одну запись и передавать ее в шаблон. Так как работаем с блогом, а не с главной страницей, распологать этот метод в HomepagePresenter не очень хорошо. Создадим новый класс PostPresenter который будет распологаться в файле app/presenters/PostPresenter.php. Понадобится работа с базой данных, поэтому добавьте зависимость базы данных.

PostPresenter должен выглядеть следующим образом:

<?php
namespace App\Presenters;

use Nette;
use Nette\Application\UI\Form;


class PostPresenter extends Nette\Application\UI\Presenter
{
    /** @var Nette\Database\Context */
    private $database;

    public function __construct(Nette\Database\Context $database)
    {
        $this->database = $database;
    }

    public function renderShow($postId)
    {
        $this->template->post = $this->database->table('posts')->get($postId);
    }
}

Для метода renderShow требуется один аргумент — ID записи, которую необходимо отобразить. Затем загружаются записи из базы данных и передаются в шаблон.

В файле шаблона app/presenters/templates/Homepage/default.latte мы добавили ссылку на обработку Post:show, для которого шаблон еще не создан. Вы можете попробовать открыть запись в браузере, воспользовавшись ссылкой на главной странице. (Если вы увидите ошибку 404, нужно будет включить mod_rewrite на вашем сервере.) Tracy покажет ошибку, потому что шаблон app/presenters/templates/Post/show.latte еще не создан (если вы видите ошибку 404, скорее всего нужно включить mod_rewrite на вашем сервере). Добавим:

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

Макрос {link} сгенерирует адрес URL, указывающий на метод Post:show. Этот макрос также передает идентификатор поста в качестве аргумента.

То же самое мы можем написать в более коротком виде n:macro:

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

Атрибут n:href является псевдонимом для макроса {link}.

Шаблон для метода Post:show еще не существует. Мы можем отрыть ссылку на запись. Tracy покажет ошибку, что шаблон app/templates/Post/show.latte не существует.  Если вы видите какой-либо другой отчет об ошибке, вам, вероятно, придется включить mod_rewrite на вашем веб-сервере.
Создадим файл app/templates/Post/show.latte с следующим содержимым:

{block content}

<p><a n:href="Homepage:default">← назад к записям</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>

Давайте посмотрим на все отдельно.

В первой строке начинается определение именованного блока с названием «content», который мы видели ранее. Он будет отображаться в главном шаблоне.

Вторая строка содержит ссылку на список записей блога, что бы пользователь мог перемещаться вперед и назад. Мы опять воспользовались атрибутом n:href, поэтому Nette позаботится о создании ссылки. Ссылка default указывает на метод Презентера Homepage (вы можете написать n:href="Homepage:", метод default может быть опущен).

Третья строка форматирует временную метку публикации с фильтром, как мы уже знаем.

Четвертая строка отображет заголовок записи в теге  <h1>. С n:block="title" вы наверно не знакомы. Можете догадаться что он делает? Если вы внимательно прочитали предыдущие части, мы упоминали n: attributes. Это еще один пример. Это эквивалентно:

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

Говоря простыми словами, он переопределяет блок с названием title. Этот блок определен в главном шаблоне (/app/presenters/templates/@layout.latte:11) и как при переопределении ОПП, он переопределяется. Таким образом, <title> страницы будет содержать заголовок текущей отображаемой записи. Мы переопределили название страницы, и все, что нам было нужно, было n:block="title". Круто, да?

Пятая и последняя строка шаблона отображает полное содержание вашего сообщения.

Проверка ID записи

Что произойдет, если кто-то изменит URL-адрес и вставляет postId, который не существует? По хорошему мы должны предоставить пользователю ошибку «страница не найдена». Давайте обновим метод показа записи в файле app/presenters/PostPresenter.php:

    public function renderShow($postId)
    {
        $post = $this->database->table('posts')->get($postId);
        if (!$post) {
            $this->error('Запись не найдена');
        }

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

Если сообщение не может быть найдено, вызов $this->error(...) отобразит страницу 404 с понятным сообщением. Обратите внимание, что в вашей среде разработки (на вашем ноутбуке) вы не увидите страницу с ошибкой. Вместо этого Tracy покажет исключение с полными подробностями, что довольно удобно для разработки. Вы можете проверить оба режима, просто измените значение, переданное setDebugMode в bootstrap.php.

Итог

У нас есть база данных с записями блога и веб-приложение с двумя представлениями — сначала отображается сводка всех последних записей, а второе отображает одну конкретную запись.

Яндекс.Метрика