No tutorial anterior, criamos a entidade Author, e fizemos o relacionamento com os posts, neste tutorial vamos fazer as configurações adequadas para que possamos deixar nossa aplicação estruturada corretamente, e vamos criar e configurar a página index, onde os usuários terão acesso para visualizar e ler os posts.
Configurando
Vamos começar com as configurações.
Entrando no bundle CoreBundle, caminho: src/Tableless/CoreBundle, exclua a pasta Controller.
Ainda neste mesmo bundle vamos excluir a pasta view, caminho: src/Tableless/CoreBundle/Resources/view.
Agora vamos entrar no bundle ModelBundle, caminho: src/Tableless/ModelBundle.
E vamos mover a pasta Controller desse bundle para o bundle CoreBundle
Vamos mover também a pasta view do ModelBundle para o bundle CoreBundle.
Depois das mudanças, nossa estrutura de pastas ficará como na imagem abaixo:
Configurando os Controllers
Vamos continuar nossas configurações, agora vamos alterar nossos controllers para que os mesmos fiquem de acordo com a estrutura de pasta atual.
Primeiramente, vamos excluir a rota do ModelBundle, pois não vamos usá-la.
Entre no arquivo app/config/routing.yml e exclua as linhas abaixo:
tableless_model: resource: "@TablelessModelBundle/Controller/" type: annotation prefix: /
Deixando somente a rota tableless_core como mostrado na imagem abaixo:
Agora vamos excluir o DefaultController.php, pois não vamos usar esse controller.
Abra o arquivo AuthorController.php, caminho: src/Tableless/CoreBundle/Controller/AuthorController.php
Na linha 3, mude o namespace.
De: Tableless\ModelBundle\Controller;
Para: Tableless\CoreBundle\Controller;
Na linha 43, mude a annotation:
De: @Template(“TablelessModelBundle:Author:new.html.twig”)
Para: @Template(“TablelessCoreBundle:Author:new.html.twig”)
Agora vamos configurar o controller PostController, caminho: src/Tableless/CoreBundle/Controller/PostController.php, vamos fazer a mesma alteração.
Na linha 3, mude o namespace.
De: Tableless\ModelBundle\Controller;
Para: Tableless\CoreBundle\Controller;
Na linha 43, mude a annotation:
De: @Template(“TablelessModelBundle:Post:new.html.twig”)
Para: @Template(“TablelessCoreBundle:Post:new.html.twig”)
Para verificarmos se correu tudo bem, vamos fazer o teste.
Rode o servidor
$ app/console server:run
Entre nas urls:
https://127.0.0.1:8000/author/
Se tudo foi configurado corretamente, nossa aplicação voltará a funcionar perfeitamente, veja:
Criando um Controller
Nesse momento vamos criar um index, para nossa aplicação, para que seja nossa pagina principal, e possamos visualizar os posts de forma correta.
Podemos criar o controller codificando, porém para efeito de didática vamos criar através do console.
Entre no terminal e digite:
$ php app/console generate:controller
Ao digitarmos o comando acima e darmos enter, entramos no assistente do console do Symfony e ele nos comunica: Primeiro, você precisa dar o nome do controlador que você deseja gerar. Você deve usar a notação de atalho como AcmeBlogBundle:Post
Nesse momento digitamos:
$ Controller name: TablelessCoreBundle:IndexControler
Ao darmos o nome do nosso controller e darmos enter, o assistente nos pergunta: Qual o formato que vamos configurar a nossa rota?
E nos indica annotation, vamos deixar como está, e apenas damos enter:
$ Routing format (php, xml, yml, annotation) [annotation]:
A próxima pergunta é:
Qual o formato que vamos usar para template?
Ele mesmo nos indica o twig. Apenas damos enter.
$ Template format (twig, php) [twig]:
Após o enter ele nos pede o nome de nossas ações, que são os métodos que vamos criar para o nosso controller.
A primeira ação (método) vamos chamar de indexAction, e damos enter.
$ New action name (press to stop adding actions): indexAction
O assistente nos pede a rota, vamos digitar “/” e damos enter.
$ Action route [/index]: /
Nos pergunta o caminho da nossa template, e ele nos indica um caminho, vamos deixar como está e apenas damos enter.
$ Templatename (optional) [TablelessCoreBundle:IndexControler:index.html.twig]:
Novamente o assistente nos pede para darmos um nome para uma nova ação (método), essa nova ação fará com que o post seja visualizado para a leitura, vamos dar o nome de showAction.
$ New action name (press to stop adding actions): showAction
O assistente nos pede a rota, e nos indica como “/show”, vamos deixar como está e damos enter.
$ Action route [/show]:
Nos pergunta sobre caminho da template, e ele nos indica um caminho, vamos deixar como está e apenas damos enter.
$ Templatename (optional) [TablelessCoreBundle:IndexControler:show.html.twig]:
Ao darmos enter, entramos no modo de criação de uma nova ação, porém não queremos nenhuma outra ação, então apenas damos um enter, para entrarmos no processo de finalização.
$ New action name (press to stop adding actions):
Ao entramos no processo de finalização o assistente nos pergunta se queremos confirmar a geração desse controller, ele nos indica sim, como queremos, apenas damos enter.
$ Do you confirm generation [yes]?
Pronto! Nosso controller IndexController está criado, juntamente com suas templates, veja a imagem abaixo:
Ao entrarmos na url: https://127.0.0.1:8000/, vamos entrar no nosso index, e receberemos a mensagem abaixo:
Welcome to the IndexControler:index page
Criando um repositório
Se entrarmos em nosso controller IndexController, caminho: src/Tableless/CoreBunde/ IndexController.php, vamos perceber que nossos métodos estão criados, porém não estão implementados, vamos implementá-los, mas queremos que nosso index apresente para o usuário os últimos posts escritos, para que sempre o post mais atual seja apresentado em primeiro lugar, para isso devemos criar um repositório para nossa entidade Post.
Para isso, vamos entrar no bundle ModelBundle e crie uma pasta com o nome de Repository, dentro dessa pasta crie uma classe com o nome PostRepository.
Com a classe PostRepository aberta, adicione o nemspace dessa classe, e de um extends na classe EntityRepository do Doctrine, não se esquecendo de dar um use nessa classe.
use Doctrine\ORM\EntityRepository;
Crie um método privado com o nome getQueryBuilder e acrescente a EntityManager para que possamos usar nossa entidade Post, veja abaixo:
private function getQueryBuilder() { $em = $this->getEntityManager(); $queryBuilder = $em->getRepository('TablelessModelBundle:Post') ->createQueryBuilder('p'); return $queryBuilder; }
Agora vamos criar um método publico chamado findAllInOrder, e vamos chamar o método getQueryBuilder(), para ordená-lo da forma que queremos, para que seja mostrado o último post postado primeiro. Veja abaixo:
public function findAllInOrder() { $qb = $this->getQueryBuilder() ->orderBy('p.createdAt', 'desc'); return $qb->getQuery()->getResult(); }
Veja a classe PostRepository pronta:
<?php namespace Tableless\ModelBundle\Repository; use Doctrine\ORM\EntityRepository; class PostRepository extends EntityRepository { private function getQueryBuilder() { $em = $this->getEntityManager(); $queryBuilder = $em->getRepository('TablelessModelBundle:Post') ->createQueryBuilder('p'); return $queryBuilder; } public function findAllInOrder() { $qb = $this->getQueryBuilder() ->orderBy('p.createdAt', 'desc'); return $qb->getQuery()->getResult(); } }
Agora temos que indicar para a entidade Post via annotation, onde está a classe PostRepository, para isso vamos abrir a entidade Post, caminho:src/Tableless/ModelBundle/Entity/Post.php, e acrescentar a annotation (repositoryClass=”Tableless\ModelBundle\Repository\PostRepository”) na linha 12 de sua entidade, veja:
/** * Post * * @ORM\Table(name="post") * @ORM\Entity(repositoryClass="Tableless\ModelBundle\Repository\PostRepository") */ class Post extends Timestampable { ...
Implementando o controller
Vamos voltar para nosso IndexController, para que possamos implementá- lo. Abra o IndexController , e no método indexAction() temos que chamar nossa entidade Post, para que através dela chamemos o método findAllInOrder() da classe PostRepository, e retornar o resultado em forma de array, veja abaixo:
public function indexAction() { $em = $this->getDoctrine()->getManager(); $posts = $em->getRepository('TablelessModelBundle:Post')->findAllInOrder(); return [ 'posts' => $posts, ]; }
Também vamos implementar o método showAction(), para que seja buscado apena o post clickado pelo usuário, para isso devemos passar um parâmetro id, tanto no método, quanto na annotation para rota, para que seja buscado somente o post solicitado. Temos que chamar nossa entidade Post novamente, para que através dela chamemos o método find(), que já vem pré configurado pelo Doctrine, porém se o usuário requisitar um post que não existe, temos que passar uma mensagem de erro, para informá- lo, veja abaixo:
/** * @Route("/show/{id}") * @Template() */ public function showAction($id) { $em = $this->getDoctrine()->getManager(); $post = $em->getRepository('TablelessModelBundle:Post')->find($id); if (!$post) { throw $this->createNotFoundException('O post não existe! Volte para home!'); } return [ 'post' => $post, ]; }
Veja o IndexController pronto:
<?php namespace Tableless\CoreBundle\Controller; use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; class IndexControlerController extends Controller { /** * @Route("/") * @Template() */ public function indexAction() { $em = $this->getDoctrine()->getManager(); $posts = $em->getRepository('TablelessModelBundle:Post')->findAllInOrder(); return [ 'posts' => $posts, ]; } /** * @Route("/show/{id}") * @Template() */ public function showAction($id) { $em = $this->getDoctrine()->getManager(); $post = $em->getRepository('TablelessModelBundle:Post')->find($id); if (!$post) { throw $this->createNotFoundException('O post não existe! Volte para home!'); } return [ 'post' => $post, ]; } }
Para vemos como está ficando nossa aplicação, abra a index.html.twig, do IndexController, caminho: src/Tableless/CoreBundle/Resouces/views/IndexController/index.html.twig e vamos dar um dump em posts, veja abaixo, vamos adicionar a linha 8:
{% extends "::base.html.twig" %} {% block title %}TablelessCoreBundle:IndexControler:index{% endblock %} {% block body %} Welcome to the IndexControler:index page {{ dump(posts) }} {% endblock %}
Vamos fazer a mesma modificação para o arquivo show.html.twig no mesmo diretório, porém ao em vez de dar um dump em posts, vamos dar um dump em post, sem o “s” no final, veja:
{% extends "::base.html.twig" %} {% block title %}TablelessCoreBundle:IndexControler:show{% endblock %} {% block body %} Welcome to the IndexControler:show page {{ dump(post) }} {% endblock %}
Para vemos o resultado, entre nas urls:
https://127.0.0.1:8000/show/{o id do seu post}
Veja as imagens para comparação:
index – url: https://127.0.0.1:8000/
Pagina show – url: https://127.0.0.1:8000/show/4 -> {o id do seu post} no meu caso 4.
Conclusão
No tutorial anterior, eu comentei que iriamos configurar nosso projeto e começarmos a trabalhar com o Twig, porém nossa configuração e a criação do index, deixou este tutorial extenso, mas no próximo tutorial, vamos trabalhar com o bootstrap e com o twig para que possamos visualizar nossos post em nossa home da forma adequada e bonita.
Links dos tutoriais anteriores:
Iniciando com Symfony 2 – Instalação
Iniciando com Symfony 2 – parte 02
Iniciando com Symfony 2 – parte 03
Iniciando com Symfony 2 – parte 04
O projeto encontra-se no GitHub!