A Versão 2.0 introduziu a arquitetura de plugin que é usada para quase todas as funcionalidades customizáveis da Smarty. Isto inclui: * funções * modificadores * funções de bloco * funções de compilador * prefiltros * posfiltros * filtros de saída * recursos * inserir Com a exceção de recursos, a compatibilidade com a forma antiga de funções de manipulador de registro via register_* API é preservada. Se você não usou o API mas no lugar disso modificou as variáveis de classe $custom_funcs, $custom_mods, e outras diretamente, então você vai precisar ajustar seus scripts para ou usar API ou converter suas funcionalidade customizadas em plugins. = Como os Plugins Funcionam = ---- Plugins são sempre lidos quando requisitados. Apenas os modificadores específicos, funções, recursos, etc convocados em scripts de template serão lidos. Além disso, cada plugin é lido apenas uma vez, mesmo se você tem várias instâncias diferentes da Smarty rodando na mesma requisição. Pre/posfiltros e filtros de saída são uma parte de um caso especial. Visto que eles não são mencionados nos templates, eles devem ser registrados ou lidos explicitamente via funções de API antes do template ser processado. A ordem em que multiplos filtros do mesmo tipo são executados dependem da ordem em que eles são registrados ou lidos. O diretório de plugins pode ser uma string contendo um caminho ou um array contendo multiplos caminhos. Para instalar um plugin, simplesmente coloque-o em um dos diretórios e a Smarty irá usá-lo automaticamente. = Convenções de Aparência = ---- Arquivos e funções de Plugin devem seguir uma convenção de aparência muito específica a fim de ser localizada pela Smarty. Os arquivos de plugin devem ser nomeados da sequinte forma: tipo.nome.php Onde tipo é um dos seguintes tipos de plugin: * function * modifier * block * compiler * prefilter * postfilter * outputfilter * resource * insert E nome seria um identificador válido (letras, números, e underscores apenas). Alguns exemplos: function.html_select_date.php, resource.db.php, modifier.spacify.php. As funções de plugin dentro dos arquivos do plugin devem ser nomeadas da seguinte forma: smarty_tipo_nome() O significado de tipo e nome são os mesmos de antes. A Smarty mostrará mensagens de erro apropriadas se o arquivo de plugins que é necessário não é encontrado, ou se o arquivo ou a função de plugin estão nomeadas inadequadamente. = Escrevendo Plugins = ---- Os Plugins podem ser ou lidos pela Smarty automaticamente do sistema de arquivos ou eles podem ser registrados no tempo de execução via uma das funções de API register_* . Eles podem também ser com o uso da função API unregister_* . Para os plugins que são registrados no tempo de execução, o nome da(s) função(ões) de plugin não têm que seguir a convenção de aparência. Se um plugin depende de alguma funcionalidade fornecida por um outro plugin (como é o caso com alguns plugins embutidos com a Smarty), então a forma apropriada para ler o plugin necessário é esta: {{{ require_once $smarty->_get_plugin_filepath('function', 'html_options'); }}} Como uma regra geral, o objeto da Smarty é sempre passado para os plugins como o último parâmetro (com duas exceções: modificadores não passam o objeto da Smarty em tudo e blocks passam &$repeat depois do objeto da Smarty para manter compatibilidade a antigas versões da Smarty). = Funções de Template = ---- void smarty_function_name (array $params, object &$smarty) Todos os atributos passados para as funções de template a partir do template estão contidas em $params como um array associativo. Ou acessa esses valores diretamente i.e $params['start'] ou usa extract($params) para importá-los para dentro da tabela símbolo. A saída (valor de retorno) da função será substituída no lugar da tag da função no template (a função fetch(), por exemplo). Alternativamente, a função pode simplesmente executar alguma outra tarefa sem ter alguma saída (a função assign()). Se a função precisa passar valores a algumas variáveis para o template ou utilizar alguma outra funcionalidade fornecida com a Smarty, ela pode usar o objeto $smarty fornecido para fazer isso. Veja também: register_function(), unregister_function(). Exemplo 16-1. função de plugin com saída {{{ que pode ser usada no template da seguinte forma: Pergunta: Nós sempre teremos tempo para viajar? Resposta: {eightball}. Exemplo 16-2. função de plugin sem saída trigger_error("assign: missing 'var' parameter"); return; } if (!in_array('value', array_keys($params))) { $smarty->trigger_error("assign: missing 'value' parameter"); return; } $smarty->assign($var, $value); } ?> }}} = Modificadores = ---- Modificadores são funções que são aplicadas a uma variável no template antes dela ser mostrada ou usada em algum outro contexto. Modificadores podem ser encadeados juntos. {{{ mixed smarty_modifier_name (mixed $value, [mixed $param1, ...]) }}} O primeiro parâmetro para o plugin midificador é o valor em que o modificador é suposto operar. O resto dos parâmetros podem ser opcionais, dependendo de qual tipo de operação é para ser executada. O modificador deve retornar o resultado de seu processamento. Veja também: register_modifier(), unregister_modifier(). Exemplo 16-3. Plugin modificador simples Este plugin basiamente é um alias de uma função do PHP. Ele não tem nenhum parâmetro adicional. {{{ }}} Exemplo 16-4. Plugin modificador mais complexo {{{ $length) { $length -= strlen($etc); $fragment = substr($string, 0, $length+1); if ($break_words) $fragment = substr($fragment, 0, -1); else $fragment = preg_replace('/\s+(\S+)?$/', '', $fragment); return $fragment.$etc; } else return $string; } ?> }}} = Block Functions = ---- void smarty_block_name (array $params, mixed $content, object &$smarty) Funções de Block são funções da forma: {func} .. {/func}. Em outras palavras, ele enclausura um bloco de template e opera no conteúdo deste bloco. Funções de Block tem precedência sobre funções customizadas com mesmo nome, assim, você não pode ter ambas, função customizável {func} e função de Bloco {func} .. {/func}. Por definição a implementação de sua função é chamada duas vezes pela Smarty: uma vez pela tag de abertura, e outra pela tag de fechamento (veja &$repeat abaixo para como mudar isto). Apenas a tag de abertura da função de bloco pode ter atributos. Todos os atributos passados para as funções de template estão contidos em $params como um array associativo. Você pode ou acessar esses valores diretamente, i.e. $params['start'] ou usar extract($params) para importá-los para dentro da tabela símbolo. Os atributos da tag de abertura são também acessíveis a sua função quando processando a tag de fechamento. O valor da variável $content depende de que se sua função é chamada pela tag de fechamento ou de abertura. Caso seja a de abertura, ele será null, se for a de fechamento o valor será do conteúdo do bloco de template. Note que o bloco de template já terá sido processado pela Smarty, então tudo que você receberá é saída do template, não o template original. O parâmetro &$repeat é passado por referência para a função de implementação e fornece uma possibilidade para ele controlar quantas vezes o bloco é mostrado. Por definição $repeat é true na primeira chamada da block-function (a tag de abertura do bloco) e false em todas as chamadas subsequentes à função de bloco (a tag de fechamento do bloco). Cada vez que a implementação da função retorna com o &$repeat sendo true, o conteúdo entre {func} .. {/func} é avaliado e a implementação da função é chamada novamente com o novo conteúdo do bloco no parâmetro $content. Se você tem funções de bloco aninhadas, é possível descobrir qual é a função de bloco pai acessando a variável $smarty->_tag_stack. Apenas faça um var_dump() nela e a estrutura estaria visível. See also: register_block(), unregister_block(). Exemplo 16-5. função de bloco {{{ _current_file . " compiled at " . date('Y-m-d H:M'). "';"; } ?> }}} Esta função pode ser chamada em um template da seguinte forma: {{{ {* esta função é executada somente no tempo de compilação *} {tplheader} }}} O código PHP resultante no template compilado seria algo assim: {{{ }}} = Prefiltros/Posfiltros = ---- Plugins Prefilter e postfilter são muito similares em conceito; onde eles diferem é na execução -- mais precisamente no tempo de suas execuções. string smarty_prefilter_name (string $source, object &$smarty) Prefilters são usados para processar o fonte do template imediatamente antes da compilação. O primeiro parâmetro da função de prefilter é o fonte do template, possivelmente modificado por alguns outros prefilters. O Plugin é suposto retornar o fonte modificado. Note que este fonte não é salvo em lugar nenhum, ele só é usado para a compilação. string smarty_postfilter_name (string $compiled, object &$smarty) Postfilters são usados para processar a saída compilada do template (o código PHP) imediatamente após a compilação ser feita e antes do template compilado ser salvo no sistema de arquivo. O primeiro parâmetro para a função postfilter é o código do template compilado, possivelmente modificado por outros postfilters. O plugin é suposto retornar a versão modificada deste código. Exemplo 16-7. Plugin prefilter {{{ ]+>!e', 'strtolower("$1")', $source); } ?> }}} Exemplo 16-8. Plugin postfilter {{{ \nget_template_vars()); ?>\n" . $compiled; return $compiled; } ?> }}} = Filtros de saída = ---- Filtros de saída operam na saída do template, depois que o template é lido e executado, mas antes a saída é mostrada. string smarty_outputfilter_name (string $template_output, object &$smarty) O primeiro parâmetro para a função do filtro de saída é a saída do template que precisa ser processada, e o segundo parâmetro é a instância da Smarty invocando o plugin. O plugin deve fazer o precessamento e retornar os resultados. Exemplo 16-9. output filter plugin {{{ /* * Smarty plugin * ------------------------------------------------------------- * File: outputfilter.protect_email.php * Type: outputfilter * Name: protect_email * Purpose: Converts @ sign in email addresses to %40 as * a simple protection against spambots * ------------------------------------------------------------- */ function smarty_outputfilter_protect_email($output, &$smarty) { return preg_replace('!(\S+)@([a-zA-Z0-9\.\-]+\.([a-zA-Z]{2,3}|[0-9]{1,3}))!', '$1%40$2', $output); } }}} = Recursos (Resources) = ---- Os plugins de Recursos são como uma forma genérica de fornecer códigos fontes de template ou componentes de script PHP para a Smarty. Alguns exemplos de recursos: banco de dados, LDAP, memória compartilhada, sockets, e assim por diante. Há um total de 4 funções que precisam estar registradas para cada tipo de recurso. Cada função receberá o recurso requisitado como o primeiro parâmetro e o objeto da Smarty como o último parâmetro. O resto dos parâmetros dependem da função. {{{ bool smarty_resource_name_source (string $rsrc_name, string &$source, object &$smarty) bool smarty_resource_name_timestamp (string $rsrc_name, int &$timestamp, object &$smarty) bool smarty_resource_name_secure (string $rsrc_name, object &$smarty) bool smarty_resource_name_trusted (string $rsrc_name, object &$smarty) }}} A primeira função deve devolver o recurso. Seu segundo parâmetro é uma variável passada por referência onde o resultado seria armazenado. A função deve retornar true se ela está apta a devolver com sucesso o recurso e caso contrário retorna false. A segunda função deve devolver a última modificação do recurso requisitado (como um timestamp Unix). O segundo parâmetro é uma variável passada por referência onde o timestamp seria armazenado. A função deve retornar true se o timestamp poderia ser determinado com sucesso, e caso contrário retornaria false. A terceira função deve retornar true ou false, dependendo do recurso requisitado está seguro ou não. Esta função é usada apenas para recursos de template mas ainda assim seria definida. A quarta função deve retornar true ou false, dependendo do recurso requisitado ser confiável ou não. Esta função é usada apenas para componentes de script PHP requisitados pelas tags include_php ou insert com o atributo src. Entretanto, ela ainda assim mesmo seria definida para os recursos de template. Veja também: register_resource(), unregister_resource(). Exemplo 16-10. Plugin resource (recurso) {{{ query("select tpl_source from my_table where tpl_name='$tpl_name'"); if ($sql->num_rows) { $tpl_source = $sql->record['tpl_source']; return true; } else { return false; } } function smarty_resource_db_timestamp($tpl_name, &$tpl_timestamp, &$smarty) { // faz o banco de dados chamar aqui para preencher $tpl_timestamp. $sql = new SQL; $sql->query("select tpl_timestamp from my_table where tpl_name='$tpl_name'"); if ($sql->num_rows) { $tpl_timestamp = $sql->record['tpl_timestamp']; return true; } else { return false; } } function smarty_resource_db_secure($tpl_name, &$smarty) { // assume que todos os templates são seguros return true; } function smarty_resource_db_trusted($tpl_name, &$smarty) { // não usado para templates } ?> }}} = Inserts = ---- Plugins Insert são usados para implementar funções que são invocadas por tags insert no template. string smarty_insert_name (array $params, object &$smarty) O primeiro parâmetro para a função é um array associativo de atributos passados para o insert. Ou acessa esses valores diretamente, i.e. $params['start'] ou usa extract($params) para importá-los para dentro da tabela símbolo. A função insert deve retornar o resultado que será substituído no lugar da tag insert no template. Exemplo 16-11. Plugin insert {{{ trigger_error("insert time: missing 'format' parameter"); return; } $datetime = strftime($params['format']); return $datetime; } ?> }}}