Informática Numaboa - Tutoriais e Programação
Joomla e Smilies
Qua 3 Fev 2010 22:20 |
- Detalhes
- Categoria: Joomla
- Atualização: Segunda, 22 Abril 2013 20:20
- Autor: vovó Vicki
- Acessos: 4002
Adoro os smilies, não tenho como negar. Estes emoticons permeiam meus textos desde que comecei a publicá-los na web. Minha coleção foi aumentando com o tempo, mesmo porque sempre tem um pessoal muito criativo lançando novas "carinhas" que realmente fazem jeito.
Tudo bem, tudo bom, mas o que é que isto tem a ver com o Joomla?
Explico. Há muitos anos criei um plugin para substituir trechos de textos com as imagens dos emoticons. Uma coisinha à toa como trocar :carinha: por ou, um dos meus preferidos, trocar :comemora: por
Acontece que, devido à minha limitação de conhecimento na época, os smilies só podiam ser chamados nos artigos que publicava, porque meu plugin foi criado para ser um plugin de conteúdo (era adicionado em /plugins/content). Quando eu inseria um emoticon numa descrição de seção ou categoria, as chamadas eram simplesmente ignoradas - uma verdadeira frustração. Ainda tem mais: usando um editor de textos para criar artigos (como o tinymce ou o jce) , as carinhas não eram mostradas na área de edição. Até que, um dia, caiu a ficha quando estava lendo um artigo sobre os eventos que podem ser interceptados quando escrevemos um plugin - mais especificamente, um plugin de sistema.
Plugins de sistema podem "caçar" qualquer evento previsto no Joomla além de mais alguns eventos que são exclusividade do sistema. São eles: onAfterInitialise, onAfterRoute, onAfterDispatch, onAfterRender, onSearch, onSearchAreas e onGetWebServices. Não vou explicar cada um deles neste tutorial porque este não é o foco deste artigo. Os que nos interessam no momento são apenas o onAfterRoute e o onAfterRender.
O evento onAfterRoute pode ser tratado no código do plugin criando uma função que recebe o mesmo nome. Este evento é disparado depois que o framework do Joomla foi carregado, inicializado e depois que o roteador tenha uma rota para a solicitação do cliente. Rotear é o processo de examinar o ambiente da solicitação para determinar qual componente deve receber a dita solicitação. Os parâmetros opcionais do componente são estabelecidos no objeto de requisição para que possam ser processados quando a aplicação for despachada. Quando este evento é interceptado, o roteador já estabeleceu a rota e colocou os parâmetros da requisição em JRequest para que possam ser utilizados pela aplicação.
O evento onAfterRender também pode ser tratado no código do plugin criando uma função com o mesmo nome. Este evento é disparado depois que o framework "renderizou" a aplicação. "Renderizar" é o mesmo que enxertar - colocar cada coisa no seu lugar. É alguma coisa como enxerto ósseo, ou seja, é o processo que coloca o conteúdo do buffer do documento nos devidos lugares indicados pelo template. Quando este evento é interceptado, a saída para a aplicação está disponível no buffer de resposta JResponse.
Usando estes conhecimentos para criar o plugin
Aqui está o código principal do plugin, o arquivo vickismilies.php que vai ser colocado no diretório /plugins/system/.
<?php
/**
* vickismilies - Smiley Plugin, developed for Joomla! 1.5
* @version $Id: vickismilies.php 0001 2010-02-04 00:00:00Z vovó Vicki $
* @package vickiSmiliesPlugin
* @copyright 2010 vovó Vicki, http://www.numaboa.com. All rights reserved.
* @license Creative Commons 3.0 http://creativecommons.org/licenses/by-nc-sa/3.0/
*/
// evitar acesso direto
defined('_JEXEC') or die('Acesso restrito');
class plgSystemVickiSmilies extends JPlugin {
/**
* Constructor
*/
function plgSystemVickiSmilies(& $subject, $config) {
parent::__construct($subject, $config);
$_smiley = array();
}
function onAfterRoute() {
$document = &JFactory::getDocument();
$doctype = $document->getType();
// Só substitui em documentos HTML
if( $doctype !== 'html' ) {
return false;
}
}
// Faz as trocas na página inteira (inclusive na área administrativa!)
function onAfterRender() {
$this->_readSmileySet();
$body = JResponse::getBody();
for( $i = 0; $i < count( $this->_smiley ); $i++ ) {
$row = $this->_smiley[$i];
if( JString::strpos( $body, $row[0] ) ) {
$body = str_replace( $row[0], '<img src="' . $row[2] . '" alt="' . $row[1] . '" border="0" align="absmiddle">', $body );
}
}
JResponse::setBody($body);
}
function _readSmileySet() {
global $mainframe;
$urlBase = $mainframe->isAdmin() ? $mainframe->getSiteURL() : JURI :: base();
$linha = 0;
$handle = fopen( $urlBase . 'plugins/system/vickismilies/vickismilies.csv', 'r' );
// ler arquivo linha por linha
while( ( $data = fgetcsv( $handle, 1000, ';' ) ) !== false ) {
$skip = false;
$code = trim( $data[0] );
if( strlen( $code ) > 0 ) {
$alt = JText :: _( $data[1] );
$src = trim( $data[2] );
if( strlen( $src ) == 0 ) {
$skip = true;
} else {
$src = $urlBase . 'plugins/system/vickismilies/' . $src;
$this->_smiley[$linha][0] = $code;
$this->_smiley[$linha][1] = $alt;
$this->_smiley[$linha][2] = $src;
}
}
if( !$skip ) $linha++;
}
fclose($handle);
}
}
?>
Acompanhando este arquivo, também é criado um sub-diretório em /plugins/system chamado vickismilies onde todos os arquivos dos smilies e o arquivo vickismilies.cvs, que dá todas as referências a estes arquivos para que possam ser utilizadas pelo script, serão colocados.
A função onAfterRoute checa apenas se a página está apresentando um arquivo HTML. Se não, o código do plugin é interrompido e a execução volta para o ponto de chamada para que não se perca tempo; se sim, continuamos na área de atuação do plugin esperando pelo evento onAfterRender.
A função onAfterRender permite "caçar" tudo o que existe numa página que está prestes a ser apresentada. É nesse momento que podemos trocar alguns marcadores pelo código HTML que desejamos. Nossa primeira providência é criar um array que armazena marcadores e o endereço das imagens e seus textos alternativos que devem substituir os marcadores. Por este motivo a função _readSmileySet() é chamada logo no início. Logo a seguir capturamos o que está armazenado no buffer com JResponse::getBody() e começamos a fazer as substituições comparando cada uma das informações do array com o conteúdo do corpo da página. Terminada esta tarefa, basta devolver ao buffer o conteúdo alterado com JResponse::setBody($body);
Resolvendo conflitos
Estava feliz da vida com meu plugin instalado e funcionando quando entrei na área administrativa para atualizar a seção de downloads. Deu uma caca total. Por mais que eu procurasse, não consegui encontrar a incompatibilidade entre o script MooTree, usado pelo componente de downloads, e o plugin que tinha acabado de instalar. Antes de fundir a cuca procurando agulha em palheiro, resolvi desativar a atuação do plugin na área administrativa colocando uma trava na função onAfterRender. Veja como ficou:
function onAfterRender() {
global $mainframe;
if( $mainframe->isAdmin() ) return false;
$this->_readSmileySet();
$body = JResponse::getBody();
for( $i = 0; $i < count( $this->_smiley ); $i++ ) {
$row = $this->_smiley[$i];
if( JString::strpos( $body, $row[0] ) ) {
$body = str_replace( $row[0], '<img src="' . $row[2] . '" alt="' . $row[1] . '" border="0" align="absmiddle">', $body );
}
}
JResponse::setBody($body);
}
Depois desta alteração ficou tudo bem novamente na área administrativa. No frontend, até agora, não tive problemas. Se você quiser fazer uso deste plugin, assumindo os mesmos riscos que assumi, ele está à sua disposição na seção de downloads da Aldeia nas duas versões: vickiSmilies frontend e vickiSmilies front e backend.
Veja o plugin funcionando
Aqui alguns exemplos: