Curioso depois da palestra Smarty 3 – O Céu é o Limite! na PHP Conf 2009, resolvi dar uma checada na versão desse sistema de templates que tanto gosto e costumo usar em meus projetos. Primeiro, vou falar um pouco sobre o que foi falado na palestra e que está no arquivo de apresentação, que foi disponibilizado aqui pelo autor. Depois, algumas observações e opiniões de algumas pesquisadas pela internet a fora e fuçadas.
Obs.: esse post foi feito para falar do Smarty 3 beta 5, ou seja, algumas mudanças e melhorias podem acontecer conforme o projeto ficar mais maduro.
Novidades
A maioria dessas novidades estão no slide, mas vou falar um pouco de cada:
Melhoria no sistema de plugins: só olhando para o esquema de diretórios do smarty, e podemos ver que está diferente: agora, tem uma pasta para plugins comuns, como já havia antes, e plugins do sistema. Nos plugins do sistema, podemos encontrar todo o código interno do smarty, incluindo métodos chamados no Smarty.class.php e funções internas do template como {foreach}.
Novo sistema de Cache: agora podemos especificar setar o caching como true e dizer que algumas partes não queremos que o cache seja usado, com a tag {nocache}. Chegaram até a perguntar durante a palestra se dava pra fazer o contrário, e setar apenas onde queremos que tenha cache, mas infelizmente não é possivel.
Templates como código PHP embutido: tem alguns templates em PHP puro e não quer reescrever para a linguagem smarty? Sem problemas, agora isso é possível, sem fazer nenhuma alteração se quer no template:
$smarty->display('php:template.php');
Por conta disso, a tag {php} agora foi desabilitada por padrão. Para compatibilidade com Smarty 2, ela pode ser habilitada com $smarty->allow_php_tag=true.
Total compatibilidade com Javascript, CSS, Jquery, etc.: atire a primeira pedra quem nunca ficou nervoso porque o parser do smarty dava erro quando encontrava as chaves de CSS e Javascript e precisava do {literal}{/literal} ou então mudar os delimitadores … no Smarty 3 não precisamos mais disso: agora ele só interpreta como tag própria se não tiver espaço depois e se tiver, é ignorado;
Código mais próximo da linguagem PHP: tags como {foreach} foram alteradas e usam a mesma sintaxe do PHP. Foram adicionados controles mais próximos do PHP também, como {else if}, {while} e {for}. Outro exemplo é que o {assign} não é mais necessário, já que podemos usar uma atribuição igual a que usamos no PHP. Por exemplo:
{$mensagem = "Data atual"}
{$data = $smarty.now|date_format:"%d/%m/%Y %H:%M:%S"}
{$mensagem = "$mensagem: $data"}
Inclusão de diretórios de templates: podemos agora definir diversas pastas para templates com as funções setTemplateDir() e addTemplateDir(). A primeira recebe um array de diretórios, enquanto a segunda recebe um valor único que pode ser tanto string quanto array e que é adicionado ao array de templates. Na hora de encontrar algum arquivo, ele é buscado do primeiro diretório encontrado ao último.
Funções dentro de templates: é possível agora definirmos funções em templates, para reuso de código. Um exemplo:
{function name=menu level=0}
<ul class="level{$level}">
{foreach $data as $entry}
{if is_array($entry)}
<li>{$entry@key}</li>
{menu data=$entry level=$level+1}
{else}
<li>{$entry}</li>
{/if}
{/foreach}
</ul>
{/function}
{$menu = ['item1','item2','item3' => ['item3-1','item3-2','item3-3' =>
['item3-3-1','item3-3-2']],'item4']}
{menu data=$menu}
Ou seja: {function} tem apenas o atributo name como obrigatório, e podemos ter vários adicionais; para chamar uma função, devemos usar uma tag com o mesmo nome da função (no exemplo, foi menu), e por isso deve ser usado apenas nomes não usados em tags do próprio smarty.
Herança de Templates: bem, esse não estava no slide, mas achei que é uma novidade interessante, que outros sistemas de templates já tinham. A herança de templates consiste em ter um template com blocos que pode ser alterado por outros templates filhos, assim como quando estendemos classes com o PHP normal. No Smarty 2 isso não era possível, mas essa necessidade era resolvida com o {include}.
O Smarty possibilita fazer isso de 2 maneiras. A primeira:
base.tpl:
<html>
<head>
<title>{block name="title"}default{/block}</title>
{block name="head"}{/block}
</head>
<body>
{block name="body"}{/block}
</body>
</html>
page.tpl:
{extends file="base.tpl"}
{block name="title"} my title {/block}
{block name="head"} <!-- insert js/css here --> {/block}
{block name="body"} <!-- insert content here --> {/block}
content.tpl:
{extends file="page.tpl"}
{block name="body"} <h1>Some Content</h1> {/block}
Chamando o content.tpl no display() do smarty, temos como resultado:
<html> <head> <title> my title </title> <!-- insert js/css here --> </head> <body> <h1>Some Content</h1> </body> </html>
Esclarecendo, temos 2 novas tags envolvidas: {extends} e {block}. O {extends} serve que nem o extends para classes php, você indica ao filho qual o template que ele herdará. Já o {block} é um pedaço de código no qual o conteúdo do template que está sendo gerado é sobreposto sempre que um filho tiver um conteúdo diferente. Analisando o resultado final isso fica evidente: sempre que o filho teve um {block} com o mesmo nome, o conteúdo foi trocado. Além disso, pudemos ver no content.tpl que não é necessário que todos os blocos sejam alterados.
Porém, como eu falei anteriormente, podemos fazer de outro jeito:
$smarty->display('extends:base.tpl|page.tpl|content.tpl');
Nesse caso, não precisaríamos usar o {extends} nos tpls, definindo dinâmicamente a herança dentro do próprio PHP.
Primeiras Impressões
Gostei de algumas facilidades que a nova versão proporciona, como não precisar mais do {literal}, a atualização do próprio sistema de templates, e a compatibilidade com a versão 2.
Mas nem tudo também me agradou. A grande expectativa minha para essa versão era justamente a melhora de performance. Ok, eu não criei benchmarks para poder provar com números, mas fiquei até preocupado quando li esse post do fórum do Smarty e alguns poucos comentários pela web a fora de que o Smarty 3 é mais lento ou pelo menos igual ao Smarty 2 nesse sentido. A esperança é que, como ainda é uma versão beta, isso ainda possa ser melhorado.
Outra coisa que eu esperava do smarty era que ele passasse a ficar mais parecido com uma linguagem de marcação, como me parece ser a tendência, ao invés de se aproximar cada vez mais do que já temos no PHP. Quero dizer, será que é realmente vantajoso tornar a compilação mais lenta com a interpretação do PHP no Smarty para continuar escrevendo códigos imperativos dentro da parte de visualização?
E por fim, temos a falta de documentação da nova versão no site. A única coisa que achei deles foi um txt que descreve algumas funcionalidades da versão beta.
Por enquanto é isso, está bom, mas acho que poderia ser melhor. Quando o Smarty 3 for lançado oficialmente e tiver uma documentação, espero ter algumas surpresas quanto as melhorias da nova versão. E você, o que achou do Smarty 3?