jueves, 29 de septiembre de 2011

Creación de un widget basado en CPortlet con Yii Framework.

En un post anterior, estabamos comentando como Yii Framework puede ser extendido mediante componentes. Veiamos como los componentes extienden de uan clase base llamada CComponent y nos servían para crear nuevas clases integradas con el Framework.

Siguiendo con el tema de los componenetes y la extensibilidad en Yii Framework ahora veremos que existen otro tipo de componentes llamados Widgets con los que también podemos extender el framerow. La útilidad de los widgets es que nos permiten construir nuevos elementos visuales para nuestro sitio web. Los Widgets es la forma de extender la parte visual de Yii Framework.

Si quisieramos crear un widget completamente nuevo, la clase que creemos debe extender de CWidget . Esta clase es un componente contenedora de presentación, que permite visualizar datos del modelo. Sin embargo rara vez necesitaremos extender o crear un Widget desde cero. Lo más fácil es extender unos de los widgets que nos proporciona Yii y adaptarlo a nuestras necesidades y eso es lo que veremos a continuación.


Extendiendo la clase CPorlet


El siguiente procedimiento, describe como crear un widget basado en la clase CPortlet. CPorlet es un widget que nos permite mostrar un fragmento de contenido, normalmente elementos del modelo, en las barras laterales de nuestra página web. De esta manera extenderemos CPortles para adaptarlo a nuestras necesidades y generaremos un nuevo widget que muestre los items que necesitemos con el formato que queramos.

A la hora de crear cualquier widget, CPortlet nos da un buen punto de partida para aquellos
widgets que se van a situar en las barras laterales de nuestro sitio web. Visualmente podremos
modificar todo el contenido que vayamos a mostrar.

Escenario

En nuestro escenario, tenemos montado un modelo llamado Productos son un conjunto de productos
que tenemos en la base de datos. Deseamos mostrar los productos que más recientemente se hayan
añadido en la base de datos y hacer el típico widget que muestra los "Productos más recientes".

Solución

Para crear el widget, crearemos en el directorio protected/components de nuestra aplicación Yii un nuevo archivo php llamado ArticulosRecientesWidget.php. Este será el nombre de nuestro widget. Para crear el widget deberemos sobreescribir dos métodos de la clase CPortlet: init() y run().

En nuestro caso lo realizaremos de la siguiente manera:



class ArticulosRecientesWidget extends CPortlet { 
  public function init() {
   return parent::init();
  }
 
  public function run() {  
   $dataProvider=new CActiveDataProvider('Productos', array(
    'criteria'=>array(
     'order' => 'fecha DESC',
     'limit' => 1,
     'offset' => 1,
    ),
    'pagination' => false,
   ));
   
   $this->render('w_articulos_recientes', array(
      'dataProvider' => $dataProvider));
   return parent::run();
  }
 } 



El primero de ellos init() nos permitirá inicializar las variables del widget. En nuestro caso nos limitamos a llamar al método init de la clase padre, que inicializa las propiedades del portlet.

El segundo de ellos run() será llamado por CBaseController::endWidget, para ejecutar el widget y mostrar sus datos. Es en este método, donde obtenemos los datos de los productos y renderizamos la vista del widget.

La vista del widget

La vista es la parte visible de nuestro widget. Podríamos haber renderizado directamente los datos, en el método run() de nuestro widget mediante la función 'echo' de PHP, pero yo recomiendo que se haga mediante el método render() del widget como cuando realizamos una vista normal de cualquier modelo. De esta manera preservaremos la separación entre la vista y el controlador (en este caso el controlador es la clase ArticulosRecientesWidget que es el controlador de nuestro widget).

Para crear la vista del widget, se hace igual que como cuando creamos una vista normal para un modelo. Para ello dentro del directorio /protected/componets creamos un directorio llamado views y ahí dentro colocamos el archivo 'w_articulos_recientes.php' que será nuestra vista

(Nota: como veis en la llamad a $this->render() en la función run() el nombre de la vista es w_articulos_recientes y por tanto el nombre del archivo PHP debe ser también ese).

EL código para la vista será el siguiente:



$this->widget('zii.widgets.CListView', array(
 'dataProvider'=>$dataProvider,
 'itemView'=>'w_articulos_recientes_item',
 'emptyText'=>Yii::t('shop', 'Ningún artículo reciente.'),
 'enablePagination' => false,
 'template' => '{items}',
));



Y como usamos un CListView para renderizar cada elemento de nuestro modelo deberemos crear también el código html para cada uno de los items (en nuestro caso solo va a ser un item). Tenemos que crear el archivo 'w_articulos_recientes_item.php' (en el mismo directorio /protected/components/views), con el siguiente código:

<div class="view" style="height: 70px">
  <div class="column span-12">
    <b><?php echo CHtml::encode($data->getAttributeLabel('nombre')); ?>:</b>
    <?php echo CHtml::link(CHtml::encode($data->nombre), array('productos/view', 'id'=>$data->id)); ?>
    <br />
    <b><?php echo CHtml::encode($data->getAttributeLabel('precio')); ?>:</b>
    <?php echo CHtml::encode(number_format($data->precio,2,",", ".") . '€'); ?>  
    <br />
  </div>   
  <br />
</div>

Una vez tenemos el widget, simplemente debemos llamarlo desde donde queramos de la siguiente manera:



$this->widget('ArticulosRecientesWidget', 
 array(
  'title'=>'Artículos recientes',
  'hideOnEmpty'=>true,
 )
);


En nuestro caso lo llamaremos desde el layout column2.php de la página que es el layout por defecto de la aplicación.

Conclusión

Los dos métodos más importantes de los widgets son init() y run(), que como hemos visto antes controlan la inicialización del widget y su ejecución. En estos dos métodos es donde, fundamentalmente, metermos nuestro código personalizado. Tampoco debemos perder de vista, que la clase que construimos como widget, hace el rol de controlador en nuestro modelo MVC. Eso significa que debe coger los datos del modelo, tratarles y enviarles a la vista correspondente (en nuestro caso la vista del widget). Es un controlador un poco especial, porque sus atribuciones, son solo para presentar los datos.

Las posibilidades de extensión de la parte de presentación, son infinitas, al igual que vimos en el artículo anterior. En este ejemplo hemos cogido CPortlet como clase base, pero Yii nos proporciona otros widgets como CListView o CGridView que también podemos usar como base para construir listas o tablas de datos, modificando su comportamiento de cara a la presentación de los datos del modelo. Heredando de estas clases podríamos mostrar los datos de manera totalmente diferente o añadir a la presentación funcionalidades Ajax que los componentes no posean.

Espero que a través de este artículo os quede un poco más claro para qué sirven y como se usan los Widgets en las aplicaciones Yii Framework.

No hay comentarios:

Publicar un comentario