Estendendo o Smarty: TinyMCE
- PHP
- March 12, 2007
(Nota: sim estender não extender)
Uso, e recomendo, a utilização do Smarty em qualquer projeto PHP. Porque?
Bem tenho inúmeros motivos para fazer esta recomendação, mas neste post vou me limitar a apenas citar alguns, pois não é o objetivo.
- Separar PHP e HTML: código limpo, manutenção fácil
- Code e Layout em paralelo: agilidade no trabalho em equipe
- Funções de maquiagem: formatar data, wordwrap, funções que dizem respeito a visualização, ficam na visualização
- Funções customizadas: estender o Smarty é simples e útil
É neste ponto, o número 4 que vou focar este post, utilizando o tinyMCE como exemplo.
O Smarty possui inúmeros “modifiers” e “plugins” que podem facilitar muito a vida de qualquer programador. Diferenças:
- Modifier - É aplicado às variaveis, alterando seu valor ou formato de apresentação. Exemplo: date_format ({$var|date_format:’%d/%m/%Y’), upper ({$title|upper})
- Functions (Funções) - Executam funções variadas, recebendo parametros e executando operações, retornando o código após execução
A peça chave do Smarty é que ele permite que você crie suas prórias funções ou modificadores, para executar as funções que você precisa no seu dia a dia. Com isso você pode criar funções específicas ao seu sistema que facilite tarefas de “layout” repetitivas ou extensas.
Um exemplo disso é o código usado pelo OpenAds para mostrar um banner de uma zona, criando uma função de Smarty que receba o código da zona, você pode rapidamente implementar um banner em determinado local com algo semelhante a:
{ OpenAds zone=2}
Simples e direto.
Outro exemplo, que eu vou apresentar a fundo neste post, é a aplicação do TinyMCE, editor de HTML largamente utilizado por varios sistemas. Sua implementação é simples, o que indica que talvez não seja apropriado a ser objeto de uma função, mas na realidade temos alguns detalhes a serem observados na implementação.
O uso do script tem básicamente duas partes, inclusão de arquivos .js e a inicialização do editor ligado aum textarea. A complicação vem na inclusão dos arquivos, vejamos estes dois casos:
- Site sem ponto central - Cada página que irá usar um editor deve conter o código de inclusão dos arquivos, repetitivo e cansativo
- Site com ponto central - Os arquivos são incluidos no ponto central, com isso páginas que não usam o editor incluem os arquivos de qualquer forma, mais download e carga.
Levando estas situações em consideração fica claro que é necessario a utilização de algo que permita que os códigos sejam incluidos apenas quando realmente são utilizados, e que não seja preciso repetir 10-15 linhas cada vez que se deseja incluir um TinyMCE. Criando uma função do Smarty podemos utilizar algo como o código a seguir que inclua or arquivos (se necessário) e inicialize o editor:
{tinyMCE mode='exact' elements='textarea\_id'}
A função se encarrega de verificar se é necessário inserir os arquivos .js, e inserir o script de inicialização, utilizando os parametros padrões, ou os que você definir. Desta forma o uso do tinyMCE se torna pontual e otimizado, evitando os problemas citados acima.
Como implementar esta função
O primeiro passo para implementar esta função é incluir um arquivo na pasta de plugins do Smarty, com o nome da função: function.tinyMCE.php
Com este arquivo criado devemos agora seguir os padrões de desenvolvimento definidos pelo Smarty. Primeiro documente a função, como todo programador nunca faz deveria fazer, e ai seguimos para a declaração da função, que deverá receber dois parametros por padrão. O primeiro é um array com todos parametros passado na chamada e o segundo é o objeto Smarty sendo usado atualmente.É importante notar que o nome da função é padronizado em “smarty_function_name”, onde substituimos name por “tinyMCE” neste caso.
/\* \* Smarty plugin \* ------------------------------------------------------------- \* Type: function \* Name: tinyMCE \* Version: 0.8 \* Date: 07 Mar, 2007 \* Author: Rafael Dohms <rafael@rafaeldohms.com.br> \* Purpose: inserts TinyMCE Code and inicializes editor \* Input: mode = modo de seleção dos campos \* elements = textarea alvo para editor \* \* ------------------------------------------------------------- \*/ function smarty\_function\_tinyMCE($params, &$smarty) {
...
}
A seguir define-se os parametros “padrão”, que serão usados no caso de nada ser enviado que sobrescreva estes valores. Para isso criei um array chamado atribs que recebe valores e usa o nome das propriedades como chave. Logo a seguir precisamos transformar o array de parametros de entrada em atributos do tinyMCE, sobrescrevendo os valores padrão, mas ignorando parametros que se iniciam com “_”, que serão usados para configurações internas da função, e não do editor.
//Valores padrao $atribs\['mode'\] = 'specific\_textareas'; $atribs\['theme\_advanced\_toolbar\_location'\] = 'top'; $atribs\['theme\_advanced\_toolbar\_align'\] = 'left'; $atribs\['theme\_advanced\_blockformats'\] = "address,pre,h1,h2,h3,h4,h5,h6"; $atribs\['theme\_advanced\_resizing'\] = "true"; $atribs\['theme\_advanced\_buttons1'\] = "bold,italic,underline,separator,justifyleft,justifycenter,justifyright,separator,bullist,numlist,separator,outdent,indent,separator,link,unlink,image,separator,sup,sub,separator,charmap"; $atribs\['theme\_advanced\_buttons2'\] = "undo,redo,code"; $atribs\['theme\_advanced\_buttons3'\] = ""; $atribs\['force\_br\_newlines'\] = "true"; $atribs\['plugins'\] = "advimage"; $atribs\['dialog\_type'\] = "modal"; $atribs\['language'\] = "pt\_br"; $atribs\['convert\_newlines\_to\_brs'\] = "true";
//Iterar pelos atributos passados foreach($params as $\_key => $\_val) { if (substr($\_key,0,1) == '\_'){ $key = substr($\_key,1); $$key = $\_val; }else{ $atribs\[$\_key\] = $\_val; } }
Em seguida iremos iniciar a implementação dos códigos. Primeiro verificamos o parametro altsrc para ver se uma fonte alternativa da biblioteca foi fornecida, ou se devemos incluir a biblioteca do local padrão setado. Em seguida verificamos uma variável global que indica se a biblioteca já foi incluida por uma chamada anterior da função que estamos criando. Após isso teremos o código javascript de inserção pronto.
//Definir path do arquivo do tiny $src = ($altsrc != '')? $altsrc:"jsglobal/tiny\_mce/tiny\_mce.js";
//Verificar se devemos ou não inserir biblioteca if (!$GLOBALS\['smarty'\]\['tinyMCE'\]\['JS'\]){ $code = '<script language="javascript" type="text/javascript" src="'.$src.'"></script>'; }
Agora montamos o código de incialização do editor, iterando pelos atributos do array atribs e jogando eles na sintaxe utilizada pelo tinyMCE. Neste ponto foi incluida uma propriedade “blank: none” apenas para nao quebrar a sintaxe, pois o foreach deixa uma virgula solta no final das iterações, e esta solução custa menos que qualquer if que possa ser usado.
//Iniciar código de inicialização do editor $code .= '<script language="javascript" type="text/javascript">'; $code .= 'tinyMCE.init({'; //Iterar por atributos foreach($atribs as $atr=>$value){ $code .= $atr.': "'.$value.'",'; } //Finalizar $code .= 'blank: "none"'; //Evitar problem de virgula perdida $code .= '});'; $code .= '</script>';
Em seguida setamos a variável global que determina se já incluimos ou não a biblioteca (.js), esta que foi verificada acima. Depois disso precisamos apenas retornar o código usando uma chamada return e tudo será impresso no template, no local da chamada.
//Setar variavel global de biblioteca inserida $GLOBALS\['smarty'\]\['tinyMCE'\]\['JS'\] = true;
//Retornar código return $code; }
Pronto, agora a chamada indicada no início da explicação irá fazer a inserção de um editor tinyMCE customizado à nossa situação com apenas uma linha de código, e algumas simples palavras. Todo esforço de escrever as linhas normais de implementação esta nas mãos do Smarty e o processo todo se torna indolor e rápido, melhorando tempo de desenvolvimento da aplicação.
Vejam o código completo aqui
Instalando em seu servidor
A instalação deste script deve ser indolor, faça o download do tinyMCE, e salve em uma pasta de seu servidor, em uma aplicação que já utilize Smarty. Copie o arquivo da função para a pasta de plugins do Smarty e ajuste os parametros parões e o path padrão da biblioteca, insira o código abaixo no template, de acordo com o que deseja e de acordo com a sintaxe do tinyMCE.
{tinyMCE mode='exact' elements='textarea\_id' language='pt-br'}
Faça o download do arquivo da função aqui .