<http://schema.org/articleBody>
"No &lt;a href=\"http://tableless.com.br/iniciando-com-symfony-2-parte-08/\" title=\"tutorial anterior\" target=\"_blank\"&gt;tutorial anterior&lt;/a&gt;, instalamos e configuramos o bundle Knp Paginator, para fazer a pagina\u00E7\u00E3o de posts em nosso index, agora vamos instalar e configurar o Bundle StofDoctrineExtensionsBundle, para fazermos os slugs de nossos posts\r\n\r\n&lt;h2&gt;Instala\u00E7\u00E3o do  bundle StofDoctrineExtensionsBundle&lt;/h2&gt;\r\n\r\nPara instalar o StofDoctrineExtensionsBundle, temos que adicion\u00E1-lo em nosso composer.json. Abra o arquivo composer.json e adicione a linha abaixo:\r\n\r\n&lt;pre class=\"lang-php\"&gt;\r\n\"stof/doctrine-extensions-bundle\": \"1.2.*@dev\"\r\n&lt;/pre&gt;\r\n\r\nDepois de adicionando o StofDoctrineExtensionsBundle no composer, vamos instal\u00E1- lo. Entre no terminal e digite:\r\n\r\n&lt;pre class=\"lang-bash\"&gt;\r\n$ composer update\r\n&lt;/pre&gt;\r\n\r\nAp\u00F3s o Download, o  StofDoctrineExtensionsBundle est\u00E1 instalado em nossa aplica\u00E7\u00E3o.\r\n\r\n&lt;h2&gt;Configurando o  StofDoctrineExtensionsBundle&lt;/h2&gt;\r\n\r\nA primeira configura\u00E7\u00E3o que devemos fazer, \u00E9 registrar o novo bundle instalado, para isso entre no AppKernel, caminho: app/AppKernel.php\r\n\r\nAdicione a linha abaixo no registro de bundles:\r\n\r\n&lt;pre class=\"lang-php\"&gt;\r\nnew Stof\\DoctrineExtensionsBundle\\StofDoctrineExtensionsBundle(),\r\n&lt;/pre&gt;\r\n\r\nVeja na linha 17:\r\n\r\n&lt;pre class=\"lang-php\"&gt;\r\nclass AppKernel extends Kernel \r\n{ \r\n    public function registerBundles() \r\n    { \r\n        $bundles = array( \r\n            new Symfony\\Bundle\\FrameworkBundle\\FrameworkBundle(), \r\n            new Symfony\\Bundle\\SecurityBundle\\SecurityBundle(), \r\n            new Symfony\\Bundle\\TwigBundle\\TwigBundle(), \r\n            new Symfony\\Bundle\\MonologBundle\\MonologBundle(), \r\n            new Symfony\\Bundle\\SwiftmailerBundle\\SwiftmailerBundle(), \r\n            new Symfony\\Bundle\\AsseticBundle\\AsseticBundle(), \r\n            new Doctrine\\Bundle\\DoctrineBundle\\DoctrineBundle(), \r\n            new Sensio\\Bundle\\FrameworkExtraBundle\\SensioFrameworkExtraBundle(), \r\n            new Tableless\\CoreBundle\\TablelessCoreBundle(), \r\n            new Tableless\\ModelBundle\\TablelessModelBundle(), \r\n\t    new Knp\\Bundle\\PaginatorBundle\\KnpPaginatorBundle(),\r\n\t    new Stof\\DoctrineExtensionsBundle\\StofDoctrineExtensionsBundle(),\r\n        );\r\n\r\n...\r\n\r\n&lt;/pre&gt;\r\n\r\nPronto, o StofDoctrineExtensionsBundle est\u00E1 registrado. \r\nAgora vamos fazer as configura\u00E7\u00F5es no arquivo config.yml, caminho: app/config/config.yml\r\n\r\nNo final do arquivo adicione as configura\u00E7\u00F5es abaixo: \r\n\r\n&lt;pre class=\"lang-php\"&gt;\r\nstof_doctrine_extensions:\r\n    orm:\r\n        default:\r\n            sluggable: true\r\n&lt;/pre&gt;\r\n\r\n&lt;h2&gt;Configurando a entidade Post&lt;/h2&gt;\r\n\r\nTemos que configurar nossa entidade post, para que a mesma receba os slugs. Entre na entidade post, caminho: src/Tableless/ModelBundle/Entity/Post.php\r\n\r\nVamos dar um use em Annotation, e apelid\u00E1-la de Gedmo veja abaixo:\r\n\r\n&lt;pre class=\"lang-php\"&gt;\r\nuse Gedmo\\Mapping\\Annotation as Gedmo;\r\n&lt;/pre&gt;\r\n\r\n\r\nAgora vamos criar uma propriedade privada chamada slug, com as suas annotations correspondentes, veja:\r\n&lt;pre class=\"lang-php\"&gt;\r\n    /**\r\n     * @var string\r\n     *\r\n     * @Gedmo\\Slug(fields={\"title\"}, unique=false)\r\n     * @ORM\\Column(length=255)\r\n     */\r\n     private $slug;\r\n\r\n...\r\n\r\n&lt;/pre&gt;\r\n\r\nTemos que gerar os getters e setters, para isso vamos entrar no terminal e digitar:\r\n\r\n&lt;pre class=\"lang-bash\"&gt;\r\n$ php app/console generate:doctrine:entities TablelessModelBundle:Post\r\n&lt;/pre&gt;\r\n\r\nPronto, em nossa entidade Post, temos  os getters e setters, veja:\r\n\r\n&lt;pre class=\"lang-php\"&gt;\r\n    /**\r\n     * Set slug\r\n     *\r\n     * @param string $slug\r\n     *\r\n     * @return Post\r\n     */\r\n    public function setSlug($slug)\r\n    {\r\n        $this-&amp;gt;slug = $slug;\r\n\r\n        return $this;\r\n    }\r\n\r\n    /**\r\n     * Get slug\r\n     *\r\n     * @return string\r\n     */\r\n    public function getSlug()\r\n    {\r\n        return $this-&amp;gt;slug;\r\n    }\r\n\r\n...\r\n&lt;/pre&gt;\r\n\r\n\r\n&lt;h2&gt;Configurando o Banco de Dados&lt;/h2&gt;\r\n\r\nDepois de nossa entidade configurada, temos que atualizar o banco de dados, por\u00E9m se tivermos posts j\u00E1 criados, ocorrer\u00E1 um erro em nosso blog. Caso n\u00E3o tenha nenhum post escrito poder\u00E1 rodar o comando abaixo:\r\n\r\n&lt;pre class=\"lang-bash\"&gt;\r\n$ php app/console doctrine:schema:update \u2013force\r\n&lt;/pre&gt;\r\n\r\nCaso tenha escrito algum post para exemplo, como no meu caso, vamos excluir o banco de dados, e cri\u00E1 lo novamente. Entre no terminal e digite:\r\n\r\nExcluindo o banco de dados:\r\n&lt;pre class=\"lang-php\"&gt;\r\n$ php app/console doctrine:database:drop --force\r\n&lt;/pre&gt;\r\n\r\n\r\nCriando o banco de dados novamente:\r\n&lt;pre class=\"lang-bash\"&gt;\r\n$ php app/console doctrine:database:create\r\n&lt;/pre&gt;\r\n\r\n\r\nCriando as tabelas:\r\n&lt;pre class=\"lang-bash\"&gt;\r\n$ php app/console doctrine:schema:create\r\n&lt;/pre&gt;\r\n\r\n\r\nObs: Caso tenha posts escritos, e n\u00E3o queria excluir o banco de dados, poder\u00E1 apenas atualiz\u00E1-lo, por\u00E9m ter\u00E1 que adicionar manualmente, slug por slug em cada post no banco de dados, sen\u00E3o ocorrer\u00E1 erro na aplica\u00E7\u00E3o.\r\n\r\n\r\n\r\nVeja a estrutura do banco de dados:\r\n\r\n&lt;a href=\"http://tableless.com.br/wp-content/uploads/2015/05/01.png\"&gt;&lt;img src=\"http://tableless.com.br/wp-content/uploads/2015/05/01.png\" alt=\"Banco de dados\" width=\"750\" height=\"403\" class=\"alignnone size-full wp-image-48547\" /&gt;&lt;/a&gt;\r\n\r\n\r\n&lt;h2&gt;Configurando o Controller&lt;/h2&gt;\r\n\r\nDepois de termos feito as configura\u00E7\u00F5es citadas acima, vamos configurar nosso controller, para isso entre no IndexControlerController, caminho: src/Tableless/CoreBundle/Controller/IndexControlerController.php\r\n\r\nNo nosso m\u00E9todo showAction, estamos passando por par\u00E2metro o $id, no momento n\u00E3o queremos mais buscar nossos posts pelo id, e sim pelo slug, vamos alterar:\r\n\r\nde:\r\n&lt;pre class=\"lang-php\"&gt;\r\npublic function showAction($id)\r\n&lt;/pre&gt;\r\n\r\npara:\r\n&lt;pre class=\"lang-php\"&gt;\r\npublic function showAction($slug)\r\n&lt;/pre&gt;\r\n\r\n\r\nTemos que mudar tamb\u00E9m a annotation da rota, veja:\r\n\r\nde: \r\n&lt;pre class=\"lang-php\"&gt;\r\n* @Route(\"/show/{id}\", name=\"show\")\r\n&lt;/pre&gt;\r\n\r\npara:\r\n&lt;pre class=\"lang-php\"&gt;\r\n* @Route(\"/show/{slug}\", name=\"show\")\r\n&lt;/pre&gt;\r\n\r\nEstamos passando para a vari\u00E1vel $post, o m\u00E9todo find, e recuperando o id, vamos mudar o find para findOneBy e passar um array de slug, veja:\r\n\r\n&lt;pre class=\"lang-php\"&gt;\r\n...\r\n\r\n$post = $em-&amp;gt;getRepository('TablelessModelBundle:Post')-&amp;gt;findOneBy([\r\n            'slug' =&amp;gt; $slug\r\n        ]);\r\n\r\n...\r\n\r\n&lt;/pre&gt;\r\n\r\nVeja o m\u00E9todo  showAction pronto:\r\n\r\n&lt;pre class=\"lang-php\"&gt;\r\n    ...\r\n\r\n    /**\r\n     * @Route(\"/post/{slug}\", name=\"show\")\r\n     * @Template()\r\n     */\r\n    public function showAction($slug)\r\n    {\r\n        $em = $this-&amp;gt;getDoctrine()-&amp;gt;getManager();\r\n\r\n        $post = $em-&amp;gt;getRepository('TablelessModelBundle:Post')-&amp;gt;findOneBy([\r\n            'slug' =&amp;gt; $slug\r\n        ]);\r\n\r\n        if (!$post) {\r\n            throw $this-&amp;gt;createNotFoundException('O post n\u00E3o existe! Volte para home!');\r\n        }\r\n\r\n        return [\r\n            'post' =&amp;gt; $post,\r\n        ];\r\n    }\r\n \r\n    ...\r\n&lt;/pre&gt;\r\n\r\n&lt;h2&gt;Configurando o index&lt;/h2&gt;\r\n\r\nEm nossa index, estamos passando os links para que os posts sejam buscados pelo id, por\u00E9m temos que alter\u00E1- los para que possamos buscar os posts pelo slug.\r\nEntre no index.html.twig, caminho: src/Tableless/CoreBundle/Resources/views/IndexController/Index.html.twig\r\n\r\nVamos alterar os links: \r\nNo meu caso a linha 21, 29 e 35:\r\n\r\nde:\r\n&lt;pre class=\"lang-html\"&gt;\r\n&amp;lt;a href=\"{{ path('show', { 'id': post.id }) }}\"&amp;gt;\r\n&lt;/pre&gt;\r\n\r\npara:\r\n&lt;pre class=\"lang-html\"&gt;\r\n&amp;lt;a href=\"{{ path('show', { slug: post.slug }) }}\"&amp;gt;\r\n&lt;/pre&gt;\r\n\r\nTestando nossa aplica\u00E7\u00E3o:\r\n\r\nCaso tenham seguido o tutorial e exclu\u00EDdo o bando de dados, que foi criado novamente, como no meu caso. Antes de criarmos um post, temos que criar os autores novamente, depois sim criarmos os posts. No meu caso vou criar apena um post para exemplo.\r\nDepois do post criado, click no link e observe a url, ver\u00E1 o slug, que em nosso caso \u00E9 o slug do titulo, veja:\r\n\r\n&lt;a href=\"http://tableless.com.br/wp-content/uploads/2015/05/02.png\"&gt;&lt;img src=\"http://tableless.com.br/wp-content/uploads/2015/05/02.png\" alt=\"Urls\" width=\"750\" height=\"50\" class=\"alignnone size-full wp-image-48548\" /&gt;&lt;/a&gt;\r\n\r\n&lt;h2&gt;Conclus\u00E3o&lt;/h2&gt;\r\n\r\nPronto, nosso simples projeto est\u00E1 retornando o slug dos post em nossa url.\r\n\r\nLinks dos tutoriais anteriores:\r\n&lt;a href=\"http://tableless.com.br/iniciando-com-symfony-2/\" title=\"instala\u00E7\u00E3o\" target=\"_blank\"&gt;Iniciando com Symfony 2 \u2013 Instala\u00E7\u00E3o&lt;/a&gt;\r\n&lt;a href=\"http://tableless.com.br/iniciando-com-symfony-2-parte-02/\" title=\"parte 02\" target=\"_blank\"&gt;Iniciando com Symfony 2 \u2013 parte 02&lt;/a&gt;\r\n&lt;a href=\"http://tableless.com.br/iniciando-com-symfony-2-parte-03/\" title=\"parte 03\" target=\"_blank\"&gt;Iniciando com Symfony 2 \u2013 parte 03&lt;/a&gt;\r\n&lt;a href=\"http://tableless.com.br/iniciando-com-symfony-2-parte-04/\" title=\"parte 04\" target=\"_blank\"&gt;Iniciando com Symfony 2 \u2013 parte 04&lt;/a&gt;\r\n&lt;a href=\"http://tableless.com.br/iniciando-com-symfony-2-parte-05/\" title=\"parte 05\" target=\"_blank\"&gt;Iniciando com Symfony 2 \u2013 parte 05&lt;/a&gt;\r\n&lt;a href=\"http://tableless.com.br/iniciando-com-symfony-2-parte-06/\" title=\"parte 06\" target=\"_blank\"&gt;Iniciando com Symfony 2 \u2013 parte 06&lt;/a&gt;\r\n&lt;a href=\"http://tableless.com.br/iniciando-com-symfony-2-parte-07/\" title=\"parte 07\" target=\"_blank\"&gt;Iniciando com Symfony 2 \u2013 parte 07&lt;/a&gt;\r\n&lt;a href=\"http://tableless.com.br/iniciando-com-symfony-2-parte-08/\" title=\"parte 08\" target=\"_blank\"&gt;Iniciando com Symfony 2 \u2013 parte 08&lt;/a&gt;\r\n\r\nO projeto\u00A0encontra-se no &lt;a href=\"https://github.com/candidosouza/tableless\" title=\"github do projeto\" target=\"_blank\"&gt;GitHub&lt;/a&gt;!\r\n"^^<http://www.w3.org/2001/XMLSchema#string>
<http://tableless.com.br/iniciando-com-symfony-2-parte-09/>