Cómo crear Widgets en Magento

Si bien este es un tema viejo (los widgets fueron implementados en febrero de 2010 con la versión 1.4.0.0 de Magento), todavía hay proveedores proyectos que fuerzan al cliente a manejar el contenido CMS copiando y pegando html puro y duro (si, en el año 2014).

Los casos más burdos vistos involucran:

  • slider
  • productos nuevos
  • productos destacados
  • página de promociones

¿Por qué es esto un problema?.

Si nos olvidamos del dolor de cabeza que puede implicar para un usuario no familiarizado con código html copiar y pegar el contenido de forma correcta, pensemos en el caso en donde en la página principal queremos mostrar un grupo de productos destacados.

Al haber copiado y pegado html, ese contenido es estático. Si es estático y uno de los productos se quedó sin stock, el producto seguirá mostrando la posibilidad de agregarlo al carrito (en lugar de bloquear el call to action).

A ésta altura, ya no estamos complicando el trabajo de aquellos que deben gestionar la tienda, sino que además, estamos molestando a los compradores.

En estos escenarios es donde los widgets vienen al rescate. Un widget es, por ponerlo de forma muy resumida y sencilla, un bloque de contenido que se puede agregar desde el editor CMS de Magento.

Si bien ya contamos con algunos tipos de widgets out-of-the-box, siempre podemos crear los nuestros, para tomar contenido de nuestros módulos o para ajustar, por ejemplo, contenido del catálogo.

El ejemplo más básico, que no tiene mucho sentido pero que sirve para ver cómo crear nuestro primer widget, sería el de crear uno que agrega contenido estático.

La primera parte del ejemplo contendrá los siguientes archivos:

Ejemplo módulo para con widget en Magento

Ahora bien, ¿cómo se define un widget?.

Fuera de los archivos comunes en un módulo, los tres archivos en los cuales nos vamos a concentrar son:

  • app/code/local/Dc/Test/etc/widget.xml
  • app/code/local/Dc/Test/Block/Widget.php
  • app/design/frontend/base/default/template/dc/test/widget.phtml

widget.xml es el archivo en el cual, nuestro módulo, definirá: nombre, qué bloque usará para generar el contenido y parámetros si fuera el caso.

Si volvemos al ejemplo, el código sería:

<?xml version="1.0"?>
<widgets>
    <test type="test/widget" module="test">
        <name>Widget Test</name>
        <description type="desc">This is my sample widget</description>
    </test>
</widgets>

Ahora necesitamos definir el bloque.

class Dc_Test_Block_Widget extends Mage_Core_Block_Template implements Mage_Widget_Block_Interface
{
    protected function _construct()
    {
        parent::_construct();
        $this->setTemplate('dc/test/widget.phtml');
    }
 
    protected function _toHtml()
    {
        return parent::_toHtml();
    }
}

Y para finalizar ajustamos nuestro phtml.

<div id="test-widget">
    <h1>Mi Widget</h1>
    <p>Ejemplo de widget estático</p>
</div>

A diferencia de otros bloques, aquí debemos implementar la interfase del widget. Luego, haciendo uso del __construct (para asignar el phtml que se mostrará) y del método _toHtml, tendremos nuestro ejemplo listo para probar.

Vamos a usar para el ejemplo la página principal.

Página de inicio de Magento 1.9

Lo siguiente será editar la página, como de costumbre.

Edición de página CMS

El icono que nos va a interesar es el segundo de la primera fila.

Insertar widget en Magento

Ahora tendremos la posibilidad de elegir entre los widgets disponibles, cuál queremos insertar.

Selección de Widgets en Magento
Selección de Widgets en Magento

Elegimos nuestro nuevo y flamante widget.

Selección de Widgets en Magento

Como puede verse, la descripción que habíamos asignado en el widget se hace presente al seleccionarlo.

Luego de insertarlo, así se verá (en su vista gráfica) el widget dentro del editor.

Widget insertado en nuestra página CMS

Ahora sólo queda guardar la página y ver el resultado.

Página de inicio de Magento 1.9

Hasta acá sólo vimos cómo crear y hacer uso de un widget, pero todavía no resolvimos el problema inicial que radicaba en permitir a un usuario insertar o manipular contenido dinámico, sin necesidad de tener conocimiento sobre código.

Para llegar a esa solución, vamos a darle algunas funciones más a nuestro widget.

Modificamos la definición en widget.xml.

<?xml version="1.0"?>
<widgets>
    <test type="test/widget" module="test">
        <name>Widget Test</name>
        <description type="desc">This is my sample widget with dynamic values</description>
        <parameters>
            <title>
                <label>Title</label>
                <visible>1</visible>
                <required>1</required>
                <type>text</type>
            </title>
            <message>
                <label>Message</label>
                <visible>1</visible>
                <required>1</required>
                <type>text</type>
            </message>
        </parameters>
    </test>
</widgets>

Ajustamos el bloque para que capture los valores dinámicos.

class Dc_Test_Block_Widget extends Mage_Core_Block_Template implements Mage_Widget_Block_Interface
{
    protected function _construct()
    {
        parent::_construct();
        $this->setTemplate('dc/test/widget.phtml');
    }
 
    protected function _toHtml()
    {
        $this->assign('title', $this->getData('title'));
        $this->assign('message', $this->getData('message'));
        return parent::_toHtml();
    }
}

Y editamos el phtml para que imprima esos valores.

<div id="test-widget">
    <h1><?php echo $this->getTitle(); ?></h1>
    <p><?php echo $this->getMessage(); ?></p>
</div>

Ahora si, volvemos a editar nuestra página. Borramos el viejo widget y vamos a insertar nuevamente el mismo, pero ahora, al seleccionar nuestro widget, vamos a ver algunos cambios.

Widget con valores para ingresar

Agregamos los valores que queremos mostrar.

Asignando valores dinámicos a un widget

Luego de insertar, repetimos la operación y asignamos diferentes valores. Al terminar, veríamos algo así en el editor.

Página CMS con múltiples widgets

Ahora si, al ver la página en el frontend, deberíamos obtener algo como esto.

Página con múltiples instancias de widget

De acá en más, podemos asignar variables con colecciones de productos, un único producto, listado de categorías, etc, etc, etc.