Como criar uma página com Symfony
Imagine que seu chefe ou cliente te pediu para desenvolver um sistema de gestão de lançamento de horas por funcionário (que no nosso caso, se chamará TikTok®). No ultimo post vimos como instalar o symfony 4 e criar o projeto. Mas, precisamos começar de fato a aplicação. Ter algo para mostrar.
Neste post, vamos passar por todos os passos necessários para criar uma primeira página e entender como o framework lida com a renderização de páginas.
Precisamos falar sobre Twig
Ter algo para mostrar, em um sistema MVC, quase sempre significa: View. Isso quer dizer que precisamos de um arquivo HTML. O problema disso é que HTML é estático, um sistema de gestão de horas estático não costuma ser uma boa ideia.
Uma solução é criar um arquivo PHP e entre uma tag PHP e outra adicionamos o HTML de forma dinâmica. Porém, como a gente comenta no curso de php da caelum misturar código PHP e HTML não é uma boa prática pois prejudica a legibilidade do código. Principalmente, pra galera de front-end da equipe.
O melhor dos dois mundos
Para garantir a legibilidade, evitando ao máximo código PHP misturado as views, e trazer o conteúdo dinâmico, temos o TWIG. Uma ferramenta excelente que vai muito além de dar includes e escrever conteúdo dinâmico. O TWIG já vem com diversas funcionalidades que vamos explorar ao longo dos posts.
E onde o Symfony entra?
O framework é muito bem integrado ao TWIG, para utilizar a ferramenta basta incluir pelo composer:
composer require twig
Na pasta raiz do projeto.
Ao terminar a instalação, já temos o diretório onde vamos criar nossos arquivos TWIG: templates
Mãos na massa!
Uma tela que com certeza vamos precisar é a primeira do sistema. Alguma mensagem de boas vindas.
Um nome comum pra esse tipo de arquivo é o famoso index.html. Como queremos conteúdo dinâmico, o nosso se chamará index.html.twig
Mas, e o conteudo dinâmico onde fica?
Ao longo da aplicação vamos precisar, e muito, injetar conteúdo PHP nesse arquivo. Se quisessemos apresentar, além da mensagem de bem vindo, a data e hora atual de quando o usuário acessou a página não conseguiriamos com HTML puro. Em php, precisaríamos escrever algo como:
<?= (new \DateTime())->format("d/m/Y h:i") ?>
Para imprimir dia/mês/ano hora:minuto.
Em twig, basta abrirmos as chaves de conteúdo dinâmico e pedir a função que encapsula data:
{{ 'now'|date('d/m/Y h:i') }}
Com isso, temos um resultado final muito mais semântico e legível. Mesmo não entendendo muito de PHP ou Symfony, é claro que ali temos uma data. Com uma breve googlada (bem breve mesmo) é fácil concluir que estamos lidando com a data de agora. Não é preciso nem conhecer muito de inglês.
E pra abrir o twig?
Já criamos o arquivo da tela de boas vindas, já adicionamos conteúdo dinâmico nele mas ainda não vimos nada! Não acessamos essa página para garantir que está tudo certo ou mostrar ao cliente!
O ideal é acessar essa página pelo navegador. Como essa é a pagina incial, a ideia é acessar pela URL padrão:
Porém, se acessarmos essa url recebemos a menssagem de erro:
Dizendo que essa rota não exite. Rotas, em um sistema MVC, quase sempre significam: Controller.
Pela estrura de pastas do Symfony, precisamos criar qualquer arquivo do tipo Controller dentro do diretório controller. Como esse arquivo cuidará da pagina inicial, podemos chamá-lo de HomeController.
Para indicar ao Symfony que este é um Controller, utilizamos a herança (extends) da classe:
Symfony\Bundle\FrameworkBundle\Controller\AbstractController.
Resolvendo o problema da rota
Rotas são ações (actions). Em orientação a objetos, toda ação deveria ser um método. Como essa funcionalidade deve nos devolver a tela de início, podemos chamá-la de IndexAction.
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
class HomeController extends AbstractController
{
public function indexAction()
{
}
}
Renderizando o twig pelo controller
Ao final de toda action, precisamos renderizar o conteudo HTML que será devolvido ao navegador. Para isso, a propria classe Controller do Symfony tem um método que busca nossos arquivos twig no diretório templates!
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class HomeController extends Controller
{
public function indexAction()
{
// renderiza o arquivo index.html.twig no diretório templates
return $this->render('index.html.twig');
}
}
Mas, ainda falta dizer para o Symfony que essa rota deve ser chamada ao acessar a url:
Routes.yaml
Uma forma comum de se fazer esse apontamento era no arquivo config/routes.yaml indicando o controller, a action e qual rota apontaria para ela. Algo como:
index:
path: /
controller: App\Controller\HomeController::indexAction
Aqui, indicamos que o caminho http://localhost:8000/ se refere à classe HomeController mais especificamente ao método indexAction.
Evitando configurações com anotações
Porém, o framework suporta (e muito bem) anotações! Uma outra forma de fazer o mesmo apontamento. Mas, logo acima do proprio método, evitando um arquivo routes.yaml gigantesco com todas as rotas do sistema.
Para habilitar as anotações do Symfony basta pedir ao composer:
composer require annotations
E, sem a necessidade de configurar mais nada, podemos dizer exatamente qual é a rota daquela action, com a anotação Route:
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Routing\Annotation\Route;
class HomeController extends Controller
{
/**
* @Route("/")
*/
public function indexAction()
{
return $this->render('index.html.twig');
}
}
Essa configuração é exatamente a mesma do arquivo routes.yaml, aponta o método indexAction da classe HomeController para http://localhost:8000.
Vale lembrar que para conseguir utilizar a facilidade da anotação precisamos dizer que estamos usando ela:
use Symfony\Component\Routing\Annotation\Route;
E temos uma página!
Ao abrir o navegador na url indicada na nossa action, temos exatamente o conteúdo que escrevemos no nosso arquivo index.html.twig
No próximo post vamos criar outras rotas com muito mais conteúdo que uma menssagem de bem vindo. Além de começar a camada de modelo, para organizar bem as informações no sistema.
E vocês, o que acharam do sistema de rotas do Symfony? e do template de views com TWIG? Conhece alguma outra forma? Compartilha com a gente nos comentarios!
Ah! O código pronto desse post você pode encontrar versionado no meu git!