Posted on: October 13, 2021 09:24 PM
Posted by: Renato
Views: 403
Um dos problemas mais comuns de frameworks que usam o MVC é a camada de view concentrar lógica invés de exibição.
Os Frameworks Laravel e Symfony utilizam por padrão template engines como Blade e Twig, respectivamente. Esses template engines possuem o intuito de diminuir a complexidade das views, no entanto, nem mesmo com essa ajuda as views ficam limpas o suficiente. Existem certos tratamentos que acabam sobrecarregando as views e também não é papel do model tratar isso. É nesse ponto que entram os Presenters.
Para ajudar na solução desses problemas podemos usar o Presenters nessa camada extra nas nossas aplicações. O principal objetivo dela é facilitar e devolver a informação já tratada para a view, diminuindo assim a quantidade de decisões de nossas views e também os models de uma responsabilidade que não é sua função.
Por padrão o Laravel não possui uma camada de Presenter, precisamos instalar via Package. Existem diversos packages que fazem esse processo, alguns mais elaborados e outros mais simples. No caso do nosso exemplo vamos usar o desenvolvido por Jeffrey Way que podemos fazer o download no packagist.org.
Basta executar o comando para o composer adicionar a dependência:
composer require laracasts/presenter
Criando e ligando o Presenter ao Model
A ideia é que cada método trate uma única informação, para mantermos também a classe de presenter organizada. No escopo do presenter é possível acessar as propriedades do model, assim fica mais fácil tratar as informações:
<?php
namespace AppPresenters;
use LaracastsPresenterPresenter;
class ProjectPresenter extends Presenter
{
public function projectName()
{
return $this->id . ' ' . $this->name;
}
public function finalDate()
{
return $this->final_date->diffForHumans();
}
}
Estamos criando um método que retorna o nome do projeto com o id e outro que retorna a data final do projeto em um formato mais fácil de ler.
Precisamos indicar o nome do presenter e usar uma trait que possui os métodos do pacote no model. Vamos supor que temos um model chamado Project, ele ficaria assim:
<?php
use AppPresentersProjectPresenter;
use LaracastsPresenterPresentableTrait;
use IlluminateDatabaseEloquentModel;
class Project extends Model
{
use PresentableTrait;
protected $presenter = ProjectPresenter::class;
}
Finalmente, agora podemos usar os métodos na view. Basta chamar em uma instancia do model um método chamado present()
. Veja o exemplo:
{{ $project->present()->projectName }}
Estamos chamando o método ProjectName
do presenter. Assim ele vai imprimir no formato ID Nome do projeto que retornamos no presenter.
Exemplo prático
Vamos imaginar que no model de projetos temos uma propriedade chamada status. Dependendo do status temos que definir a cor do label exibido para o usuário:
- Status não iniciado: Etiqueta Azul
- Status no prazo: Etiqueta Verde
- Status atrasado: Etiqueta Vermelha
Usando as classes do bootstrap poderíamos fazer assim:
<span class="label label-{{ $project->present()->statusLabelColor }}">
Status aqui
</span>
E no presenter definir a lógica:
<?php
namespace AppPresenters;
use LaracastsPresenterPresenter;
class ProjectPresenter extends Presenter
{
public function statusLabelColor()
{
$labels = [
'nao-iniciado' => 'primary',
'no-prazo' => 'success',
'atrasado' => 'danger'
];
return $labels[$this->status];
}
}
Isoladamente não parece fazer tanta diferença utilizar os presenters ou não, porém, ao compararmos as views dos projetos que utilizam com os que não utilizam, isso fica muito claro.
O resultado é ainda melhor se o nome dos métodos do presenter forem definidos semanticamente, assim além de remover o código “feio” da view ainda a torna mais fácil de ser lida por humanos.
Fontes:
- https://github.com/laracasts/Presenter
- https://packagist.org/packages/laracasts/presenter
- https://www.treinaweb.com.br/blog/removendo-logica-das-views-com-presenters-no-laravel
Donate to Site
Renato
Developer