Manuales Joomla

Sistema de comentarios - Tutorial 1, Formulario para comentar

(Lo puedes leer en: 20 - 39 minutos)

por .

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.

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:

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>Esta dirección de correo electrónico está siendo protegida contra los robots de spam. Necesita tener JavaScript habilitado para poder verlo.</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>
Source code

Archivo de maniesto "pkg_mjcommentsystem.xml"

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."
Source code

Archivo de idioma “es-ES.pkg_mjcommentsystem.sys.ini”

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>Esta dirección de correo electrónico está siendo protegida contra los robots de spam. Necesita tener JavaScript habilitado para poder verlo.</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>
Source code

Archivo de manifiesto “com_mjcomments.xml”

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.

Gestor de extensiones

Gestor de extensiones

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:

Esquema del tráfico entre extensiones

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>
Source code

Gestión de base datos del componente

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`
Source code

Archivo install.sql

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`;
Source code

Archivo de desintalación de la tabla en la base de datos

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
Source code

Archivo de actualización para el componente en la base de datos

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:

Añadiendo carpeta SQL al manifiesto

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>
Source code

XML del formulario para comentar

XML del formulario para comentar

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."
Source code

Archivo de idioma del componente

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'
Source code

Modelo para obtener el formulario para comentar

Modelo para obtener el formulario de comentar

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>
Source code

Añadir carpetas "language" y "models" al manifiesto del componente

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>
Source code

Añadiendo entrada al plugin en el manifiesto del paquete

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.  
Source code

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>Esta dirección de correo electrónico está siendo protegida contra los robots de spam. Necesita tener JavaScript habilitado para poder verlo.</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>
Source code

Archivo manifiesto del pluginArchivo manifiesto del plugin

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.

Gestor de plugin

Parámetros del plugin MJFORMCOMMENT

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."
Source code

Cadenas de idiomas del plugin MJFORMCOMMENT

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."
Source code

Cadenas de idioma del plugin MJFORMCOMMENT

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>
Source code

Actualización en el manifiesto del plugin

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'
Source code

Archivo de entrada del plugin
Archivo de entrada del plugin
Archivo de entrada del plugin
Archivo de entrada del plugin

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'
Source code

Layout del plugin

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"
Source code

Layout para el formulario

Layout para el formulario

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);
Source code

Solución al problema del modelo

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…

Error en salida del formulario

¿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.  */
Source code

Inclusión del archivo de idioma del plugin

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

Inclusión con éxito del archivo de idioma del plugin

¡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');
Source code

Inclusión del formulario

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

Salida con éxito del formulario

¡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!

Etiquetas: Desarrollo, Extensiones, Ciclo de desarrollo, Comentarios, Programación

Imprimir