Template engines
LidoEsta aula explora a importância das template engines no desenvolvimento PHP, apresentando conceitos como separação de responsabilidades, escape automático e segurança. Você aprenderá a diferença entre Twig e Blade, e como usá-los para criar views limpas e seguras, com exemplos práticos e exercícios para fixar o conteúdo.
Bem-vindo à aula sobre template engines no PHP! Nesta aula, vamos mergulhar no mundo das engines de template, ferramentas essenciais para qualquer desenvolvedor PHP moderno. Você já deve ter visto código PHP misturado com HTML, o famoso 'spaghetti code', onde a lógica e a apresentação se misturam de forma confusa. As template engines resolvem esse problema, separando a lógica de negócio da camada de apresentação, tornando o código mais limpo, seguro e fácil de manter.
Ao longo desta aula, você vai entender por que usar uma template engine, conhecer as duas principais do ecossistema PHP (Twig e Blade), aprender sobre o escape automático de dados e como organizar suas views de forma eficiente. Vamos explorar exemplos práticos e ao final teremos exercícios para consolidar o conhecimento. Prepare-se para elevar seu nível de desenvolvimento PHP!
Por que usar
Em projetos PHP tradicionais, é comum encontrar arquivos que misturam HTML e PHP, como este:
<?php
$users = ['João', 'Maria', 'Pedro'];
?>
<h1>Lista de Usuários</h1>
<ul>
<?php foreach ($users as $user): ?>
<li><?php echo $user; ?></li>
<?php endforeach; ?>
</ul>Esse código funciona, mas rapidamente se torna difícil de manter. Quando o designer precisa alterar o layout, ele precisa navegar por lógica de negócio. Quando o programador precisa ajustar a lógica, ele se perde no HTML. Além disso, a segurança é uma preocupação: sem um sistema de escape automático, é fácil esquecer de escapar dados do usuário, abrindo brechas para ataques XSS (Cross-Site Scripting).
As template engines resolvem esses problemas oferecendo:
- Separação de responsabilidades: a lógica fica no controlador/modelo, e a apresentação fica nos templates.
- Sintaxe simplificada: comandos como
foreacheiftêm uma versão mais limpa e legível. - Escape automático: as engines escapam as variáveis por padrão, protegendo contra XSS.
- Herança de templates: permite criar layouts base e estender em páginas específicas, evitando repetição de código.
- Componentes e partials: reutilização de blocos de interface.
Além disso, as engines são mais rápidas em produção, pois compilam os templates para PHP puro, que é cacheado. Isso significa que o desempenho não é sacrificado; pelo contrário, pode até melhorar em comparação com a execução de muitos blocos PHP.
Twig/Blade (visão geral)
No ecossistema PHP, duas template engines se destacam: Twig e Blade. Ambas são poderosas, mas têm filosofias ligeiramente diferentes.
Twig é uma engine independente, criada por Fabien Potencier (o mesmo criador do Symfony). Ela é usada em muitos projetos, incluindo o Symfony e o Drupal 8+. Twig tem uma sintaxe limpa e segura, com recursos como herança de templates, blocos, macros e filtros. Sua documentação é excelente e é muito popular fora do mundo Laravel.
Exemplo de template Twig:
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}Página Inicial{% endblock %}</title>
</head>
<body>
<h1>Olá, {{ nome }}!</h1>
<ul>
{% for item in itens %}
<li>{{ item }}</li>
{% endfor %}
</ul>
</body>
</html>Blade é a engine nativa do Laravel. Ela é muito intuitiva, permitindo que você use PHP puro dentro dos templates, mas também oferece uma sintaxe elegante com {{ }} para exibir dados e @if, @foreach para controle de fluxo. Blade compila os templates para PHP puro e os armazena em cache, tornando a execução rápida. Uma diferença importante é que Blade não escapa automaticamente quando você usa a sintaxe de chave dupla {{ }}, mas escapa quando usa {{!! !!}}? Na verdade, {{ }} escapa, e {!! !!} não escapa (para dados já confiáveis).
Exemplo de template Blade:
<!DOCTYPE html>
<html>
<head>
<title>@yield('title', 'Página Inicial')</title>
</head>
<body>
<h1>Olá, {{ $nome }}!</h1>
<ul>
@foreach ($itens as $item)
<li>{{ $item }}</li>
@endforeach
</ul>
</body>
</html>Ambas as engines suportam herança de templates, permitindo que você defina um layout base e estenda em páginas específicas. Por exemplo, com Twig você usa {% extends 'base.html.twig' %} e {% block content %}{% endblock %}. Com Blade, você usa @extends('layouts.app') e @section('content').
A escolha entre Twig e Blade depende do seu projeto: se você está usando Laravel, Blade é natural; se está usando Symfony ou um framework independente, Twig é uma excelente opção. Ambas são maduras e bem documentadas.
Escape automático
Um dos maiores benefícios das template engines é o escape automático de saída. Isso significa que, por padrão, qualquer variável exibida no template é escapada, ou seja, caracteres especiais como <, >, & e aspas são convertidos em entidades HTML seguras. Isso previne ataques de Cross-Site Scripting (XSS), onde um usuário mal-intencionado injeta scripts maliciosos através de inputs.
Em PHP puro, você precisaria fazer manualmente:
<?php echo htmlspecialchars($userInput, ENT_QUOTES, 'UTF-8'); ?>Com Twig, basta usar {{ userInput }} e o escape é automático. Se você precisar exibir conteúdo HTML que já é seguro (por exemplo, vindo de um editor rich text), pode usar o filtro |raw:
{{ conteudoHtml | raw }}No Blade, o mesmo comportamento: {{ $userInput }} escapa, e {!! $conteudoHtml !!} não escapa. É importante ter cuidado ao usar raw ou {!! !!}, apenas com dados que você confia plenamente, como conteúdo gerado pelo próprio sistema.
Além disso, as engines oferecem filtros para formatação, como escape, upper, lower, date, etc. No Twig, você pode aplicar filtros com |, como {{ nome | upper }}. No Blade, você pode usar funções PHP diretamente, como {{ strtoupper($nome) }}, mas também há diretivas próprias.
O escape automático é uma prática de segurança fundamental. Ao usá-lo, você reduz drasticamente o risco de vulnerabilidades XSS em suas aplicações, tornando-as mais robustas.
Separação de view
A separação de view é o princípio de manter a lógica de apresentação (HTML, CSS, JavaScript) em arquivos de template separados da lógica de negócio (PHP). Isso é conhecido como MVC (Model-View-Controller), e as template engines são o 'V' (View) nesse padrão.
Na prática, isso significa que seus controladores preparam os dados e passam para a view, que apenas exibe esses dados. Por exemplo, em Laravel, um controlador pode fazer:
public function index()
{
$users = User::all();
return view('users.index', compact('users'));
}E a view users/index.blade.php seria algo como:
<h1>Lista de Usuários</h1>
<ul>
@foreach ($users as $user)
<li>{{ $user->name }}</li>
@endforeach
</ul>Isso traz benefícios enormes:
- Manutenibilidade: é fácil localizar e alterar o HTML sem mexer na lógica.
- Colaboração: designers podem trabalhar nos templates sem conhecer PHP profundo.
- Testabilidade: você pode testar a lógica separadamente da apresentação.
- Reutilização: componentes de interface podem ser reutilizados em várias páginas.
Além disso, as template engines permitem criar layouts e partials. Por exemplo, você pode ter um layout base com cabeçalho, menu e rodapé, e cada página apenas preenche o conteúdo. Isso evita repetição e garante consistência visual.
Em Twig, você pode incluir partials com {% include 'header.html.twig' %} e usar herança com {% extends %}. Em Blade, você usa @include('partials.header') e @extends('layouts.app').
A separação de views também ajuda na organização de projetos grandes, onde você pode ter pastas para cada módulo, cada uma com suas views específicas. Isso torna o código mais previsível e escalável.
Boas práticas
Ao trabalhar com template engines, siga estas boas práticas:
- Nunca use
rawou{!! !!}sem necessidade: sempre escape a menos que você tenha certeza absoluta de que o conteúdo é seguro. - Mantenha os templates enxutos: evite lógica complexa nos templates; a lógica deve estar nos controladores ou serviços.
- Use herança de templates: crie layouts base e estenda para cada página, reduzindo duplicação.
- Nomeie os templates de forma clara: use convenções como
users/index.blade.phpouusers/index.html.twig. - Aproveite os filtros e funções: em vez de manipular strings no PHP, use filtros como
date,upper, etc.
Seguir essas práticas fará seu código mais profissional, seguro e fácil de manter.
Exercícios
- Exercício 1: Explique por que o escape automático é importante e dê um exemplo de como ele previne XSS em um template Twig.
- Exercício 2: Crie um template Blade que exiba uma lista de produtos com seus preços, usando a diretiva
@foreache escape automático. - Exercício 3: Qual a diferença entre
{{ }}e{!! !!}no Blade? Quando você deve usar cada um? - Exercício 4: Como você criaria um layout base com Twig e estenderia em uma página específica? Mostre o código do layout e da página.
- Exercício 5: Liste três benefícios de separar a view da lógica de negócio e explique cada um.
<script>alert('xss')</script> como nome, ao exibir com {{ nome }}, Twig escapa para <script>alert('xss')</script>, que é exibido como texto, não executado.<ul>
@foreach ($produtos as $produto)
<li>{{ $produto->nome }} - R$ {{ number_format($produto->preco, 2, ',', '.') }}</li>
@endforeach
</ul>{{ }} escapa a saída (protegendo contra XSS), enquanto {!! !!} não escapa, permitindo HTML bruto. Use {{ }} para dados do usuário ou não confiáveis; use {!! !!} apenas para conteúdo que você confia, como HTML gerado pelo sistema.Layout (base.html.twig):
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}Meu Site{% endblock %}</title>
</head>
<body>
{% block content %}{% endblock %}
</body>
</html>
Página (home.html.twig):
{% extends 'base.html.twig' %}
{% block title %}Página Inicial{% endblock %}
{% block content %}
<h1>Bem-vindo!</h1>
{% endblock %}