Desarrollando Plugins en Joomla 3.0, parte I

Esto es una serie de artículos donde tratare de explicar como desarrollar un plugin en Joomla 3, explicando como hacer un plugin que nos permita agregar información antes y después del contenido, así como modificarlo, el resultado de un articulo con dicho plugin activado es el siguiente:

Plugin Test Eventos

Resultado tras crear el plugin

Plugins en Joomla ¿Que diablos es un plugin?

Cabe mencionar que un plugin en Joomla es lo que antes eran conocidos como mambots en las primeras versiones de Joomla(cuando heredo de Mambo), menciono esto no por que sea un romántico de lo antaño, si no por que me parece mas fácil entender un plugin desde el concepto de un bot(robot o automata).

Dicho esto un Plugin en Joomla es una extensión que una vez activada dispara funcionalidades en determinados eventos.

Funcionamiento de un Plugin ¿como carajo me pueden servir?

Nos sirve para agregarle funcionalidad y personalizar el comportamiento de nuestro portal Joomla, usando plugins por ejemplo podemos:

  • Detectar y hacer algo en las autenticaciones fallidas.
  • Modificar los contenidos p.e. agregar botones de redes sociales, formularios, etc…
  • Realizar cierta acción cuando el usuario busque determinada información.
  • Enviar un correo electrónico de felicitación al usuario registrado núm 1000.
  • Realizar acciones del sistema como re-direccionamientos o manejo de errores.

Y muchas otras acciones más que pueden llegar a realizar nuestros sitios, solo es cuestión de enganchar el evento adecuado y un poco de imaginación.

Grupos de plugin ¿Como están divididos los plugins?

Cabe mencionar que los Plugins a su vez están divididos en grupos según su funcionalidad:

  • authentication
  • captcha
  • content
  • editors
  • extension
  • finder
  • search
  • system
  • user

Si observas la carpeta /plugins/ encontraras una subcarpeta para cada grupo ahí también encontraras una serie de plugins para cada grupo que te puede servir de ejemplo. Por cada grupo se definen una serie de eventos(disparados en funciones), en este manual voy a explicar el funcionamiento del grupo que corresponde a los contenidos (content).

Los eventos definidos en Content mas comunes son los siguientes:

onContentPrepare Modificando el contenido

Esta función es ejecutada antes de que el artículo se imprima en la pantalla. Si quiere modificar el contenido(ó el titulo) de alguna manera, este sería el mejor lugar para realizar estas modificaciones.

onContentBeforeDisplay Agregando texto previo al contenido

Esta función es disparada antes de que Joomla mande a imprimir el cuerpo de un contenido, aquí podemos devolver algun texto que queramos que se muestre en dicho espacio.

onContentAfterDisplay Agregando texto posterior al contenido

Esta función es disparada depues de que Joomla mande a imprimir el cuerpo de un contenido, aquí podemos devolver algún texto que queramos que se muestre en dicho espacio.

Haciendo nuestro primer plugin de Contenido Ejemplo con los eventos mas comunes

Vamos a desarollar un plugin del tipo contenido que nos sirva para probar los eventos que podemos usar(en realidad los mas comunes).

Definición del archivo instalador

<?xml version="1.0" encoding="utf-8"?>
<extension version="3.0" type="plugin" group="content" method="upgrade">
    <name>Test Eventos de Plugins</name>
    <author>Fitorec</author>
    <creationDate>02-04-2013</creationDate>
    <authorEmail>programacion@mundosica.com</authorEmail>
    <license>GNU/GPL version 2 or later</license>
    <authorUrl>https://mundosica.com</authorUrl>
    <version>1.0</version>
    <description>
        Plugin de prueba que nos muestra un el funcionamiento de los eventos en un Plugin de Joomla!
    </description>
    <files>
        <filename plugin="TestPluginEventos">TestPluginEventos.php</filename>
        <filename>TestPluginEventos.xml</filename>
    </files>
</extension>

El archivo anterior define una extensión para la versión 3.0, del tipo Plugin, que pertenece al grupo Content.

También definimos el nombre que tendrá el plugin y mas datos como autor, descripción, etc..

