A View ====== Depois de ler a primeira parte desse tutorial, você decidiu que o Symfony2 vale pelo menos mais 10 minutos? Boa escolha! Nessa segunda parte, você vai aprender sobre o sistema de template do Symfony2, o `Twig`_. Ele é um sistema de templates para PHP flexível, rápido e seguro. Ele faz com que seus templates sejam mais legíveis e concisos e também os torna mais amigáveis para os web designers. .. note:: Em vez do Twig, você também pode usar :doc:`PHP ` para os seus templates. Ambos são suportados pelo Symfony2. Familiarizando-se com o Twig ---------------------------- .. tip:: Se quiser aprender a usar o Twig, nós recomendamos fortemente que leia a `documentação`_ oficial dele. Essa seção é apenas uma visão geral sobre os principais conceitos. Um template Twig é um arquivo de texto que pode gerar qualquer tipo de conteúdo (HTML, XML, CSV, LaTex, ...). O Twig define dois tipos de delimitadores: * ``{{ ... }}``: Imprime uma variável ou o resultado de uma expressão; * ``{% ... %}``: Controla a lógica do template; é usado para executar loops ``for`` e instruções ``if``, por exemplo. Abaixo temos um template mínimo que ilustra alguns comandos básicos usando as duas váriaveis, ``page_title`` e ``navigation``, que são passadas para o template: .. code-block:: html+jinja My Webpage

{{ page_title }}

