Pular para o conteúdo

Migração Smarty 4

Este guia cobre as mudanças e etapas de migração necessárias ao atualizar de Smarty 3 para Smarty 4 no XOOPS. Entender essas diferenças é essencial para manter compatibilidade com instalações XOOPS modernas.

  • Smarty-Basics - Fundamentos do Smarty no XOOPS
  • Theme-Development - Criando temas XOOPS
  • Template-Variables - Variáveis disponíveis em templates

Smarty 4 introduziu várias mudanças de ruptura do Smarty 3:

  1. Comportamento de atribuição de variável mudou
  2. Tags {php} completamente removidas
  3. Mudanças na API de cache
  4. Atualizações no tratamento de modificadores
  5. Mudanças na política de segurança
  6. Recursos deprecados removidos

Em Smarty 2/3, valores atribuídos eram diretamente acessíveis:

// PHP
$GLOBALS['xoopsTpl']->assign('mod_url', $helper->url());
{* Smarty 2/3 - funcionava bem *}
<img src="<{$mod_url}>/assets/images/icon.png">

Em Smarty 4, variáveis são envoltas em objetos Smarty_Variable:

Smarty_Variable Object
(
[value] => http://example.com/modules/mymodule/
[nocache] =>
)
{* Smarty 4 - acessar propriedade de valor *}
<img src="<{$mod_url->value}>/assets/images/icon.png">

Ativar modo de compatibilidade em PHP:

$smarty = new Smarty();
$smarty->setCompatibilityMode(true);

Isto permite acesso direto à variável como Smarty 3.

Escrever templates que funcionem em ambas as versões:

<{if $smarty.version|regex_replace:'[^0-9]':'' >= 4}>
<{$mod_url->value}>
<{else}>
<{$mod_url}>
<{/if}>

Criar uma função auxiliar para atribuições:

function smartyAssign($smarty, $name, $value)
{
if (version_compare($smarty->version, '4.0.0', '>=')) {
// Smarty 4+ - atribuir normalmente, acessar via ->value em templates
$smarty->assign($name, $value);
} else {
// Smarty 3 - atribuição padrão
$smarty->assign($name, $value);
}
}

Smarty 3+ não suporta tags {php} por razões de segurança:

{* Isto NÃO FUNCIONA MAIS em Smarty 3+ *}
<{assign var="cid" value=$downloads.cid}>
<{php}>
$catid = $this->get_template_vars('cid');
<{/php}>
{* Usar acesso à variável integrado do Smarty *}
<{assign var="cid" value=$downloads.cid}>
<{assign var="catid" value=$smarty.template_vars.cid}>

Lógica complexa deve estar em PHP, não em templates:

// Em PHP - fazer o processamento
$catid = $downloads['cid'];
$categoryInfo = getCategoryInfo($catid);
// Atribuir dados processados ao template
$GLOBALS['xoopsTpl']->assign('category', $categoryInfo);
{* Em template - apenas exibir *}
<h2><{$category.name}></h2>

Para funcionalidade reutilizável, criar plugins Smarty:

/class/smarty/plugins/function.getcategory.php
function smarty_function_getcategory($params, $smarty)
{
$catId = $params['id'] ?? 0;
$categoryHandler = xoops_getModuleHandler('category', 'mymodule');
$category = $categoryHandler->get($catId);
if ($category) {
$smarty->assign($params['assign'], $category->toArray());
}
}
{* Em template *}
<{getcategory id=$cid assign="category"}>
<h2><{$category.name}></h2>
// Estilo Smarty 3
$smarty->caching = true;
$smarty->cache_lifetime = 3600;
$smarty->cache_dir = '/path/to/cache';
// Nocache por variável
$xoopsTpl->tpl_vars["mod_url"]->nocache = false;
// Estilo Smarty 4
$smarty->setCaching(Smarty::CACHING_LIFETIME_CURRENT);
$smarty->setCacheLifetime(3600);
$smarty->setCacheDir('/path/to/cache');
// Ou usando propriedades (ainda funciona)
$smarty->caching = Smarty::CACHING_LIFETIME_CURRENT;
$smarty->cache_lifetime = 3600;
// Modos de cache
Smarty::CACHING_OFF // Sem cache
Smarty::CACHING_LIFETIME_CURRENT // Usar cache_lifetime
Smarty::CACHING_LIFETIME_SAVED // Usar lifetime em cache
{* Marcar conteúdo como nunca cacheado *}
<{nocache}>
<p>Current time: <{$smarty.now|date_format:"%H:%M:%S"}></p>
<{/nocache}>

Alguns modificadores foram renomeados ou descontinuados:

{* Smarty 3 *}
<{$text|escape:'htmlall'}>
{* Smarty 4 - usar 'html' em vez disso *}
<{$text|escape:'html'}>

Modificadores de array requerem prefixo @:

{* Contar elementos de array *}
<{$items|@count}> items
{* Unir array *}
<{$tags|@implode:', '}>
{* JSON encode *}
<{$data|@json_encode}>

