Página inicial do Blog
Vamos criar a home page exibindo seus posts recentes.
Antes de começarmos, você deve saber pelo menos algumas noções básicas sobre o padrão de design Model-View-Presenter (similar ao MVC):
- **Modelo*** – camada de manipulação de dados. Está completamente separado do resto da aplicação. Ele só se comunica com os apresentadores.
- Veja – uma camada de definição front-end. Ela torna os dados solicitados ao usuário usando modelos.
- Presente (ou Controlador) – uma camada de conexão. O apresentador conecta Modelo e Vista. Trata os pedidos, pede dados ao Modelo e depois os passa para a Vista atual.
No caso de uma aplicação muito simples como nosso blog, a camada Model consistirá apenas em consultas ao próprio banco de dados – não precisamos de nenhum código PHP extra para isso. Precisamos apenas criar camadas de Apresentador e Visualização. Na Nette, cada Apresentador tem suas próprias Views, portanto continuaremos com ambas simultaneamente.
Criação do banco de dados com Adminer
Para armazenar os dados, utilizaremos o banco de dados MySQL porque é a escolha mais comum entre os desenvolvedores web. Mas se você não gostar, sinta-se à vontade para usar um banco de dados de sua escolha.
Vamos preparar o banco de dados que irá armazenar nossos posts no blog. Podemos começar de forma muito simples – apenas com uma única tabela para postagens.
Para criar o banco de dados, podemos baixar o Adminer, ou você pode usar outra ferramenta para o gerenciamento do banco de dados.
Vamos abrir o Adminer e criar um novo banco de dados chamado quickstart
.
Crie uma nova tabela chamada posts
e adicione estas colunas:
id
int, clique em autoincrement (AI)title
varchar, comprimento 255content
textocreated_at
timestamp
Deveria ser assim:
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;
É muito importante utilizar o InnoDB armazenamento de mesa. Você verá o motivo mais tarde. Por enquanto, basta escolher isso e enviar. Você pode clicar em Salvar agora.
Tente adicionar alguns exemplos de posts no blog antes de implementarmos a capacidade de adicionar novos posts diretamente de nossa aplicação.
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, quando o banco de dados é criado e temos alguns posts nele, é o momento certo para exibi-los em nossa nova página brilhante.
Em primeiro lugar, precisamos informar nossa aplicação sobre qual banco de dados utilizar. A configuração da conexão do
banco de dados é armazenada em config/common.neon
. Defina a conexão DSN e suas credenciais. Deve ter este aspecto:
database:
dsn: 'mysql:host=127.0.0.1;dbname=quickstart'
user: *enter user name*
password: *enter password here*
Esteja atento à indentação durante a edição deste arquivo. O formato NEON aceita ambos os espaços e abas, mas não ambos juntos! O arquivo de configuração no Projeto Web utiliza abas como padrão.
Injetando a conexão do banco de dados
O apresentador HomePresenter
, que listará os artigos, precisa de uma conexão de banco de dados. Para
recebê-la, escreva um construtor como este:
<?php
namespace App\UI\Home;
use Nette;
final class HomePresenter extends Nette\Application\UI\Presenter
{
public function __construct(
private Nette\Database\Explorer $database,
) {
}
// ...
}
Carregamento de postes a partir do banco de dados
Agora vamos buscar os posts no banco de dados e passá-los para o template, que então renderizará o código HTML. É para isso que serve o chamado método render:
public function renderDefault(): void
{
$this->template->posts = $this->database
->table('posts')
->order('created_at DESC')
->limit(5);
}
O apresentador agora tem um método de renderização renderDefault()
que passa dados para uma visualização
chamada default
. Os modelos do apresentador podem ser encontrados em
app/UI/{PresenterName}/{viewName}.latte
, então neste caso o modelo será localizado em
app/UI/Home/default.latte
. No modelo, uma variável chamada $posts
está agora disponível, que contém
os posts do banco de dados.
Modelo
Há um modelo genérico para toda a página (chamado layout, com cabeçalho, folhas de estilo, rodapé, …) e depois modelos específicos para cada visualização (por exemplo, para exibir a lista de posts do blog), que podem substituir algumas das peças do modelo de layout.
Por padrão, o modelo de layout está localizado em app/UI/@layout.latte
, que contém:
...
{include content}
...
{include content}
insere um bloco chamado content
no modelo principal. Você pode defini-lo nos
gabaritos de cada vista. Neste caso, editaremos o arquivo Home/default.latte
desta forma:
{block content}
Hello World
{/block}
Ele define o blococontent, que será inserido no layout. Se
você atualizar o navegador, verá uma página com o texto “Hello world” (em código fonte também com cabeçalho e rodapé
de página HTML definidos em @layout.latte
).
Vamos exibir os posts do blog – editaremos o modelo desta forma:
{block content}
<h1>My blog</h1>
{foreach $posts as $post}
<div class="post">
<div class="date">{$post->created_at|date:'j. n. Y'}</div>
<h2>{$post->title}</h2>
<div>{$post->content|truncate:256}</div>
</div>
{/foreach}
{/block}
Se você atualizar seu navegador, você verá a lista de seus posts no blog. A lista não é muito chique ou colorida,
portanto, sinta-se à vontade para adicionar algum CSS brilhante a www/css/style.css
e vinculá-lo em um layout:
...
<link rel="stylesheet" href="{$basePath}/css/style.css">
</head>
...
A tag {foreach}
itera todos os posts passados para a variável $posts
e exibe um pedaço de código
HTML para cada post. Assim como um código PHP faria.
A coisa |date
é chamada de filtro. Os filtros são usados para formatar a saída. Este filtro particular
converte uma data (por exemplo, 2013-04-12
) para sua forma mais legível (12. 4. 2013
). O filtro
|truncate
truncata a string no comprimento máximo especificado, e adiciona uma elipse à extremidade se a string for
truncada. Como isto é uma prévia, não há sentido em exibir o conteúdo completo do artigo. Outros filtros padrão podem ser encontrados na documentação ou você pode criar o seu próprio, se
necessário.
Mais uma coisa. Podemos tornar o código um pouco mais curto e, portanto, mais simples. Podemos substituir as etiquetas por n:atributos desta forma:
{block content}
<h1>My 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}</div>
</div>
{/block}
O n:foreach
, simplesmente envolve o div com um para cada bloco (ele faz exatamente a mesma coisa
que o bloco de código anterior).
Sumário
Temos um banco de dados MySQL muito simples, com alguns posts em blogs. O aplicativo se conecta ao banco de dados e exibe uma lista simples dos posts.