Escrito por el

Para este primer ciclo del proyecto de desarrollo con Joomla en “Manuales Joomla”, hemos trazado como objetivo primario, desarrollar todos los tipos de extensiones existentes en Joomla. Por lo que una vez termine este ciclo, habremos desarrollado al menos un componente, un módulo, un plugin, una plantilla y una librería.

Con este artículo damos comienzo al primer ciclo del proyecto de desarrollo con Joomla. ¿De que se trata el proyecto? ¿Qué objetivos tiene? ¿De que va eso de los ciclos de desarrollo? Desde el siguiente enlace le damos respuesta a estas interrogantes, por lo que les recomendamos que lean esas dos páginas y vean la estructura que tienen estos ciclos.

Como nuestro desarrollo lo vamos a basar para casos reales, “nos han pedido” hacer un sitio para un blog personal, y la funcionalidad que nos han solicitado que no puede faltar es que los visitantes puedan comentar los trabajos. Por tanto, toca ponernos en modo desarrollador y crear un sistema de comentarios para Joomla.

Vista funcional del formulario. Sin acción de envío de comentarios

Antes que nada, analisemos que nos hace falta, para saber que tenemos que hacer.

  • Necesitamos mostrar un formulario en cada artículo, el cual nos muestre los campos necesarios para que el lector pueda realizar o expresar su opinión. Para esta tarea, crearemos un plugin.
  • Necesitamos mostrar debajo del formulario, una lista con los últimos comentarios del artículo. Esto lo haremos con el mismo plugin previamente creado, ya que sería añadir un layout nuevo al plugin con la lista de los comentarios, debajo del layout del formulario.
  • Necesitamos mostrar en el lateral del blog, un bloque con los últimos comentarios realizados en los artículos de una o varias categorías. Para esta tarea, crearemos un módulo.
  • Necesitamos proveer una interfaz en donde puedan ser gestionados los comentarios del sitio. Para ello, crearemos un componente.

El componente a parte de proveer en la interfaz de administración de nuestro sitio una forma de gestionar los comentarios, también nos servirá para establecer en él la lógica de nuestra programación para el resto de las extensiones. ¿Qué significa esto? Pues, que todas las consultas que se deban hacer a la base de datos, por ejemplo para extraer los últimos comentarios de un artículo, se desarrollaran dentro del modelo del componente. Esto permite que tengamos todo centralizado, y evitarnos que cada una de las otras extensiones tengan que gestionar sus propios datos, que sin duda representa un sobrecarga innecesaria.

Por tanto, todas estas extensiones que mencionamos anteriormente están coo-relacionadas entre sí, ya que una depende de la otra. En Joomla, hay algo que nos permite esta funcionalidad, los Paquetes (Package). ¡Al fin, llego el código!

Estructura básica del paquete

Creamos una carpeta en alguna parte de nuestra PC con el nombre “pkg_mjcommentsystem”. Dentro, tendrá las subcarpetas:

  • extensions: Para almacenar todas las extensiones del paquete
  • language: Para los archivos de idioma del paquete

Ahora le toca el turno al manifiesto de nuestro paquete. Para ello, creamos el archivo “pkg_mjcommentsystem.xml” dentro de la carpeta "pkg_mjcommentsystem" y lo editamos para darle esta forma:

  1. <extension type="package" version="3.1" method="upgrade">
  2. <name>pkg_mjcommentsystem</name>
  3. <author>Carlos Rodriguez</author>
  4. <authorEmail>crsanchez8646@gmail.com</authorEmail>
  5. <authorUrl>manualesjoomla.es</authorUrl>
  6. <creationDate>Noviembre 2015</creationDate>
  7. <packager>Carlos Rodriguez</packager>
  8. <packagename>mjcommentsystem</packagename>
  9. <packagerurl>manualesjoomla.es</packagerurl>
  10. <version>1.0.0</version>
  11. <description>PKG_MJCOMMENTSYSTEM_XML_DESCRIPTION</description>
  12.  
  13. <!-- Extension to install -->
  14. <files folder="extensions">
  15. <!-- Components -->
  16. <file type="component" id="mjcomments">components/com_mjcomments</file>
  17. </files>
  18.  
  19. <languages folder="language">
  20. <language tag="es-ES">es-ES/es-ES.pkg_mjcommentsystem.sys.ini</language>
  21. </languages>
  22. </extension>
<extension type="package" version="3.1" method="upgrade">
   <name>pkg_mjcommentsystem</name>
   <author>Carlos Rodriguez</author>
   <authorEmail>crsanchez8646@gmail.com</authorEmail>
   <authorUrl>manualesjoomla.es</authorUrl>
   <creationDate>Noviembre 2015</creationDate>
   <packager>Carlos Rodriguez</packager>
   <packagename>mjcommentsystem</packagename>
   <packagerurl>manualesjoomla.es</packagerurl>
   <version>1.0.0</version>
   <description>PKG_MJCOMMENTSYSTEM_XML_DESCRIPTION</description>
   
   <!-- Extension to install -->
   <files folder="extensions">
      <!-- Components -->
      <file type="component" id="mjcomments">components/com_mjcomments</file>
   </files>
   
   <languages folder="language">
      <language tag="es-ES">es-ES/es-ES.pkg_mjcommentsystem.sys.ini</language>
   </languages>
</extension>

Hemos declarado en nuestro manifiesto la existencia de un componente llamado “com_mjcomments” y un archivo de idioma “es-ES.pkg_mjcommentsystem.sys.ini” (Archivo de idioma convenciones de nomenclatura y precedencia). Por tanto, vamos a crear estas carpetas y el archivo de idioma que contendrá las cadenas de texto traducibles que tenemos en el manifiesto, quedándonos todo de esta forma:

  1. ; pkg_mjcommentsystem
  2. ; Copyright (C) 2015 Carlos Rodriguez. All rights reserved.
  3. ; License http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL
  4. ; Note : All ini files need to be saved as UTF-8
  5.  
  6. PKG_MJCOMMENTSYSTEM="Blog - Sistema de comentarios"
  7. PKG_MJCOMMENTSYSTEM_XML_DESCRIPTION="Paquete de extensiones del Ciclo 1."
; pkg_mjcommentsystem
; Copyright (C) 2015 Carlos Rodriguez. All rights reserved.
; License http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL
; Note : All ini files need to be saved as UTF-8

PKG_MJCOMMENTSYSTEM="Blog - Sistema de comentarios"
PKG_MJCOMMENTSYSTEM_XML_DESCRIPTION="Paquete de extensiones del Ciclo 1."

Con vista de probar si ya nuestro paquete está funcionando bien, pongamos lo necesario para que el componente se instale correctamente, a pesar de que no haga nada aún.

La instalación de un componente en Joomla consta generalmente de dos interfaces, una para la administración (backend) y otra para la parte pública (frontend). Por lo tanto, crearemos dentro de la carpeta “com_mjcomments” una carpeta llamada “admin” y otra carpeta llamada “site”. Para la correcta instalación de un componente, Joomla establece estos nombres así. Luego crearemos los puntos de entrada a ambos lados. Para ello creamos un archivo php llamado “mjcomments.php” dentro de la carpeta “admin”, y otro archivo de igual nombre y tipo, dentro de la carpeta “site”. No hay que escribir nada de código dentro de ellos, dejenlo en blanco por el momento.