Algo muy importante es que definimos que el plugin TestPluginEventos esta ubidado en el archivo TestPluginEventos.php.

Faltaría definir el archivo TestPluginEventos.php donde pondremos el Plugin en cuestión.

<?php
// Restringe el Acceso al archivo si no es desde el Entorno Joomla.
defined('_JEXEC') or die;

/**
 * Plugin test de Eventos.
 */

class plgContentTestPluginEventos extends JPlugin
{
    private $_titulo = '<h3 style="color: %s">%s</h3>';

/**
 * Constructor del objeto
 * 
 * @param object &$subject es una instancia del objeto a construir
 * @param array $config parámetro opcional arreglo asociativo: puede contener las claves
 *                      'name', 'group', 'params', 'language'
 */
    public function __construct(&$subject, $config)
    {
        parent::__construct($subject, $config);
    }//fin constructor

/**
 * Esta función es ejecutada antes de renderizar el articulo
 *
 * @param String $context es el contexto en el cual es ejecutada
 * @param Object $row es un objeto que contiene la información del articulo(como titulo, contenido, url, autor, etc)
 * @param Object $params es un objeto que contiene la información del portal y parametros del plugin
 * @param Integer $limitstart desplazamiento del elemento
 */
    public function onContentPrepare($context, &$row, &$params, $limitstart)
    {
        if($context == 'com_content.article')
            $row->text = '<p>Contenido modificado en el evento <b>onContentPrepare</b></p>' . $row->text;
    }//fin onContentPrepare

/**
 * Esta función es ejecutada antes de mostrar renderizar el cuerpo del articulo
 *
 * @param String $context es el contexto en el cual es ejecutada
 * @param Object $row es un objeto que contiene la información del articulo(como contenido, url, autor, etc)
 * @param Object $params es un objeto que contiene la información del portal y parametros del plugin
 * @param Integer $limitstart desplazamiento del elemento
 */
    public function onContentBeforeDisplay($context, &$row, &$params, $limitstart)
    {
        return sprintf($this->_titulo, '#FF4A00', 'Evento onContentBeforeDisplay');
    }//fin onContentBeforeDisplay

/**
 * Esta función es ejecutada después de mostrar renderizar el cuerpo del articulo
 *
 * @param String $context es el contexto en el cual es ejecutada
 * @param Object $row es un objeto que contiene la información del articulo(como contenido, url, autor, etc)
 * @param Object $params es un objeto que contiene la información del portal y parametros del plugin
 * @param Integer $limitstart desplazamiento del elemento
 */
    public function onContentAfterDisplay($context, &$row, &$params, $limitstart)
    {
            return sprintf($this->_titulo, '#1C9202', 'Evento onContentAfterDisplay');
    }//fin onContentAfterDisplay

}

Como podemos ver un Plugin de Joomla es un Objeto que hereda de JPlugin esta clase esta definida en /libraries/joomla/plugin/plugin.php.

Es importante mencionar que al nombre de la clase se le agrega el prefijo plgContent, ya que es un plugin (plg) del tipo Contenido(Content) quedando finalmente como plgContentTestPluginEventos, si no nombramos correctamente la clase, Joomla no podrá ejecutar el plugin.

Enlaces recomendados y conclusiones

Quizas te preguntes que pasaría si ¿2 plugins(ó extensiones) activados ocuparan el mismo evento?, pues lo que sucede es que Joomla detecta las funciones definidas para determinado evento y va generando una lista de ellas para que una vez que ocurra el evento las ejecute todas, esto lo hace basado en el un patrón conodicido como Observer a continuación presento el diagrama UML del comportamiento de este patrón.

patrón Osbrver

Comportamiento patrón Observer

Si gusta abundar por en el tema le sugiero seguir las siguientes ligas:

Descarga este Plugin y proximos posts

Descargar este plugin | Visualizar el código fuente en Linea

En el siguiente articulo me gustaría hacer un plugin de contenido, ya con alguna funcionalidad mas especifica se me ocurre agregar botones de redes sociales, ocupando parámetros en el plugin.