Página inicial do blog
Agora criaremos a página inicial exibindo as postagens mais recentes.
Antes de começarmos, é necessário conhecer pelo menos os fundamentos do padrão de projeto Model-View-Presenter (semelhante ao MVC):
- Model – camada que trabalha com dados. É completamente separada do resto da aplicação. Comunica apenas com o presenter.
- View – camada de front-end. Renderiza os dados solicitados usando templates e os exibe ao usuário.
- Presenter (ou Controller) – camada de conexão. O Presenter conecta o Model e a View. Processa requisições, consulta o Model por dados e os retorna para a View.
No caso de aplicações simples, como será nosso blog, toda a camada de modelo consistirá apenas em consultas ao banco de dados – para isso, por enquanto, não precisamos de nenhum código extra. Para começar, criaremos apenas os presenters e templates. No Nette, cada presenter tem seus próprios templates, então os criaremos simultaneamente.
Criação do banco de dados usando o Adminer
Para armazenar dados, usaremos um banco de dados MySQL, pois é o mais difundido entre os programadores de aplicações web. No entanto, se você não quiser usá-lo, sinta-se à vontade para escolher o banco de dados de sua preferência.
Agora prepararemos a estrutura do banco de dados onde os artigos do nosso blog serão armazenados. Começaremos de forma muito simples – criaremos apenas uma tabela para as postagens.
Para criar o banco de dados, podemos baixar o Adminer, ou outra ferramenta de gerenciamento de banco de dados de sua preferência.
Abra o Adminer e crie um novo banco de dados com o nome quickstart
.
Crie uma nova tabela chamada posts
com as seguintes colunas:
id
int, marque autoincremento (AI)title
varchar, comprimento 255content
textcreated_at
timestamp
A estrutura resultante deve ter a seguinte aparência:

CREATE TABLE `posts` (
`id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`title` varchar(255) NOT NULL,
`content` text NOT NULL,
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB CHARSET=utf8;
É realmente importante usar o armazenamento InnoDB. Em breve mostraremos por quê. Por enquanto, simplesmente selecione-o e clique em salvar.
Antes de criarmos a possibilidade de adicionar artigos ao banco de dados através da aplicação, adicione alguns artigos de exemplo ao blog manualmente.
INSERT INTO `posts` (`id`, `title`, `content`, `created_at`) VALUES
(1, 'Article One', 'Lorem ipusm dolor one', CURRENT_TIMESTAMP),
(2, 'Article Two', 'Lorem ipsum dolor two', CURRENT_TIMESTAMP),
(3, 'Article Three', 'Lorem ipsum dolor three', CURRENT_TIMESTAMP);
Conexão com o banco de dados
Agora que o banco de dados foi criado e temos alguns artigos armazenados nele, é hora de exibi-los em nossa bela nova página.
Primeiro, precisamos dizer à aplicação qual banco de dados usar. A conexão com o banco de dados é configurada no arquivo
config/common.neon
usando DSN e credenciais de login. Deve ter a
seguinte aparência:
database:
dsn: 'mysql:host=127.0.0.1;dbname=quickstart'
user: *insira o nome de usuário aqui*
password: *insira a senha do banco de dados aqui*
Ao editar este arquivo, preste atenção à indentação das linhas. O formato NEON aceita tanto indentação por espaços quanto por tabulações, mas não ambos ao mesmo tempo. O arquivo de configuração padrão no Web Project usa tabulações.
Passando a conexão do banco de dados
O presenter HomePresenter
, que cuidará da listagem dos artigos, precisa de uma conexão com o banco de dados.
Para obtê-la, usaremos um construtor, que terá a seguinte aparência:
<?php
namespace App\Presentation\Home;
use Nette;
final class HomePresenter extends Nette\Application\UI\Presenter
{
public function __construct(
private Nette\Database\Explorer $database,
) {
}
// ...
}
Carregando postagens do banco de dados
Agora carregaremos as postagens do banco de dados e as enviaremos para o template, que as renderizará como código HTML. Para isso, existe o chamado método render:
public function renderDefault(): void
{
$this->template->posts = $this->database
->table('posts')
->order('created_at DESC')
->limit(5);
}
O presenter agora contém um método de renderização renderDefault()
, que passa dados do banco de dados para
o template (View). Os templates estão localizados em app/Presentation/{PresenterName}/{viewName}.latte
, então
neste caso o template está localizado em app/Presentation/Home/default.latte
. No template, a variável
$posts
estará agora disponível, contendo as postagens obtidas do banco de dados.
Template
Para todo o site, temos um template principal (que se chama layout, contém cabeçalho, estilos, rodapé,…) e, em seguida, templates específicos para cada view (por exemplo, para exibir postagens no blog), que podem sobrescrever algumas partes do template principal.
Por padrão, o template de layout está localizado em app/Presentation/@layout.latte
e contém:
...
{include content}
...
A escrita {include content}
insere no template principal um bloco chamado content
. Definiremos isso
nos templates das views individuais. No nosso caso, modificaremos o arquivo Home/default.latte
da
seguinte forma:
{block content}
Olá Mundo
{/block}
Com isso, definimos o bloco content, que será inserido no
layout principal. Se atualizarmos o navegador novamente, veremos a página com o texto “Olá Mundo” (no código-fonte
também com o cabeçalho e rodapé HTML definidos em @layout.latte
).
Vamos exibir as postagens do blog – modificaremos o template da seguinte forma:
{block content}
<h1>Meu blog</h1>
{foreach $posts as $post}
<div class="post">
<div class="date">{$post->created_at|date:'F j, Y'}</div>
<h2>{$post->title}</h2>
<div>{$post->content|truncate:256}</div>
</div>
{/foreach}
{/block}
Se atualizarmos o navegador, veremos a lista de todas as postagens. A lista ainda não está muito bonita nem colorida,
então podemos adicionar alguns estilos CSS
ao arquivo www/css/style.css
e vinculá-lo no layout:
...
<link rel="stylesheet" href="{$basePath}/css/style.css">
</head>
...
A tag {foreach}
itera sobre todas as postagens que passamos para o template na variável $posts
, e
para cada uma renderiza o pedaço de HTML correspondente. Comporta-se exatamente como o código PHP.
Chamamos a escrita |date:
de filtro. Os filtros são destinados a formatar a saída. Este filtro específico
converte a data (por exemplo, 2013-04-12
) para sua forma mais legível (Abril 12, 2013
). O filtro
|truncate
corta a string no comprimento máximo especificado e, caso a string seja encurtada, adiciona reticências
no final. Como se trata de uma prévia, não faz sentido exibir todo o conteúdo do artigo. Outros filtros padrão podem ser encontrados na documentação ou podemos criar os nossos próprios, quando
necessário.
Mais uma coisa. Podemos encurtar e simplificar o código anterior. Conseguimos isso substituindo as tags Latte por n:atributos:
{block content}
<h1>Meu blog</h1>
<div n:foreach="$posts as $post" class="post">
<div class="date">{$post->created_at|date:'F j, Y'}</div>
<h2>{$post->title}</h2>
<div>{$post->content|truncate:256}</div>
</div>
{/block}
O atributo n:foreach
envolve o bloco div com um foreach (funciona exatamente da mesma forma que
o código anterior).
Resumo
Agora temos um banco de dados MySQL muito simples com algumas postagens. A aplicação se conecta a este banco de dados e exibe uma lista simples dessas postagens no template.