Criando e editando postagens

Isso é ótimo! Temos um novo blog super legal, as pessoas estão discutindo intensamente nos comentários e finalmente temos um pouco de tempo para programar mais. Embora o Adminer seja uma ótima ferramenta, não é totalmente ideal para escrever novas postagens no blog. Provavelmente é a hora certa de criar um formulário simples para adicionar novas postagens diretamente do aplicativo. Vamos lá.

Comecemos projetando a interface do usuário:

  1. Na página inicial, adicionaremos um link “Escrever nova postagem”.
  2. Este link exibirá um formulário com um título e uma área de texto para o conteúdo da postagem.
  3. Quando clicarmos no botão Salvar, a postagem será salva no banco de dados.

Mais tarde, também adicionaremos login e permitiremos a adição de postagens apenas para usuários logados. Mas isso depois. Que código precisamos escrever agora para que tudo funcione?

  1. Criaremos um novo presenter com um formulário para adicionar postagens.
  2. Definiremos um callback que será executado após o envio bem-sucedido do formulário e que salvará a nova postagem no banco de dados.
  3. Criaremos um novo template no qual o formulário estará.
  4. Adicionaremos um link para o formulário no template da página principal.

Novo presenter

Chamaremos o novo presenter de EditPresenter e o salvaremos em app/Presentation/Edit/EditPresenter.php. Ele também precisa se conectar ao banco de dados, então escreveremos novamente um construtor que exigirá a conexão com o banco de dados:

<?php
namespace App\Presentation\Edit;

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

final class EditPresenter extends Nette\Application\UI\Presenter
{
	public function __construct(
		private Nette\Database\Explorer $database,
	) {
	}
}

Formulário para salvar postagens

Já explicamos formulários e componentes ao criar comentários. Se ainda não estiver claro, vá revisar a criação de formulários e componentes, nós esperaremos aqui ;)

Agora adicione este método ao presenter EditPresenter:

protected function createComponentPostForm(): Form
{
	$form = new Form;
	$form->addText('title', 'Título:')
		->setRequired();
	$form->addTextArea('content', 'Conteúdo:')
		->setRequired();

	$form->addSubmit('send', 'Salvar e publicar');
	$form->onSuccess[] = $this->postFormSucceeded(...);

	return $form;
}

Salvando nova postagem do formulário

Continuamos adicionando um método que processará os dados do formulário:

private function postFormSucceeded(array $data): void
{
	$post = $this->database
		->table('posts')
		->insert($data);

	$this->flashMessage("A postagem foi publicada com sucesso.", 'success');
	$this->redirect('Post:show', $post->id);
}

Apenas uma rápida recapitulação: este método obtém os dados do formulário, insere-os no banco de dados, cria uma mensagem para o usuário sobre o salvamento bem-sucedido da postagem e redireciona para a página com a nova postagem, para que possamos ver imediatamente como ela ficou.

Página para criar nova postagem

Vamos criar agora o template Edit/create.latte:

{block content}
<h1>Nova postagem</h1>

{control postForm}

Tudo já deve estar claro. A última linha renderiza o formulário que acabamos de criar.

Poderíamos criar também o método renderCreate correspondente, mas não é necessário. Não precisamos obter nenhum dado do banco de dados e passá-lo para o template, então esse método estaria vazio. Nesses casos, o método não precisa existir.

Você provavelmente já sabe como adicionar um link para o EditPresenter e sua ação create. Experimente.

Basta adicionar ao arquivo app/Presentation/Home/default.latte:

<a n:href="Edit:create">Escrever nova postagem</a>

Edição de postagens

Agora também adicionaremos a opção de editar uma postagem. Será muito simples. Já temos o formulário postForm pronto e podemos usá-lo também para edição.

Adicionaremos uma nova página edit ao presenter EditPresenter:

public function renderEdit(int $id): void
{
	$post = $this->database
		->table('posts')
		->get($id);

	if (!$post) {
		$this->error('Post not found');
	}

	$this->getComponent('postForm')
		->setDefaults($post->toArray());
}

E criaremos outro template Edit/edit.latte:

{block content}
<h1>Editar postagem</h1>

{control postForm}

E modificaremos o método postFormSucceeded, que será capaz tanto de adicionar um novo artigo (como faz agora) quanto de editar um artigo já existente:

private function postFormSucceeded(array $data): void
{
	$id = $this->getParameter('id');

	if ($id) {
		$post = $this->database
			->table('posts')
			->get($id);
		$post->update($data);

	} else {
		$post = $this->database
			->table('posts')
			->insert($data);
	}

	$this->flashMessage('A postagem foi publicada com sucesso.', 'success');
	$this->redirect('Post:show', $post->id);
}

Se o parâmetro id estiver disponível, significa que vamos editar a postagem. Nesse caso, verificaremos se a postagem solicitada realmente existe e, se sim, a atualizaremos no banco de dados. Se o parâmetro id não estiver disponível, significa que uma nova postagem deve ser adicionada.

Mas de onde vem o parâmetro id? É o parâmetro que foi passado para o método renderEdit.

Agora podemos adicionar um link ao template app/Presentation/Post/show.latte:

<a n:href="Edit:edit $post->id">Editar postagem</a>

Resumo

O blog agora está funcional, os visitantes estão comentando ativamente e não precisamos mais do Adminer para publicar. O aplicativo é totalmente independente e qualquer pessoa pode adicionar uma nova postagem. Espere um momento, isso provavelmente não está totalmente certo, que qualquer pessoa – e quero dizer realmente qualquer pessoa com acesso à internet – possa adicionar novas postagens. É necessária alguma segurança para que apenas um usuário logado possa adicionar uma nova postagem. Veremos isso no próximo capítulo.