Página única de postagem
Vamos adicionar outra página ao nosso blog, que exibirá o conteúdo de um determinado post do blog.
Precisamos criar um novo método de renderização, que irá buscar um post específico no blog e passá-lo para o modelo. Ter
esta visão em HomePresenter
não é legal porque se trata de um post de blog, não da página inicial. Então, vamos
criar uma nova classe PostPresenter
e colocá-la em app/UI/Post/
. Ela precisará de uma conexão de
banco de dados, então coloque o código injeção de banco de dados lá novamente.
O PostPresenter
deve se parecer com isto:
<?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);
}
}
Temos que definir um namespaces correto App\UI\Post
para nosso apresentador. Isso depende do mapeamento do apresentador.
O método renderShow
requer um argumento – a identificação do posto a ser exibido. Em seguida, ele carrega
o posto do banco de dados e passa o resultado para o modelo.
No modelo Home/default.latte
, adicionamos um link para a ação Post:show
:
...
<h2><a href="{link Post:show $post->id}">{$post->title}</a></h2>
...
A tag {link}
gera um endereço URL que aponta para a ação Post:show
. Esta tag também encaminha a
identificação do correio como argumento.
O mesmo podemos escrever em breve usando n:attribute:
...
<h2><a n:href="Post:show $post->id">{$post->title}</a></h2>
...
O atributo n:href
é similar à tag {link}
.
O modelo para a ação Post:show
ainda não existe. Podemos abrir um link para este post. Tracy mostrará um erro, porque Post/show.latte
ainda não existe. Se você
vir qualquer outro relatório de erro, provavelmente terá que ligar o mod_rewrite em seu servidor web.
Por isso, criaremos Post/show.latte
com este conteúdo:
{block content}
<p><a n:href="Home:default">← back to posts list</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>
Vamos dar uma olhada nas partes individuais.
A primeira linha inicia a definição de um bloco nomeado chamado “conteúdo”, que vimos anteriormente. Ele será
exibido em um modelo de layout. Como você pode ver, a etiqueta final {/block}
está faltando. Ela é
opcional.
A segunda linha fornece um backlink para a lista de postagens do blog, para que o usuário possa navegar suavemente para
frente e para trás em nosso blog. Usamos novamente o atributo n:href
, portanto a Nette se encarregará de gerar a
URL para nós. O link aponta para a ação default
do apresentador Home
(você também poderia escrever
n:href="Home:"
, pois a ação default
pode ser omitida).
A terceira linha formata o carimbo de tempo de publicação com um filtro, como já sabemos.
A quarta linha exibe o título do post do blog como um <h1>
título. Há uma parte que você pode
não estar familiarizado, e que é n:block="title"
. Você pode adivinhar o que ela faz? Se você leu cuidadosamente
as partes anteriores, mencionamos n: attributes
. Este é outro exemplo. É equivalente a:
{block title}<h1>{$post->title}</h1>{/block}
Em palavras simples, ele redefine um bloco chamado title
. O bloco é definido no modelo layout
(/app/UI/@layout.latte:11
) e, como no OOP, ele é anulado aqui. Portanto, a página é <title>
conterá o título do post exibido. Anulamos o título da página e tudo o que precisávamos era n:block="title"
.
Ótimo, não é?
A quinta e última linha do modelo exibe o conteúdo completo do seu post.
Verificação da identificação do posto
O que acontece se alguém altera a URL e insere id
que não existe? Devemos fornecer ao usuário um bom erro de
“página não encontrada”. Vamos atualizar o método de renderização em PostPresenter
:
public function renderShow(int $id): void
{
$post = $this->database
->table('posts')
->get($id);
if (!$post) {
$this->error('Post not found');
}
$this->template->post = $post;
}
Se o correio não puder ser encontrado, ligando para $this->error(...)
, aparecerá uma página 404 com uma
mensagem agradável e compreensível. Note que em seu ambiente de desenvolvimento (em seu laptop), você não verá a página de
erro. Em vez disso, Tracy mostrará a exceção com todos os detalhes, o que é bastante conveniente para o desenvolvimento.
Você pode verificar os dois modos, basta alterar o valor passado para setDebugMode
em
Bootstrap.php
.
Sumário
Temos um banco de dados com posts em blogs e um aplicativo web com duas visualizações – o primeiro exibe o resumo de todos os posts recentes e o segundo exibe um post específico.