.. tip:: Podem ser incluídos comentários nos templates usando o delimitador ``{# ... #}``. Para renderizar um template no Symfony, use o método ``render`` a partir do controller, e passe para ele todas as variávels necessárias ao template:: $this->render('AcmeDemoBundle:Demo:hello.html.twig', array( 'name' => $name, )); As variáveis passadas para o template podem ser strings, arrays ou até objetos. O Twig abstrai a diferença entre eles e deixa acessar os "atributos" de uma variável usando dot notation (``.``): .. code-block:: jinja {# array('name' => 'Fabien') #} {{ name }} {# array('user' => array('name' => 'Fabien')) #} {{ user.name }} {# force array lookup #} {{ user['name'] }} {# array('user' => new User('Fabien')) #} {{ user.name }} {{ user.getName }} {# force method name lookup #} {{ user.name() }} {{ user.getName() }} {# pass arguments to a method #} {{ user.date('Y-m-d') }} .. note:: É importante saber que as chaves não fazem parte da variável mas sim do comando de impressão. Se você acessar variáveis em tags não coloque as chaves em volta delas. Decorando os Templates ---------------------- É frequente em um projeto que os templates compartilhem elementos comuns, como os bem-conhecidos cabeçalho e rodapé. No Symfony2, gostamos de enxergar essa situação de uma forma diferente: um template pode ser decorado por outro. Funciona exatamente do mesmo jeito que nas classes PHP: a herança de templates permite que se construa o template base "layout", que contém todos os elementos comuns do seu site, e define "blocos" que os templates filhos podem sobrescrever. O template ``hello.html.twig`` herda do ``layout.html.twig``, graças a tag ``extends``: .. code-block:: html+jinja {# src/Acme/DemoBundle/Resources/views/Demo/hello.html.twig #} {% extends "AcmeDemoBundle::layout.html.twig" %} {% block title "Hello " ~ name %} {% block content %}

Hello {{ name }}!

{% endblock %} A notação ``AcmeDemoBundle::layout.html.twig`` parece familiar, não é mesmo? Ela é a mesma notação usada para referenciar um template normal. A parte ``::`` significa simplesmente que o elemento controller está vazio, então o arquivo correspondente é guardado diretamente no diretório ``Resources/views/``. Agora, vamos dar uma olhada em um ``layout.html.twig`` simplificado: .. code-block:: jinja {# src/Acme/DemoBundle/Resources/views/layout.html.twig #}
{% block content %} {% endblock %}
As tags ``{% block %}`` definem blocos que os templates filhos podem preencher. Tudo o que essas tags fazem é dizer ao sistema de template que um filho pode sobrescrever aquelas partes de seu template pai. Nesse exemplo, o template ``hello.html.twig` sobrescreve o bloco ``content``, que significa que o texto "Hello Fabien" é renderizado dentro do elemento ``div.symfony-content`` Usando Tags, Filtros e Funções ------------------------------ Uma das melhores funcionalidades do Twig é sua extensibilidade por meio de tags, filtros e funções. O Symfony2 já vem com muitos desses embutidos facilitando o trabalho do designer de templates. Incluindo outros Templates ~~~~~~~~~~~~~~~~~~~~~~~~~~ A melhor forma de compartilhar um trecho de código entre vários templates distintos é criar um novo desses que possa ser incluído nos outros. Crie um template ``embedded.html.twig``: .. code-block:: jinja {# src/Acme/DemoBundle/Resources/views/Demo/embedded.html.twig #} Hello {{ name }} E altere o template ``index.html.twig`` para incluí-lo: .. code-block:: jinja {# src/Acme/DemoBundle/Resources/views/Demo/hello.html.twig #} {% extends "AcmeDemoBundle::layout.html.twig" %} {# override the body block from embedded.html.twig #} {% block content %} {% include "AcmeDemoBundle:Demo:embedded.html.twig" %} {% endblock %} Incorporando outros Controllers ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ E o que fazer se você quiser incorporar o resultado de um outro controller em um template? Isso é muito útil quando estiver trabalhado com Ajax, ou quando o template incorporado precisa de alguma variável que não está disponível no template principal. Suponha que você tenha criado uma action ``fancy``, e quer incluí-la dentro do template ``index``. Para fazer isso, use a tag ``render``: .. code-block:: jinja {# src/Acme/DemoBundle/Resources/views/Demo/index.html.twig #} {% render "AcmeDemoBundle:Demo:fancy" with { 'name': name, 'color': 'green' } %} Aqui, a string ``AcmeDemoBundle:Demo:fancy`` se refere a action ``fancy`` do controller ``Demo``. Os argumentos (``name``e ``color``) agem como variáveis de requisições simuladas (como se ``fancyAction`` estivesse manipulando uma requisição totalmente nova) e ficam disponíveis para o controller:: // src/Acme/DemoBundle/Controller/DemoController.php class DemoController extends Controller { public function fancyAction($name, $color) { // create some object, based on the $color variable $object = ...; return $this->render('AcmeDemoBundle:Demo:fancy.html.twig', array('name' => $name, 'object' => $object)); } // ... } Criando Links entre Páginas ~~~~~~~~~~~~~~~~~~~~~~~~~~~ Quando estamos falando de aplicações web, a criação de links entre páginas é uma obrigação. Em vez de fazer "hardcode" das URLS nos templates, usamos a função ``path`` que sabe como gerar URLs baseando-se na configuração das rotas. Dessa forma, todas as URLs podem ser atualizadas facilmente apenas mudando essa configuração: .. code-block:: html+jinja Greet Thomas! A função ``path`` pega o nome da rota e um array de parâmetros como argumentos. O nome da rota é a chave principal sob a qual as rotas são referenciadas e os parâmetros são os valores dos marcadores definidos no padrão da rota:: // src/Acme/DemoBundle/Controller/DemoController.php use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; /** * @Route("/hello/{name}", name="_demo_hello") * @Template() */ public function helloAction($name) { return array('name' => $name); } .. tip:: A função ``url`` cria URLs *absolutas*: ``{{ url('_demo_hello', { 'name': 'Thomas' }) }}``. Incluindo Assets: imagens, JavaScripts e folhas de estilo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ O que seria da Internet sem as imagens, os JavaScripts e as folhas de estilo? O Symfony2 fornece a função ``asset`` para lidar com eles de forma fácil: .. code-block:: jinja O objetivo principal da função ``asset`` é deixar sua aplicação mais portátil. Graças a ela, você pode mover o diretório raiz da aplicação para qualquer lugar no diretório web root sem mudar nem uma linha no código de seus templates. Escapando Variáveis ------------------- O Twig é configurado por padrão para escapar automaticamente toda a saída de dados. Leia a `documentação`_ do Twig para aprender mais sobre como escapar a saída de dados e sobre a extensão Escaper. Considerações Finais -------------------- O Twig é simples mas poderoso. Graças a inclusão de layouts, blocos, templates e actions, é muito fácil organizar seus templates de uma maneira lógica e extensível. No entanto se você não estiver confortável com o Twig sempre poderá usar templates PHP no Symfony sem problemas. Você está trabalhando com o Symfony2 há apenas 20 minutos, mas já pode fazer coisas incríveis com ele. Esse é o poder do Symfony2. Aprender a base é fácil, e logo você aprenderá que essa simplicidade está escondida debaixo de uma arquitetura muito flexível. Mas eu já estou me adiantando. Primeiro, você precisa aprender mais sobre o controller e esse é exatamente o assunto da :doc:`próxima parte do tutorial`. Pronto para mais 10 minutos de Symfony2? .. _Twig: http://twig.sensiolabs.org/ .. _documentação: http://twig.sensiolabs.org/documentation