Por último creamos el archivo manifiesto de nuestro componente. El nombre y el tipo sería “com_mjcomments.xml” y lo ponemos dentro de la carpeta “com_mjcomments”. Ahora lo abrimos para editarlo, quedando todo de esta forma:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <extension type="component" version="3.1" method="upgrade">
  3. <name>com_mjcomments</name>
  4. <author>Carlos Rodriguez</author>
  5. <creationDate>November 2015</creationDate>
  6. <copyright>Copyright (C) 2015 Carlos Rodríguez. All rights reserved.</copyright>
  7. <license>License http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL</license>
  8. <authorEmail>crsanchez8646@gmail.com</authorEmail>
  9. <authorUrl>manualesjoomla.es</authorUrl>
  10. <version>1.0.0</version>
  11. <description>COM_MJCOMMENTS_XML_DESCRIPTION</description>
  12.  
  13. <files folder="site">
  14. <filename>mjcomments.php</filename>
  15. </files>
  16.  
  17. <administration>
  18. <files folder="admin">
  19. <filename>mjcomments.php</filename>
  20. </files>
  21. </administration>
  22. </extension>
<?xml version="1.0" encoding="utf-8"?>
<extension type="component" version="3.1" method="upgrade">
   <name>com_mjcomments</name>
   <author>Carlos Rodriguez</author>
   <creationDate>November 2015</creationDate>
   <copyright>Copyright (C) 2015 Carlos Rodríguez. All rights reserved.</copyright>
   <license>License http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL</license>
   <authorEmail>crsanchez8646@gmail.com</authorEmail>
   <authorUrl>manualesjoomla.es</authorUrl>
   <version>1.0.0</version>
   <description>COM_MJCOMMENTS_XML_DESCRIPTION</description>

   <files folder="site">
      <filename>mjcomments.php</filename>
   </files>

   <administration>
      <files folder="admin">
         <filename>mjcomments.php</filename>
      </files>
   </administration>
</extension>

En este manifiesto le estamos diciendo al instalador de Joomla, que lea dentro de la carpeta “site” y coloque todos los archivos y carpetas que ahí se encuentran en la ruta raíz_sitio/components/com_mjcomments (línea 13 - 15). Y que lea dentro de la carpeta “admin” y coloque todo lo que encuentre en la ruta raíz_sitio/administrator/components/com_mjcomments (línea 17 - 21). Vean que la única diferencia son las etiquetas <administration>.....</administration>. Con esto ya podemos probar si podemos o no instalar nuestro paquete. Así que abrimos la administración del sitio, y vamos a Extensiones->Gestionar. Dentro escogemos la opción Instalar desde una carpeta y ponemos la ruta absoluta en donde está nuestro paquete de extensiones, por ejemplo, en mi caso bajo el SO Windows sería este: D:\Carlos\Joomla\Code Repo\pkg_mjcommentsystem. Luego le damos a instalar para completar el proceso.

Todo funciona correctamente. Ya tenemos un registro nuevo en la tabla “#__extensions” de nuestro paquete, permitiéndonos de esta forma poder desinstalar o instalar un grupo de extensiones comunes entre sí, supliendo de esta forma la necesidad de la gestión de dependencia en las extensiones.

Desarrollo básico del manifiesto

Al principio comentamos que el componente va a ser el núcleo central de nuestro desarrollo, ya que en él se iban a gestionar todos los datos que van a necesitar las demás extensiones. Vamos a mostrar una imagen, que siempre dice más:

Ahora se entiende mejor qué queremos decir cuando tenemos centralizadas todas nuestras consultas. Dentro del componente se llevará a cabo todo el saneamiento de los datos que se están manejando, para luego enviar los mismo de manera correcta a cada una de las extensiones que los solicitaron.

Teniendo esto claro, antes de seguir debemos volver hacer otro análisis. ¿Que se necesita para crear una vista funcional del formulario? La respuesta a esta pregunta es el objetivo de este primer tutorial.

Lo primero que necesitamos, es definir que campos vamos a utilizar en nuestro formulario y en donde vamos a guardar los valores entrados. Para ello vamos primero al archivo manifiesto de nuestro componente “com_mjcomments.xml” y lo abrimos para editarlo, añadiendo lo siguiente:

  1. <install>
  2. <sql>
  3. <file charset="utf8" driver="mysql">sql/install/mysql/install.sql</file>
  4. </sql>
  5. </install>
  6. <uninstall>
  7. <sql>
  8. <file charset="utf8" driver="mysql">sql/install/mysql/uninstall.sql</file>
  9. </sql>
  10. </uninstall>
  11. <update>
  12. <schemas>
  13. <schemapath type="mysql">sql/updates/mysql</schemapath>
  14. </schemas>
  15. </update>
<install>
   <sql>
      <file charset="utf8" driver="mysql">sql/install/mysql/install.sql</file>
   </sql>
</install>
<uninstall>
   <sql>
      <file charset="utf8" driver="mysql">sql/install/mysql/uninstall.sql</file>
   </sql>
</uninstall>
<update>
   <schemas>
      <schemapath type="mysql">sql/updates/mysql</schemapath>
   </schemas>
</update>

Aquí le decimos al instalador de Joomla donde se encuentra el archivo para crear las tablas necesarias en la base de datos (línea 13 - 17). También le decimos dónde se encuentra el archivo para desinstalar estas mismas tablas, en caso que el componente sea desinstalado (línea 18 - 22). Y por último, le decimos en donde tiene que buscar en caso de que el componente sea actualizado (línea 23 - 27).

Nota: Notarán que en la organización que le hemos dado a las carpetas, existe una carpeta llamada “mysql”, esto es porque en cada etiqueta <file> el driver de la base de datos que está presente es el de “mysql”, por lo que si queremos darle soporte a “postgresql” por ejemplo, tenemos que añadir una nueva etiqueta con el driver y añadir una nueva carpeta con el nombre correspondiente.

