.. index:: single: Templating Criando e usando Templates ============================ Como você sabe o :doc:`controller ` é responsável por controlar cada requisição que venha de uma aplicação Symfony2. Na realidade, o controller delega muito do trabalho pesado para outros lugares então aquele código pode ser testado e reusado. Quando um controller precisa gerar HTML, CSS e qualquer outro conteúdo, ele entrega o trabalho para o engine de template. Nesse capítulo, você irá aprender como escrever templates poderosas que podem ser usada para retornar conteúdo para o usuário, preencher corpo de e-mail, e mais. Você irá aprender atalhos, maneiras espertas de extender templates e como reusar código de template. .. index:: single: Templating;O que é um template? Templates --------- Um template é simplesmente um arquivo de texto que pode gerar qualquer formato baseado em texto (HTML, XML, CSV, LaTeX ...). O tipo mais familiar de template é um template em *PHP* - um arquivo de texto analisado pelo PHP que contém uma mistura de texto e código PHP::
{{ entry.body }}
{% endfor %} {% endblock %} .. code-block:: php extend('::base.html.php') ?> set('title', 'My cool blog posts') ?> start('body') ?>getBody() ?>
stop() ?> .. note:: O template pai é idenficado por uma sintaxe especial de string (``::base.html.twig``) que indica que o template reside no diretório ``app/Resources/views`` do projeto. Essa convenção de nomeamento é explicada inteiramente em :ref:`template-naming-locations`. A chave para herança template é a tag ``{% extends %}``. Ela avisa o engine de template para primeiro avaliar o template base, que configura o layout e define vários blocos. O template filho é então processado, ao ponto que os blocos ``title`` e ``body`` do template pai sejam substituídos por aqueles do filho. Dependendo do valor de ``blog_entries``, a saída poderia parecer com isso::The body of the first post.
The body of the second post.
{{ article.body }}
.. code-block:: phpgetBody() ?>
Incluir este template de qualquer outro template é fácil: .. configuration-block:: .. code-block:: html+jinja {# src/Acme/ArticleBundle/Resources/Article/list.html.twig #} {% extends 'AcmeArticleBundle::layout.html.twig' %} {% block body %}
.. code-block:: php
O principal propósito da função ``asset`` é tornar sua aplicação mais portátil.
Se sua aplicação reside na raiz do seu host (ex: http://example.com),
então os atalhos interpretados deveriam ser ``/images/logo.png``. Mas se sua aplicação
reside em um sub-diretório (ex: http://example.com/my_app), cada caminho do asset
deveria interpretar com o diretório (e.g. ``/my_app/images/logo.png``). A função
``asset`` toma conta disto ao determinar como sua aplicação está
sendo usada e gerando os atalhos de acordo com o correto.
Adicionalmente, se você usar função asset, Symfony pode automaticamente
anexar uma string de consulta para asset, em detrimento de garantir que assets
estáticos atualizados não serão armazenados quando distribuídos. Por exemplo, ``/images/logo.png`` poderia
parecer como ``/images/logo.png?v2``. Para mais informações, veja a opção de configuração
:ref:`ref-framework-assets-version`.
.. index::
single: Templating; Incluindo folhas de estilo e Javascripts
single: Folhas de estilo; Incluindo folhas de estilo
single: Javascripts; Incluindo Javascripts
Incluindo Folhas de Estilo e Javascript no Twig
---------------------------------------------
Nenhum site seria completo sem incluir arquivos Javascript e folhas de estilo.
Em Symfony, a inclusão desses assets é elegantemente manipulada ao tirar
vantagem das heranças de template do Symfony.
.. tip::
Esta seção irá ensinar você a filosofia por trás disto, incluindo folha de estilo
e asset Javascript em Symfony. Symfony também engloba outra biblioteca,
chamada Assetic, que segue essa filosofia mas também permite você fazer mais coisas
muito interessantes com esses assets. Para mais informações sobre
usar Assetic veja :doc:`/cookbook/assetic/asset_management`.
Comece adicionando dois blocos a seu template base que irá abrigar seus assets:
uma chamada ``stylesheets`` dentro da tag ``head`` e outra chamada ``javascripts``
justamente acima do fechamento da tag ``body``. Esses blocos irão conter todas as
folhas de estilo e Javascripts que você irá precisar através do seu site:
.. code-block:: html+jinja
{# 'app/Resources/views/base.html.twig' #}
{# ... #}
{% block stylesheets %}
{% endblock %}
{# ... #}
{% block javascripts %}
{% endblock %}
Isso é fácil o bastante ! Mas e se você precisar incluir uma folha de estilo ou
Javascript de um template filho ? Por exemplo, suponha que você tenha uma página
de contatos e você precise incluir uma folha de estilo ``contact.css`` *bem* naquela
página. Dentro do template da página de contatos, faça o seguinte:
.. code-block:: html+jinja
{# src/Acme/DemoBundle/Resources/views/Contact/contact.html.twig #}
{# extends '::base.html.twig' #}
{% block stylesheets %}
{{ parent() }}
{% endblock %}
{# ... #}
No template filho, você simplesmente sobrepõe o bloco ``stylesheets`` e
coloca sua nova tag de folha de estilo dentro daquele bloco. Claro, desde que você queira
adicionar ao conteúdo do bloco pai (e realmente não irá *substituí-lo), você
deveria usar a função ``parent()`` do Twig function para incluir tudo do bloco ``stylesheets``
do template base.
Você pode também incluir assets localizados em seus arquivos de pacotes ``Resources/public``.
Você precisará executar o comando``php app/console assets:install target [--symlink]`` ,
que move (ou symlinks) arquivos dentro da localização correta.
(target é sempre por padrão "web).
.. code-block:: html+jinja
O resultado final é uma página que inclui ambas as folhas de estilo
``main.css`` e ``contact.css``.
.. index::
single: Templating; O Serviço de Templating
Configurando e usando o Serviço ``templating``
------------------------------------------------
O coração do sistema de template em Symfony2 é o template ``Engine``.
Este objeto especial é responsável por manipular templates e retornar
o conteúdo deles. Quando você manipula um template em um controller, por exemplo,
você está na verdade usando o serviço do template engine. Por exemplo:
.. code-block:: php
return $this->render('AcmeArticleBundle:Article:index.html.twig');
é equivalente a:
.. code-block:: php
$engine = $this->container->get('templating');
$content = $engine->render('AcmeArticleBundle:Article:index.html.twig');
return $response = new Response($content);
.. _template-configuration:
O engine de template (ou "serviço") é pré-configurada para trabalhar automaticamente
dentro de Symfony2. Ele pode, claro, ser configurado mais adiante no arquivo
de configuração da aplicação:
.. configuration-block::
.. code-block:: yaml
# app/config/config.yml
framework:
# ...
templating: { engines: ['twig'] }
.. code-block:: xml
{{ entry.body }}
{% endfor %} {% endblock %} Perceba que este template estende a template de sessão - (``AcmeBlogBundle::layout.html.twig``) que por sua vez estende o layout de aplicação base (``::base.html.twig``). Isso é o modelo comum de herança de três níveis. Quando construir sua aplicação, você pode escolher seguir esse método ou simplesmente tornar cada template de página estender a template de aplicação base diretamente (ex: ``{% extends '::base.html.twig' %}``). O modelo de três templates é o método de melhor prática usado por vendor bundles então aquele template base para um pacote pode ser facilmente sobreposto para propriamente estender seu layout base de aplicação. .. index:: single: Templating; Saída para escape Saída para escape --------------- Quando gerar HTML de um template, sempre há um risco que uma variável de template pode gerar HTML involutário ou codigo do lado cliente perigoso. O resultado é que o conteúdo dinâmico poderia quebrar o HTML de uma página de resultados ou permitir um usuário maldoso realizar um ataque `Cross Site Scripting`_ (XSS). Considere esse exemplo clássico: .. configuration-block:: .. code-block:: jinja Hello {{ name }} .. code-block:: php Hello Imagine que o usuário entre o seguinte código como o nome dele/dela:: Sem qualquer outra saída de escape, o resultado da template irá causar uma caixa de alerta em JavaScript para saltar na tela:: Hello E enquanto isso parece inofensivo, se um usuário pode chegar tão longe, o mesmo usuário deveria também ser capaz de escrever Javascript que realiza ações maliciosas dentro de uma área segura de um usuário legítimo e desconhecido. A resposta para o problema é saída para escape. Sem a saída para escape ativa, o mesmo template irá manipular inofensivamente, e literalmente imprimir a tag ``script`` na tela:: Hello <script>alert('helloe')</script> Os sistemas de templating Twig e PHP aproximam-se do problema de formas diferentes. Se você está usando Twig, saída para escape é ativado por padrão e você está protegido. Em PHP, saída para escape não é automático, significando que você precisará manualmente fazer o escape quando necessário. Saída para escape em Twig ~~~~~~~~~~~~~~~~~~~~~~~~~ Se você está usando templates Twig, então saída para escape é ativado por padrão. Isto significa que você está protegido externamente de consequencias acidentais por código submetido por usuário. Por padrão, a saída para escape assume que o conteúdo está sendo escapado pela saída HTML. Em alguns casos, você precisará desabilitar saída para escape quando você está manipulando uma variável que é confiável e contém marcação que não poderia ter escape. Suponha que usuários administrativos são capazes de escrever artigos que contenham código HTML. Por padrão, Twig irá escapar o corpo do artigo. Para fazê-lo normalamente, adicione o filtro ``raw``: ``{{ article.body | raw }}``. Você pode também desabilitar saída para escape dentro de uma área ``{% block %}`` ou para um template inteiro. Para mais informações, veja `Output Escaping`_ na documentação do Twig. Saída para escape em PHP ~~~~~~~~~~~~~~~~~~~~~~~~ Saída para escape não é automática quando usamos templates PHP. Isso significa que a menos que você escolha escapar uma variável explicitamente, você não está protegido. Para usar saída para escape use o método de view ``escape()``:: Hello escape($name) ?> Por padrão, o método ``escape()`` assume que a variável está sendo manipulada dentro de um contexto HTML (e assim a variável escapa e está segura para o HTML). O segundo argumento deixa você mudar o contexto. Por exemplo, para gerar algo em uma string Javascript, use o contexto ``js`` : .. code-block:: js var myMsg = 'Hello escape($name, 'js') ?>'; .. index:: single: Templating; Formats .. _template-formats: Debugging --------- .. versionadded:: 2.0.9 Esta funcionalidade está disponível no Twig ``1.5.x``, e foi adicionada primeiramente no Symfony 2.0.9. Ao utilizar o PHP, você pode usar o ``var_dump()`` se precisa encontrar rapidamente o valor de uma variável passada. Isso é útil, por exemplo, dentro de seu controlador. O mesmo pode ser conseguido ao usar o Twig com a extensão de depuração. Esta extensão precisa ser ativada na configuração: .. configuration-block:: .. code-block:: yaml # app/config/config.yml services: acme_hello.twig.extension.debug: class: Twig_Extension_Debug tags: - { name: 'twig.extension' } .. code-block:: xml