Modificadores personalizados devem ser registrados:

// Registrar um modificador personalizado
$smarty->registerPlugin('modifier', 'my_modifier', 'my_modifier_function');
function my_modifier_function($string, $param1 = 'default')
{
// Processar e retornar
return processed_string($string, $param1);
}

Smarty 4 tem segurança padrão mais rigorosa:

// Configurar política de segurança
$smarty->enableSecurity('Smarty_Security');
// Ou criar política personalizada
class MySecurityPolicy extends Smarty_Security
{
public $php_functions = ['isset', 'empty', 'count'];
public $php_modifiers = ['escape', 'count'];
public $allow_super_globals = false;
}
$smarty->enableSecurity(new MySecurityPolicy($smarty));

Por padrão, Smarty 4 restringe quais funções PHP podem ser usadas:

{* Estas podem ser restritas *}
<{if isset($variable)}>
<{if empty($array)}>
<{$array|@count}>

Configurar funções permitidas se necessário:

$smarty->security_policy->php_functions = [
'isset', 'empty', 'count', 'sizeof',
'in_array', 'is_array', 'date', 'time'
];

A sintaxe de bloco permanece similar mas com algumas mudanças:

{* Template pai *}
<html>
<head>
{block name=head}
<title>Default Title</title>
{/block}
</head>
<body>
{block name=content}{/block}
</body>
</html>
{* Template filho *}
{extends file="parent.tpl"}
{block name=head}
{$smarty.block.parent} {* Incluir conteúdo do bloco pai *}
<meta name="custom" content="value">
{/block}
{block name=content}
<h1>My Content</h1>
{/block}
{block name=head append}
{* Isto é adicionado após conteúdo pai *}
<link rel="stylesheet" href="extra.css">
{/block}
{block name=scripts prepend}
{* Isto é adicionado antes do conteúdo pai *}
<script src="early.js"></script>
{/block}
RecursoAlternativa
Tags {php}Mover lógica para PHP ou usar plugins
{include_php}Usar plugins registrados
$smarty.captureAinda funciona mas deprecado
{strip} com espaçosUsar ferramentas de minificação
{* Em vez de {php} *}
{* Mover para PHP e atribuir resultado *}
{* Em vez de include_php *}
<{include file="db:mytemplate.tpl"}>
{* Em vez de capture (ainda funciona mas considere) *}
<{capture name="sidebar"}>
<h3>Sidebar</h3>
<{/capture}>
<div><{$smarty.capture.sidebar}></div>
  1. Fazer backup de todos os templates
  2. Listar todo uso de tag {php}
  3. Documentar plugins personalizados
  4. Testar funcionalidade atual
  1. Remover todas as tags {php}
  2. Atualizar sintaxe de acesso a variáveis
  3. Verificar uso de modificadores
  4. Atualizar configuração de cache
  5. Revisar configurações de segurança
  1. Testar todos os templates
  2. Verificar se todos os formulários funcionam
  3. Verificar se cache funciona
  4. Testar com diferentes funções de usuário
// Verificar versão Smarty em PHP
$version = Smarty::SMARTY_VERSION;
if (version_compare($version, '4.0.0', '>=')) {
// Código específico Smarty 4+
} else {
// Código Smarty 3
}
{* Verificar versão em template *}
<{assign var="smarty_major" value=$smarty.version|regex_replace:'/\\..*$/':''}>
<{if $smarty_major >= 4}>
{* Código de template Smarty 4+ *}
<{else}>
{* Código de template Smarty 3 *}
<{/if}>
  1. Evitar tags {php} inteiramente - Elas não funcionam em Smarty 3+

  2. Manter templates simples - Lógica complexa pertence a PHP

  3. Usar modificadores padrão - Evitar os descontinuados

  4. Testar em ambas as versões - Se você precisa suportar ambas

  5. Usar plugins para operações complexas - Mais manutenível

{* Funciona em Smarty 3 e 4 *}
<!DOCTYPE html>
<html>
<head>
<title><{$page_title|default:'Default Title'|escape}></title>
</head>
<body>
<{if isset($items) && $items|@count > 0}>
<ul>
<{foreach $items as $item}>
<li><{$item.name|escape}></li>
<{/foreach}>
</ul>
<{else}>
<p>No items found.</p>
<{/if}>
</body>
</html>

Problema: <{$mod_url}> retorna nada em Smarty 4

Solução: Usar <{$mod_url->value}> ou ativar modo de compatibilidade

Problema: Template lança erro em tags {php}

Solução: Remover todas as tags PHP e mover lógica para arquivos PHP

Problema: Modificador personalizado lança erro “unknown modifier”

Solução: Registrar o modificador com registerPlugin()

Problema: Função não permitida em template

Solução: Adicionar função à lista de permissões da política de segurança


#smarty #migration #upgrade #xoops #smarty4 #compatibility