Ahora creamos todas estas carpetas con sus archivos dentro de la carpeta “admin” del componente. Empecemos con “install.sql”:

  1. span style="color: #ff0000;">`#__mjcomments` (
  2. `id``content_id``visitor_name``visitor_email``visitor_comments``created`'0000-00-00 00:00:00',
  3. `state``id``idx_state` (`state`
CREATE TABLE IF NOT EXISTS `#__mjcomments` (
   `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
   `content_id` int(11) UNSIGNED NOT NULL,
   `visitor_name` varchar(255) NOT NULL,
   `visitor_email` varchar(100) NOT NULL,
   `visitor_comments` text NOT NULL,
   `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
   `state` tinyint(2) NOT NULL DEFAULT 0,
   PRIMARY KEY (`id`),
   KEY `idx_state` (`state`)
)  ENGINE=InnoDB DEFAULT CHARSET=utf8;

Como ven, hemos creado algunos campos básicos para nuestro sistema de comentarios, uno para el nombre de la persona que comente, otro para su correo electrónico, otro para el comentario en sí y también hemos añadido la fecha de creación del comentario y el estado (publicado o despublicado) en que se encuentra. Este último campo, podemos utilizarlo para la moderación de los comentarios. Es decir, podemos poner que por defecto todos los comentarios que se hagan tengan el estado “despublicado” para que un moderador los revise y le de el visto bueno y los publique. Recordar también que Joomla cambia el comodín “#__” por el prefijo que se esté usando en las tablas de nuestra base de datos

EL siguiente archivo es “uninstall.sql”:

  1. span style="color: #ff0000;">`#__mjcomments`;
DROP TABLE IF EXISTS `#__mjcomments`;

Y por último, crearemos un archivo llamado “1.0.0.sql” dentro de la carpeta “updates/mysql” con el fin de inicializar el esquema en la base de datos y decirle a Joomla la versión actual de nuestra extensión:

  1. -- Versión inicial del componente
-- Versión inicial del componente

Vale aclarar, que como en este caso, sucede que el archivo no tiene nada al no ser un comentario, pero es importante mantener un archivo para cada nueva versión de nuestro componente.

Por último, añadimos al manifiesto del componente la nueva carpeta “sql” que hemos incluido, quedándonos de esta forma:

Si volvemos a instalar nuestro paquete (que en este caso sería actualizarlo), podremos ver como en la tabla “schemas” ya hay un registro estableciendo la versión del componente. Además, podrán ver la tabla nueva que acabamos de crear.

Desarrollo del xml para los campos del formulario

Ahora que ya sabemos que vamos a guardar y en donde lo vamos a guardar, pasemos a la creación de los campos para el formulario.

Joomla maneja estos campos usando un archivo XML para los mismos. Pero estos campos no se van a definir dentro del manifiesto del componente, sino que hay que crear un archivo individual para ellos. Según la estructura que nos plantea el desarrollo con Joomla, este archivo debe ser colocado dentro de una carpeta llamada “forms” o  dentro de la carpeta “models” (lugar de los modelos del componente). Como son campos que vamos a manejar desde el frontend, pues creamos esta estructura desde la carpeta “site”. Como los campos que vamos a definir son para el formulario de comentar, llamaremos al archivo “formcomment.xml” colocando dentro los campos que necesitamos. Todo esto queda de la siguiente forma:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <form>
  3. <fieldset name="basic" label="COM_MJCOMMENTS_FORMS_FORM_BASIC">
  4. <field
  5. name="visitor_name"
  6. type="text"
  7. label="COM_MJCOMMENTS_FORMS_FORM_BASIC_NAME_LABEL"
  8. description="COM_MJCOMMENTS_FORMS_FORM_BASIC_NAME_DESC"
  9. filter="string"
  10. required="true"
  11. size="30"
  12. class="form-control"
  13. />
  14.  
  15. <field
  16. name="visitor_email"
  17. type="email"
  18. label="COM_MJCOMMENTS_FORMS_FORM_BASIC_EMAIL_LABEL"
  19. description="COM_MJCOMMENTS_FORMS_FORM_BASIC_EMAIL_DESC"
  20. message="COM_MJCOMMENTS_FORMS_FORM_BASIC_EMAIL_MESSAGE"
  21. filter="string"
  22. required="true"
  23. size="30"
  24. validate="email"
  25. class="form-control"
  26. />
  27.  
  28. <field
  29. name="visitor_comments"
  30. type="textarea"
  31. label="COM_MJCOMMENTS_FORMS_FORM_BASIC_COMMENTS_LABEL"
  32. description="COM_MJCOMMENTS_FORMS_FORM_BASIC_COMMENTS_DESC"
  33. rows="6"
  34. cols="100%"
  35. required="true"
  36. class="form-control"
  37. hint="COM_MJCOMMENTS_FORMS_FORM_BASIC_COMMENTS_PLACEHOLDER"
  38. />
  39.  
  40. <field
  41. name="content_id"
  42. type="hidden"
  43. default="0"
  44. />
  45. </fieldset>
  46. </form>
<?xml version="1.0" encoding="utf-8"?>
<form>
   <fieldset name="basic" label="COM_MJCOMMENTS_FORMS_FORM_BASIC">
      <field
         name="visitor_name"
         type="text"
         label="COM_MJCOMMENTS_FORMS_FORM_BASIC_NAME_LABEL"
         description="COM_MJCOMMENTS_FORMS_FORM_BASIC_NAME_DESC"
         filter="string"
         required="true"
         size="30"
         class="form-control"
      />

      <field
         name="visitor_email"
         type="email"
         label="COM_MJCOMMENTS_FORMS_FORM_BASIC_EMAIL_LABEL"
         description="COM_MJCOMMENTS_FORMS_FORM_BASIC_EMAIL_DESC"
         message="COM_MJCOMMENTS_FORMS_FORM_BASIC_EMAIL_MESSAGE"
         filter="string"
         required="true"
         size="30"
         validate="email"
         class="form-control"
      />

      <field
         name="visitor_comments"
         type="textarea"
         label="COM_MJCOMMENTS_FORMS_FORM_BASIC_COMMENTS_LABEL"
         description="COM_MJCOMMENTS_FORMS_FORM_BASIC_COMMENTS_DESC"
         rows="6"
         cols="100%"
         required="true"
         class="form-control"
         hint="COM_MJCOMMENTS_FORMS_FORM_BASIC_COMMENTS_PLACEHOLDER"
      />

      <field
         name="content_id"
         type="hidden"
         default="0"
      />
   </fieldset>
</form>

Como ven, la estructura de este archivo no es compleja. Tenemos diferentes tipos de campos, un campo de tipo “text” para el nombre, otro de tipo “email” para el correo electrónico, otro de tipo “textarea” para el texto del comentario y por último uno de tipo “hidden” el cual utilizaremos para almacenar el ID del artículo en que se realizó el comentario, porque recuerden que tenemos un campo en la tabla que está en la base de datos llamado “content_id” donde su función es precisamente esta.

Quiero que observen como los nombres de los campos en este archivo XML, coinciden con los nombres de los campos en la tabla de la base de datos. Esto como es lógico no es una casualidad y se tiene que utilizar así, porque es de esta forma que Joomla sabe que campo corresponde a quien a la hora de guardar o eliminar o actualizar algún registro en la tabla de la base de datos. Esto no quiere decir, que para poder poner más campos en el archivo XML, tengamos que añadir una nueva columna en la tabla de la base de datos. Podemos poner cuanto campo necesitemos en este archivo XML, pero solo aquellos donde el nombre coinciden se gestionan con la tabla de la base de datos.

En este último archivo, se nos han generado unas cuantas cadenas de texto traducibles, pero hasta el momento no tenemos donde asignarle algún valor a las mismas, cambiemos esto. Como estas cadenas de texto traducibles, son pertenecientes al frontend, pues creamos una carpeta “language” dentro de la carpeta “site”. Dentro colocamos una carpeta con el idioma que estamos manejando “es-ES” y un archivo llamado “es-ES.com_mjcomments.ini” con los valores de estas cadenas de texto traducibles. Todo esto queda de la siguiente forma:

  1. ; com_mjcomments
  2. ; Copyright (C) 2015 Carlos Rodriguez. All rights reserved.
  3. ; License http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL
  4. ; Note : All ini files need to be saved as UTF-8
  5.  
  6. COM_MJCOMMENTS="MJ - Sistema de comentarios"
  7. COM_MJCOMMENTS_XML_DESCRIPTION="Gestor de comentarios del Ciclo 1."
  8.  
  9. ; Comment form
  10. COM_MJCOMMENTS_FORMS_FORM_BASIC="Comentarios"
  11. COM_MJCOMMENTS_FORMS_FORM_BASIC_COMMENTS_LABEL="Texto"
  12. COM_MJCOMMENTS_FORMS_FORM_BASIC_COMMENTS_DESC="Texto del comentario."
  13. COM_MJCOMMENTS_FORMS_FORM_BASIC_COMMENTS_PLACEHOLDER="Haga un comentario..."
  14. COM_MJCOMMENTS_FORMS_FORM_BASIC_EMAIL_LABEL="Correo (no será publicado)"
  15. COM_MJCOMMENTS_FORMS_FORM_BASIC_EMAIL_DESC="Correo electrónico del MJisitante."
  16. COM_MJCOMMENTS_FORMS_FORM_BASIC_EMAIL_MESSAGE="Correo electrónico incorrecto. Por favor, añada un correo electrónico válido."
  17. COM_MJCOMMENTS_FORMS_FORM_BASIC_NAME_LABEL="Nombre"
  18. COM_MJCOMMENTS_FORMS_FORM_BASIC_NAME_DESC="Nombre del visitante."
; com_mjcomments
; Copyright (C) 2015 Carlos Rodriguez. All rights reserved.
; License http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL
; Note : All ini files need to be saved as UTF-8

COM_MJCOMMENTS="MJ - Sistema de comentarios"
COM_MJCOMMENTS_XML_DESCRIPTION="Gestor de comentarios del Ciclo 1."

; Comment form
COM_MJCOMMENTS_FORMS_FORM_BASIC="Comentarios"
COM_MJCOMMENTS_FORMS_FORM_BASIC_COMMENTS_LABEL="Texto"
COM_MJCOMMENTS_FORMS_FORM_BASIC_COMMENTS_DESC="Texto del comentario."
COM_MJCOMMENTS_FORMS_FORM_BASIC_COMMENTS_PLACEHOLDER="Haga un comentario..."
COM_MJCOMMENTS_FORMS_FORM_BASIC_EMAIL_LABEL="Correo (no será publicado)"
COM_MJCOMMENTS_FORMS_FORM_BASIC_EMAIL_DESC="Correo electrónico del MJisitante."
COM_MJCOMMENTS_FORMS_FORM_BASIC_EMAIL_MESSAGE="Correo electrónico incorrecto. Por favor, añada un correo electrónico válido."
COM_MJCOMMENTS_FORMS_FORM_BASIC_NAME_LABEL="Nombre"
COM_MJCOMMENTS_FORMS_FORM_BASIC_NAME_DESC="Nombre del visitante."

Teniendo los campos listos para su uso, pasemos ahora a crear el modelo que se encargará de manejarlos. Para ello creamos un archivo llamado “formcomment.php” dentro de la carpeta “models” y su misión será por el momento, obtener de manera correcta estos campos para su posterior visualización en el sitio. Como dato curioso, noten que es la primera vez que vamos a escribir código php.

  1. span style="color: #808080; font-style: italic;">/**
  2.  * @package MJ.Component
  3.  * @subpackage mjcomments
  4.  *
  5.  * @copyright Copyright (C) 2015 Carlos Rodriguez. All rights reserved.
  6.  * @license License http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL
  7.  */'_JEXEC'/**
  8.  * Form model class.
  9.  *
  10.  *//**
  11.   * Method to get the form.
  12.   *
  13.   * @param array $data An optional array of data for the form to interogate.
  14.   * @param boolean $loadData True if the form is to load its own data (default case), false if not.
  15.   *
  16.   * @return JForm A JForm object on success, false on failure
  17.   *
  18.   */// Get the form.
  19. 'com_mjcomments.formcomment', 'formcomment''control' => 'jform', 'load_data'
<?php
/**
* @package MJ.Component
* @subpackage mjcomments
*
* @copyright Copyright (C) 2015 Carlos Rodriguez. All rights reserved.
* @license License http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL
*/

defined('_JEXEC') or die;

/**
* Form model class.
*
*/
class MjcommentsModelFormcomment extends JModelForm
{
   /**
    * Method to get the form.
    *
    * @param array $data An optional array of data for the form to interogate.
    * @param boolean $loadData True if the form is to load its own data (default case), false if not.
    *
    * @return JForm A JForm object on success, false on failure
    *
    */
   public function getForm($data = array(), $loadData = false)
   {
      // Get the form.
      $form = $this->loadForm('com_mjcomments.formcomment', 'formcomment', array('control' => 'jform', 'load_data' => $loadData));

      if (empty($form))
      {
         return false;
      }

      return $form;
   }
}

Primero que nada, la línea 10 de este archivo es una constante para todos los archivos php que creemos en lo adelante. Pueden ver su explicación aquí.

¿Que más pusimos dentro de este archivo? Primero, declaramos una clase llamada “MjcommentsModelFormcomment”, esto por supuesto no es a priori. Joomla establece esta nomenclatura. Primero se pone el nombre del componente siempre con la primera letra en mayúscula, seguido por la palabra “Model” y por último, el nombre del modelo (el cual es a su vez el mismo nombre del archivo) que estamos llevando a cabo, empezando también con la primera letra en mayúscula.

Luego le decimos a nuestra clase que herede de “JModelForm”. A esta clase padre (libraries\legacy\model\form.php) sin duda le podemos dedicar un artículo completo, explicando cada una de las funciones que contiene, pero como va a ser una clase que vamos a utilizar bastante en todos los ciclos de desarrollo que llevemos a cabo, pues la explicamos a medida que vayamos avanzando en los mismos.

Como ven, nuestra clase actualmente contiene una única función. Esta función está implementada dentro de “JModelForm”, pero no tiene contexto alguno (Joomla 3.4.5 - libraries\legacy\model\form.php - línea 144), solo es una función abstracta la cual hay que implementar obligatoriamente en nuestra nueva clase creada, porque por lógica, sin esta función no se podría empezar nada, ya que es ella la que se tiene de encargar de obtener el formulario.

Nuestra función “getForm” recibe dos argumentos. La variable “data”, la cual contiene opcionalmente un array de campos adicionales a ser comprobado para el formulario. La otra variable que se pasa como argumento es “loadData”. Esta variable es un valor booleano, que si es “true” entonces la función “loadForm” que está más abajo (línea 30) en su implementación va a utilizar otra función llamada “loadFormData” ¿Para que es esta función? lo veremos más adelante cuando nos haga falta que “loadData” contenga el valor “true”. Por el momento “loadForm” lo ponemos en “false” por lo que solo obtendremos un array vacío.

La función “loadForm” que utilizamos en la línea 30, es la que se va a encargar de obtener el formulario o el archivo XML que hemos creado anteriormente el cual conforma nuestro formulario. Esta función está implementada en la clase “JModelForm” que estamos heredando (Joomla 3.4.5 - libraries\legacy\model\form.php - línea 160 a 212).

El primer argumento que le pasamos, es la variable que registra los datos del formulario en la sesión con el fin de redirigir al visitante al formulario en caso de errores o campos faltantes. De esta manera, el visitante no tiene que volver a introducir los campos ya introducidos en el formulario.

El otro argumento que pasamos sería el nombre del formulario que queremos que Joomla lea. Como queremos que Joomla lea el archivo “formcomment.xml” pues ponemos “formcomment”. Por defecto y ustedes lo pueden ver (línea 175 - libraries\legacy\model\form.php) Joomla busca dentro de la carpeta “/models/forms” de nuestro componente un archivo con igual nombre al que nosotros le pasamos en este argumento, siendo este el formulario a utilizar.

El último argumento es un array usado para la configuración. Nada que destacar aquí, tan solo observen que uno de los valores es “loadData” que aún no lo vamos a utilizar.

La función “getForm” acaba devolviendo el formulario en caso de que no esté vacío.

Con esto hecho, ya nos queda menos para poder visualizar el formulario. Pero antes de continuar, hay que recordar que hemos añadido dos carpetas nuevas, “language” y “models” por lo que hay que actualizar el manifiesto de nuestro componente y añadir las mismas para que le instalador de Joomla las añada en la próxima actualización. Esto quedaría de la siguiente forma:

  1. <folder>language</folder>
  2. <folder>models</folder>
<folder>language</folder>
<folder>models</folder>

Creación de la estructura del plugin

Para completar la misión solo resta poder visualizar nuestro formulario. Como explicamos al principio, utilizaremos un plugin (con nombre mjformcomment) para darle respuesta a este problema. Lo primero es crear el sistema de carpetas con el archivo de entrada del plugin y actualizar el manifiesto de nuestro paquete añadiendo todo esto al mismo. Quedaría así:

  1. <file type="plugin" id="mjformcomment" group="content">plugins/content/mjformcomment</file>
<file type="plugin" id="mjformcomment" group="content">plugins/content/mjformcomment</file>

Aquí solo destacar que para el caso de los plugins, un nuevo atributo “group” aparece. Como los plugins se organizan en grupos, este atributo especifica a qué grupo pertenece este plugin. Como queremos mostrar el formulario de comentar dentro de un artículo, necesitamos hacer uso del evento “onContentAfterDisplay” disponible solo para el grupo de plugin de contenido o “content”. Este evento es disparado al final del contenido de un artículo, el cual es el lugar exacto donde queremos mostrar el formulario. Pueden mirar en el archivo “default.php” en components\com_content\views\article\tmpl y verán que al final del archivo se encuentra la línea siguiente:

  1.  
<?php echo $this->item->event->afterDisplayContent; ?>

Esta línea es la responsable de disparar el evento “onContentAfterDisplay”.

Pasemos ahora a crear el manifiesto del plugin. Además de lo básico que lleva el manifiesto, notaran que configuraremos dos parámetros, uno es el layout que se va a utilizar por defecto y otro la categoría en la que el plugin va a funcionar. Vamos a editar el manifiesto, y luego veremos para que nos van a servir esos parámetros. El archivo “mjformcomment.xml” quedaría de esta forma:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <extension version="3.1" type="plugin" group="content" method="upgrade">
  3. <name>plg_content_mjformcomment</name>
  4. <author>Carlos Rodriguez</author>
  5. <creationDate>December 2015</creationDate>
  6. <copyright>Copyright (C) 2015 Carlos Rodriguez. All rights reserved.</copyright>
  7. <license>License http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL</license>
  8. <authorEmail>crsanchez8646@gmail.com</authorEmail>
  9. <authorUrl>manualesjoomla.es</authorUrl>
  10. <version>1.0.0</version>
  11. <description>PLG_CONTENT_MJFORMCOMMENT_XML_DESCRIPTION</description>
  12.  
  13. <files>
  14. <filename plugin="comment">comment.php</filename>
  15. </files>
  16.  
  17. <config>
  18. <fields name="params">
  19. <fieldset name="basic">
  20. <field
  21. name="layout"
  22. type="modulelayout"
  23. default="_:default"
  24. label="PLG_CONTENT_MJFORMCOMMENT_PARAMS_LAYOUT"
  25. description="PLG_CONTENT_MJFORMCOMMENT_PARAMS_LAYOUT_DESC"
  26. />
  27. <field
  28. name="catid"
  29. type="category"
  30. extension="com_content"
  31. multiple="true"
  32. default=""
  33. size="10"
  34. label="JCATEGORY"
  35. description="PLG_CONTENT_MJFORMCOMMENT_PARAMS_CATEGORY_DESC"
  36. >
  37. <option value="all">JOPTION_ALL_CATEGORIES</option>
  38. </field>
  39. </fieldset>
  40. </fields>
  41. </config>
  42. </extension>
<?xml version="1.0" encoding="utf-8"?>
<extension version="3.1" type="plugin" group="content" method="upgrade">
   <name>plg_content_mjformcomment</name>
   <author>Carlos Rodriguez</author>
   <creationDate>December 2015</creationDate>
   <copyright>Copyright (C) 2015 Carlos Rodriguez. All rights reserved.</copyright>
   <license>License http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL</license>
   <authorEmail>crsanchez8646@gmail.com</authorEmail>
   <authorUrl>manualesjoomla.es</authorUrl>
   <version>1.0.0</version>
   <description>PLG_CONTENT_MJFORMCOMMENT_XML_DESCRIPTION</description>

   <files>
      <filename plugin="comment">comment.php</filename>
   </files>

   <config>
      <fields name="params">
         <fieldset name="basic">
            <field
               name="layout"
               type="modulelayout"
               default="_:default"
               label="PLG_CONTENT_MJFORMCOMMENT_PARAMS_LAYOUT"
               description="PLG_CONTENT_MJFORMCOMMENT_PARAMS_LAYOUT_DESC"
            />
            <field
               name="catid"
               type="category"
               extension="com_content"
               multiple="true"
               default=""
               size="10"
               label="JCATEGORY"
               description="PLG_CONTENT_MJFORMCOMMENT_PARAMS_CATEGORY_DESC"
            >
               <option value="all">JOPTION_ALL_CATEGORIES</option>
            </field>
         </fieldset>
      </fields>
   </config>
</extension>

Notaran que le manifiesto del plugin, es muy semejante al de un componente, y verán, que también es muy semejante al de un módulo. Una de las diferencias en este manifiesto, es el atributo “group” de la etiqueta “extension” en la línea 2, el cual hace la misma función que explicamos cuando lo declaramos en el manifiesto del paquete la existencia de un plugin.

El bloque donde declaramos los archivos y carpetas que contiene el plugin, es muy semejante también, con la diferencia que el archivo de entrada del plugin, lleva el atributo “plugin” con el nombre del plugin a instalar, veanlo en la línea 14.

Por último, aparecen los parámetros del plugin. Este formato que usamos para declarar los parámetros, es común para todas las extensiones. Ya lo veremos cuando avancemos más en el ciclo.

Declaramos 2 parámetros. Uno de tipo “modulelayout”, el cual nos proporciona la grandiosa funcionalidad de los layout. El otro es de tipo “category” que nos brinda una lista con las categorías creadas en el “com_content”, más una opción para marcar todas, en caso de que queramos que funcione para todas. Este parámetro lo utilizaremos para que el plugin solo trabaje en las categorías que le indiquemos desde aquí. Es decir, el formulario para comentar solo será mostrado en aquellas categorías seleccionadas.

Hagamos una actualización al paquete, para ver estos parámetros desde la administración del sitio.

Cuando actualizamos nuestro paquete, si vamos al gestor de plugin y filtramos por los tipos de plugin de “content” veremos el de nosotros listado. Cuando accedemos a la configuración de sus parámetros, veremos los dos que ya habíamos creado desde el manifiesto. El de los layout sale de esa forma, porque aún no hemos creado ninguno. También noten, que las cadenas de texto traducibles salen en su forma bruta, por lo que lo próximo es crear la carpeta “lenguage” dentro del plugin para poder asignarle valores a estas cadenas. Esto quedaría de esta forma:

es-ES.plg_content_mjformcomment.ini

  1. ; plg_content_mjformcomment
  2. ; Copyright (C) 2015 Carlos Rodriguez. All rights reserved.
  3. ; License http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL
  4. ; Note : All ini files need to be saved as UTF-8
  5.  
  6. ; Plugin
  7. PLG_CONTENT_MJFORMCOMMENT_PARAMS_LAYOUT="Plantilla"
  8. PLG_CONTENT_MJFORMCOMMENT_PARAMS_LAYOUT_DESC="Selecciona la plantilla que quieres usar para el plugin."
  9. PLG_CONTENT_MJFORMCOMMENT_PARAMS_CATEGORY_DESC="Escoga en que categorías del gestor de artículos funcionara el formulario para comentar."
  10.  
  11. ; System
  12. PLG_CONTENT_MJFORMCOMMENT="MJ - Formulario para comentar"
  13. PLG_CONTENT_MJFORMCOMMENT_XML_DESCRIPTION="Añade un formulario para la inserción de comentarios al artículo, así como una lista de los comentarios que tiene el artículo."
; plg_content_mjformcomment
; Copyright (C) 2015 Carlos Rodriguez. All rights reserved.
; License http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL
; Note : All ini files need to be saved as UTF-8

; Plugin
PLG_CONTENT_MJFORMCOMMENT_PARAMS_LAYOUT="Plantilla"
PLG_CONTENT_MJFORMCOMMENT_PARAMS_LAYOUT_DESC="Selecciona la plantilla que quieres usar para el plugin."
PLG_CONTENT_MJFORMCOMMENT_PARAMS_CATEGORY_DESC="Escoga en que categorías del gestor de artículos funcionara el formulario para comentar."

; System
PLG_CONTENT_MJFORMCOMMENT="MJ - Formulario para comentar"
PLG_CONTENT_MJFORMCOMMENT_XML_DESCRIPTION="Añade un formulario para la inserción de comentarios al artículo, así como una lista de los comentarios que tiene el artículo."

es-ES.plg_content_mjformcomment.sys.ini

  1. ; plg_content_mjformcomment
  2. ; Copyright (C) 2015 Carlos Rodriguez. All rights reserved.
  3. ; License http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL
  4. ; Note : All ini files need to be saved as UTF-8
  5.  
  6. PLG_CONTENT_MJFORMCOMMENT="MJ - Formulario para comentar"
  7. PLG_CONTENT_MJFORMCOMMENT_XML_DESCRIPTION="Añade un formulario para la inserción de comentarios al artículo, así como una lista de los comentarios que tiene el artículo."
; plg_content_mjformcomment
; Copyright (C) 2015 Carlos Rodriguez. All rights reserved.
; License http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL
; Note : All ini files need to be saved as UTF-8

PLG_CONTENT_MJFORMCOMMENT="MJ - Formulario para comentar"
PLG_CONTENT_MJFORMCOMMENT_XML_DESCRIPTION="Añade un formulario para la inserción de comentarios al artículo, así como una lista de los comentarios que tiene el artículo."

Hemos creado dos archivos de idioma, uno con el nombre “es-ES.plg_content_mjformcomment.ini” y otro con el nombre “es-ES.plg_content_mjformcomment.sys.ini” ¿Porqué? pueden leerlo aquí.

Recuerden que para que Joomla sepa, que hemos incluido estas carpetas y archivos en la próxima actualización del paquete, necesitamos actualizar el manifiesto del plugin añadiendo la carpeta “language”.

  1. <folder>language</folder>
<folder>language</folder>

De esta forma, si actualizamos el paquete nuevamente ya las cadenas que antes las veíamos en su forma menos vistosa, ahora son bastante vistosas, y valga la redundancia.

Pasemos ahora a desarrollar el punto de entrada del plugin. Como hasta ahora hemos hecho, mostramos como queda para explicar luego lo que hicimos. Editamos el archivo “mjformcomment.php”:

  1. span style="color: #808080; font-style: italic;">/**
  2.  * @package MJ.Plugin
  3.  * @subpackage Content.Mjformcomment
  4.  *
  5.  * @copyright Copyright (C) 2015 Carlos Rodriguez. All rights reserved.
  6.  * @license License http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL
  7.  */'_JEXEC'/**
  8.  * Mjformcomment plugin.
  9.  *
  10.  *//**
  11.   * A JForm object on success, false on failure
  12.   *
  13.   * @var JForm
  14.   *//**
  15.   * Displays the comments area
  16.   *
  17.   * @param string $context The context of the content being passed to the plugin
  18.   * @param object &amp;$row The article object
  19.   * @param object &amp;$params The article params
  20.   * @param integer $page The 'page' number
  21.   *
  22.   * @return mixed html string containing code for the comment if in com_content.article else boolean false
  23.   *
  24.   */".", $context);
  25. $plgCatid = $this->params->def('catid');
  26.  
  27. // Check is run com_content
  28. 'com_content'// Check category of the plugin in the allowable category array of the plugin
  29. 'all'// Name of the variables that will be used in the layout
  30. 'view' => $context,
  31. 'form''default''data''/layouts');
  32. }
  33.  
  34. /**
  35.   * Method to get the comment form
  36.   *
  37.   * @return html Html comment form structure
  38.   */'Formcomment'/**
  39.   * Method to get the model instance.
  40.   *
  41.   * @param string $name The model
  42.   * @param string $prefix The model prefix
  43.   *
  44.   * @return JForm A JForm object on success, false on failure
  45.   *
  46.   */'Mjcomments')
  47. {
  48. // Get an instance of the generic form model
  49. 'ignore_request'
<?php
/**
* @package MJ.Plugin
* @subpackage Content.Mjformcomment
*
* @copyright Copyright (C) 2015 Carlos Rodriguez. All rights reserved.
* @license License http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL
*/

defined('_JEXEC') or die;

/**
* Mjformcomment plugin.
*
*/
class PlgContentMjformcomment extends JPlugin
{
   /**
    * A JForm object on success, false on failure
    *
    * @var JForm
    */
   protected $form;

   /**
    * Displays the comments area
    *
    * @param string $context The context of the content being passed to the plugin
    * @param object &$row The article object
    * @param object &$params The article params
    * @param integer $page The 'page' number
    *
    * @return mixed html string containing code for the comment if in com_content.article else boolean false
    *
   */
   public function onContentAfterDisplay($context, &$row, &$params, $page=0)
   {
      $parts = explode(".", $context);
      $plgCatid = $this->params->def('catid');

      // Check is run com_content
      if ($parts[0] != 'com_content')
      {
         return false;
      }

      // Check category of the plugin in the allowable category array of the plugin
      if ($plgCatid[0] != 'all' && !in_array($row->catid, $plgCatid))
      {
         return false;
      }

      $this->setCommentForm();

      // Name of the variables that will be used in the layout
      $data = array(
         'view' => $context,
         'form' => $this->form
      );

      return JLayoutHelper::render('default', compact('data'), __DIR__ . '/layouts');
}

   /**
    * Method to get the comment form
    *
    * @return html Html comment form structure
    */
   protected function setCommentForm()
   {
      $modelForm = $this->getModel('Formcomment');
      $this->form = $modelForm->getForm();
   }

   /**
    * Method to get the model instance.
    *
    * @param string $name The model
    * @param string $prefix The model prefix
    *
    * @return JForm A JForm object on success, false on failure
    *
    */
   protected function getModel($name, $prefix = 'Mjcomments')
   {
      // Get an instance of the generic form model
      $model = JModelLegacy::getInstance($name, $prefix, array('ignore_request' => true));
      return $model;
   }
}




Sin duda se darán cuenta que no hemos hecho casi nada, apenas 91 líneas. ¿Recuerdan lo que escribimos dentro del modelo del componente? Nada prácticamente también. Los plugins son las extensiones más fáciles de desarrollar en Joomla, y son sumamente utilizados. Expliquemos un poco lo que hemos hecho.

Primero, les corresponde una lectura la cual nos ahorra reinventar la rueda. Empezaremos explicando desde la última función hacia arriba.

La función “getModel” nos permitirá obtener el modelo que necesitamos para pedir los campos del formulario. Recibe 2 argumentos el nombre del modelo, y el prefijo del mismo. En nuestro caso, queremos obtener el modelo del componente de comentarios, el cual nos brindara todo lo necesario para el trabajo con el formulario para comentar. Si recuerdan, la clase de nuestro modelo llevaba por nombre “MjcommentsModelFormcomment”, por lo que en la variable $name el nombre que debe aparecer es “Formcomment”. Y esto es precisamente lo que hace la función “setCommentForm”, le asigna a la variable global $form que hemos declarado dentro de la clase del plugin, la estructura del objeto de nuestro formulario.

La función “onContentAfterDisplay” no necesita presentación. Si tienen duda sobre ella, recuerden que pueden documentarse aquí. Hicimos algunas comprobaciones para saber si estamos en el lugar correcto para que el plugin haga su trabajo. Por ejemplo, comprobamos que la vista de la página que está siendo generada en el sitio sea del componente “com_content” (Línea 42 - 45). También comprobamos que la categoría a la que pertenece la vista de la página que estamos visitando, este dentro del grupo de categorías asignadas en los parámetros del plugin (Línea 48 - 51).

Luego creamos un array con todos los valores recogidos, y se lo pasamos al layout con nombre “default” de nuestro plugin (Línea 61). Layout que aún no hemos creado. Recuerden que la explicación de esta función pueden verla aquí.

Con la lógica ya creada en el punto de entrada de nuestro plugin, nos queda una última tarea para completar nuestra misión. Crear el layout encargado de la visualización del formulario. Manos a la obra.

Lo primero es crear una carpeta dentro del plugin llamada “layouts”, lo que cual conlleva que a su vez actualicemos el manifiesto del plugin para declarar la misma. Dentro de la carpeta “layouts” crearemos el archivo “default.php” el cual es la vista que tanto queremos mostrar. Este archivo contiene lo siguiente:

  1. span style="color: #808080; font-style: italic;">/**
  2.  * @package MJ.Plugin
  3.  * @subpackage Content.Mjformcomment
  4.  *
  5.  * @copyright Copyright (C) 2015 Carlos Rodriguez. All rights reserved.
  6.  * @license License http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL
  7.  */'_JEXEC''view'] == 'com_content.article'"mjformcomments"'default_form''data'
