Já demonstrei em tópicos anteriores que o Zend_View é um ótimo componente para facilitar a nossa camada view de um projeto MVC. Porém, ela não é a única: de fato, esse tipo de sistema é o que não falta para PHP, e o Smarty é uma das que se destaca.
O Smarty é uma biblioteca de template que facilita a aplicação do modelo MVC, que permite a separação do HTML e do PHP, facilitando o trabalho dos designers, que não precisam conhecer a linguagem para poder alterar o visual do site. Outras vantagens do Smarty:
- É rápido: evita o overhead que muitos sistemas de template têm, pois compila apenas uma vez
- É facilmente configurável: com pouco código podemos especificar onde estão as pastas necessárias para o funcionamento, as tags delimitadores (por padrão são “{}”), etc.
- É extensível: podemos facilmente criar plugins, e portanto, podemos adequá-lo ao nosso projeto
Primeiros Passos
- Baixe a última versão estável do Smarty e extraia para uma pasta separada.
- Crie uma pasta separada para o nosso projeto, e detro dela crie uma pasta chamada Smarty
- Da pasta extraída, copie o que está dentro da pasta lib/ para a pasta Smarty do nosso projeto
- Na pasta do projeto, crie as pastas ‘templates’, ‘templates_c’, ‘configs’ e ‘cache’
- Crie um arquivo index.php, ainda sem nada
- Crie um arquivo index.tpl, também sem nada
Deve ficar assim:

Apenas lembrando: eu estou usando essa estrutura apenas para facilitar as chamadas, tanto que não é recomendável deixar essas pastas na raíz. Eu poderia ter chamado o Smarty de fora do projeto, ter outros nomes de pastas auxiliares e deixá-los em outros lugares também, mas deixei assim mesmo porque a minha intenção era apenas simplificar a explicação.
Entendendo
Temos a pasta ‘Smarty’, que possui todos os arquivos da biblioteca, e temos outras 4 pastas que são usadas pelo Smarty com diferentes objetivos:
- cache: pasta usada pelo Smarty para armazenar os arquivos usados quando a opção de cache está habilitada
- configs: pasta que deve conter os arquivos de configuração ‘.conf’
- templates: pasta em que devem estar os arquivos ‘.tpl’, onde ficam os códigos html e do próprio smarty
- templates_c: pasta usada pelo Smarty para armazenar as páginas compiladas
Lembrando que eu uso esses nomes porque são ‘padrões’ de quem usa o Smarty, mas podemos muito bem alterar os nomes na hora de configurá-lo.
Mãos à obra
Vamos então fazer um pouco de código: primeiro temos que chamar o Smarty e configurá-lo, e farei isso em uma classe isolada, apenas para não precisar fazer isso em todas as páginas que usaremos o Smarty:
<?php
require('Smarty/Smarty.class.php');
class Meu_Smarty extends Smarty {
public function Meu_Smarty()
{
$this->Smarty();
$this->template_dir = 'templates';
$this->compile_dir = 'templates_c';
$this->cache_dir = 'cache';
$this->config_dir = 'configs';
$this->left_delimiter = '{{';
$this->right_delimiter = '}}';
}
}
Agora, a página index.php, que fazemos a chamada à classe e configuramos uma variável que chamaremos no tpl:
<?php
require('smarty.php');
$smarty = new Meu_Smarty();
// aqui dizemos que quermos uma variável chamada 'name' com o valor 'World'
$smarty->assign('name', 'World');
// especificamos o nome do tpl que será usado
$smarty->display('index.tpl');
?>
E finalmente o arquivo .tpl:
<html>
<head>
<title>Tutorial Smarty - Index
</head>
<body>
Hello {{$name}}!
</body>
</html>
Nada de muito trabalhoso: no index.php ‘dizemos’ ao Smarty para reconhecer uma variável chamada $nome, e no tpl chamamos-a.
Dificultando o nosso exemplo
Vamos a um processo mais difícil, mas também mais comum: queremos pegar dados de um banco de dados. Eu não vou entrar no mérito de conectar ao banco e tudo mais, mas normalmente quando fazemos isso, recebemos um array e usamos ele para mostrar os dados… então farei apenas isso, sem mudar o foco para o banco.
No index.php, teremos:
$resultado_banco = array(
array(
'id' => 1,
'name' => 'Diego'
),
array(
'id' => 2,
'name' => 'Tiago'
),
array(
'id' => 3,
'name' => 'Paulo'
)
);
$smarty->assign('resultado', $resultado_banco);
e no index.tpl:
<table>
<tr>
<th>ID</th>
<th>Nome</th>
</tr>
{{section name="i" loop=$resultado}}
<tr>
<td>{{$resultado[i].id}}</td>
<td>{{$resultado[i].name}}</td>
</tr>
{{/section}}
</table>
A grande diferença foi que usamos um comando pronto do Smarty, o {section}. Ele faz a função do loop no template, de forma que houve a iteração na variável $resultado, que era o array de resultados.
Uma coisa que precisa ser observada é a regra dos arrays no tpl, que no nosso exemplo foi o “{{$resultado[i].name}}”. A primeira vez que vi isso me perguntei “por que não {{$resultado[i]['name']}}, ou {{$resultado.i.name}}??”, mas bastou notar que ele trata índices numéricos com os conchetes e índices não numéricos com o ponto: aquele ‘i’ não é uma variável de fato, apenas um identificador de qual índice do array está sendo iterado no momento, enquanto que o ‘nome’ é o nome do índice que queremos pegar.
Conclusão
Acaba por aqui a primeira parte sobre o Smarty. Mostrei o básico, para quem não conhece, de como usar um ótimo sistema de templates para facilitar o uso das suas views, de maneira a desenvolver sem ficar aquele amontoado de código php junto do html.
Futuramente devo falar sobre coisas mais específicas do Smarty, como o uso do cache, arquivos de configuração e como criar plugins, recurso importantíssimo para estender o smarty com funcionalidades mais específicas.
Até a próxima!
novembro 19th, 2009 at 22:33 #Tiago
Ola senhor Diego, eu sou um pretendente a leitor do seus pots!
Mas para tanto vc precisa escrever sobre php+jquery+zend
Desde já agradeço!
dezembro 22nd, 2009 at 18:06 #Denes
Olá Diego, blz?
Kra tô fuçando o google pra aprender como integrar o smarty com o zend fw(versões atuais), mas só encontrei posts antigos. Gostaria de saber se vc não poderia postar um artigo sobre isso.
janeiro 18th, 2010 at 15:26 #Smarty: Sistema de Templates em PHP (Parte 2) - Diego Jeronymo
[...] do post passado, agora vou tratar de assuntos mais específicos do Smarty: arquivos de configuração e algo sobre [...]
fevereiro 2nd, 2012 at 19:54 #Broken Gold Buyer OKC
Yep….
I couldn’t have said it better myself……