<?php
/**
* @package MJ.Plugin
* @subpackage Content.Mjformcomment
*
* @copyright Copyright (C) 2015 Carlos Rodriguez. All rights reserved.
* @license License http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL
*/

defined('_JEXEC') or die;

extract($displayData);

?>

<?php if ($data['view'] == 'com_content.article') : ?>
   <div id="mjformcomments">
      <?php echo JLayoutHelper::render('default_form', compact('data'), __DIR__); ?>
   </div>
<?php endif; ?>

Nada del otro mundo ¿Verdad? Solo destacar aquí la comprobación de la línea 16, en donde revisamos si estamos dentro de la vista de un artículo, porque el formulario para comentar solo debe ir ahí y no en ningún otro lado. Si estamos en la vista de un artículo, entonces llamamos a otro layout responsable únicamente de la visualización de nuestro formulario para comentar. Creamos el archivo "default_form" dentro de la carpeta “layouts” conteniendo lo siguiente:

  1. span style="color: #808080; font-style: italic;">/**
  2.  * @package MJ.Plugin
  3.  * @subpackage Content.Mjformcomment
  4.  *
  5.  * @copyright Copyright (C) 2015 Carlos Rodriguez. All rights reserved.
  6.  * @license License http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL
  7.  */'_JEXEC''form'"row""alert alert-danger" role="alert"'PLG_CONTENT_COMMENT_FORM_ERROR'"row""comments-form" action="" method="post""form-validate" enctype="multipart/form-data""col-md-6""form-group"'form']->getLabel('visitor_name''form']->getInput('visitor_name'"col-md-6""form-group"'form']->getLabel('visitor_email''form']->getInput('visitor_email'"col-md-12""form-group"'form']->getInput('visitor_comments'"col-md-3 col-md-offset-9""form-actions">
  8. <button type="submit""btn btn-primary btn-block"
<?php
/**
* @package MJ.Plugin
* @subpackage Content.Mjformcomment
*
* @copyright Copyright (C) 2015 Carlos Rodriguez. All rights reserved.
* @license License http://www.gnu.org/licenses/gpl-3.0.html GNU/GPL
*/

defined('_JEXEC') or die;

extract($displayData);

?>

<?php if (!$data['form']) : ?>
   <div class="row">
      <div class="alert alert-danger" role="alert">
         <?php echo JText::_('PLG_CONTENT_COMMENT_FORM_ERROR'); ?>
      </div>
   </div>
<?php else : ?>
   <div class="row">
      <form id="comments-form" action="" method="post" class="form-validate" enctype="multipart/form-data">
         <div class="col-md-6">
            <div class="form-group">
               <?php echo $data['form']->getLabel('visitor_name'); ?>
               <?php echo $data['form']->getInput('visitor_name'); ?>
            </div>
         </div>
         <div class="col-md-6">
            <div class="form-group">
               <?php echo $data['form']->getLabel('visitor_email'); ?>
               <?php echo $data['form']->getInput('visitor_email'); ?>
            </div>
         </div>
         <div class="col-md-12">
            <div class="form-group">
               <?php echo $data['form']->getInput('visitor_comments'); ?>
            </div>
         </div>
         <div class="col-md-3 col-md-offset-9">
            <div class="form-actions">
               <button type="submit" class="btn btn-primary btn-block">Enviar</button>
            </div>
         </div>
      </form>
   </div>
<?php endif; ?>

Y al fin aparece la vista del formulario, ¡nuestra última tarea ha sido completada!

A resaltar aquí tenemos pocas cosas. Primero (Línea 16 -21), comprobamos que no ha ocurrido ningún error en el modelo del componente en la obtención del formulario, porque en ese caso mostramos una cadena de texto traducible a través de la clase “JText” de Joomla. Esta cadena por supuesto que hay que añadirla al archivo de idioma del plugin con su valor correspondiente.

Luego mostramos cada campo del formulario con las funciones “getLabel” y “getInput”. Como bien lo indican el nombre de cada función pertenecientes a Joomla, obtienen la estructura HTML del campo del formulario pasado como argumento. Por supuesto que el nombre de este argumento tiene que coincidir con algún nombre del archivo “formcomment.xml” de nuestro formulario.

Y ahora sí, salvamos todo y actualizamos nuestro paquete. Luego vamos a la vista de un artículo y…….. ¡¡¡¡ERROR!!!! Fatal error: Call to a member function getForm().....

¿Triste? Todo no puede ser perfecto, algo teníamos que tener ¿verdad? Resolveremos este pequeño inconveniente abriendo el archivo de entrada de nuestro plugin y editando la función, “getModel”. Lo primero que haremos es editar el prefijo de nuestro modelo, ya que ese que esta, no es el correcto o al menos está incompleto, ya que el correcto es “MjcommentsModel”. Luego añadimos dos líneas a la función. La primera es una variable con la ruta hacia la carpeta de nuestro componente en la parte pública de nuestro sitio. Y luego, adicionamos otra línea más, añadiendo esta ruta, a las rutas en donde Joomla tiene que buscar los modelos que se les solicitan, de esta forma, ve el modelo de nosotros porque sino nos excluye. Todo esto queda de esta forma:

  1. // Proxy to the component site path
  2. '/components/com_mjcomments/';
  3.  
  4. // Add the models
  5. '/models', $prefix);
// Proxy to the component site path
$com_path = JPATH_SITE . '/components/com_mjcomments/';

// Add the models
JModelLegacy::addIncludePath($com_path . '/models', $prefix);

Bien fácil la función para añadir modelos que queremos utilizar en una extensión ¿verdad? El problema era que nosotros llamábamos a nuestro modelo, pero Joomla no tenía en registrado la ruta hacia el modelo de nosotros, por lo que había que especificarle la misma.

Recuerden que utilizamos el modelo del componente porque tenemos centralizados todas nuestras consultas allá. El plugin solo lo utilizamos para la visualización del formulario.

Bueno, probemos de nuevo a ver si tenemos suerte. Actualizamos y…

¿Otra vez? Bueno al menos ya nos sale la página. Pero la mala noticia es que tenemos dos errores en uno. Uno, el formulario no cargo. Y otro, la cadena de texto traducible del error, a pesar que le asignamos un valor en el archivo de idioma del plugin, no cambió su aspecto. Empecemos por resolver el último.

Al parecer los archivos de idiomas del plugin no se están cargando. Y tiene toda la razón, porque nos ha faltado especificar una variable global dentro de la clase de nuestro plugin la cual su función es precisamente esta, cargar estos archivos en la inicialización del plugin. La variable en sí es “$autoloadLanguage” véanla en acción aquí:

  1. /**
  2.  * Load the language file on instantiation.
  3.  *
  4.  * @var boolean
  5.  */
/**
* Load the language file on instantiation.
*
* @var boolean
*/
protected $autoloadLanguage = true;

Esta variable proviene de nuestra clase padre “JPlugin” (libraries\cms\plugin\plugin.php). Bien, si volvemos a actualizar nuestro paquete, entonces:

¡Resuelto el primer problema!

El segundo problema viene relacionado a que el formulario no está siendo cargado o Joomla nos está jugando una mala pasada. Pero al igual que el anterior, Joomla no tiene la culpa. El problema radica que Joomla no encuentra una ruta hacia el formulario de nosotros ¿Porque? Pues porque el componente de nosotros no está todo lo listo que se necesita, para que funcione al 100%. Pero tranquilos que así como está, está muy bien. A medida que avancemos en el ciclo, ya veremos que este problema lo erradicamos. Por el momento, hagamos explícito la ruta hacia el formulario de nosotros. Para ello, editaremos otra vez la función “getModel” de nuestro plugin y la añadiremos una línea más en la cual le decimos a Joomla que cuando vaya a buscar formularios, que añada una ruta más en su búsqueda. Parecido a lo que hicimos anteriormente con el modelo, pero esta vez con otra función:

  1. // Add the form.
  2. '/models/forms');
// Add the form.
JForm::addFormPath($com_path . '/models/forms');

Probemos de nuevo, y recemos que todo ya este bien. Actualizamos y…

¡Epale! Todo ha ido bien, y a pesar que no tiene ningún formato nuestro formulario, es bonito ver los campos mostrandose ¿verdad?.

Recuerden que el diseño lo trabajaremos luego cuando desarrollemos la plantilla para nuestro sitio. Por el momento estamos usando la “protostart” que viene por defecto en Joomla, que a pesar que usa bootstrap, no usa la versión que nosotros queremos, ya que la que queremos es la última versión estable de este grandioso framework frontend.

Otra cosa curiosa es que las cadenas de texto traducibles están en su forma menos vistosa, a pesar que les hemos asignado un valor en el archivo de idioma del componente. Tarea para la casa.

Siempre tengan presente que el repositorio de nuestros ciclos lo podrán encontrar en GITHUB.

Pero bueno, esta charla ya tocará en otro momento. Por ahora, damos punto final a este bien extenso artículo que le da comienzo a un ciclo de desarrollo que promete mucho. Espero que lo hayan disfrutado al igual que yo. ¡Nos vemos!