Hola a todos.
Como otros muchos soy nuevo con J! 1.5 y teniendo que desarrollar un componente me encontré con el problema de que la documentación existente explicaba el modelo MVC a base de ejemplos en los que se mostraban los ficheros necesarios para pintar la famosa frasecilla 'Hola Mundo!'. Sin embargo ninguno de los documentos que encontré explicaba cómo funciona por dentro J! por lo que en cuanto me salía un poco de los ejemplos empezaba a tener problemas.
Al final me las arreglé para aprender por qué J! hace lo que hace y aprovecho este foro para ofrecerlo a quien esté en la misma situación. Este mini tutorial no pretende explicar exhaustivamente como se construye un componente completo con instalador y todo (de eso ya hay muchos tutoriales), sino contar las cosas que el entorno (framework) de J! espera encontrar en su camino hacia la presentación de una página dada.
Se entra en el entorno de J! efectuando llamadas a index.php. Joomla! ha sido diseñado principalmente para entregar los datos devueltos por los componentes. Cuando introducimos una URL como index.php?option=com_<nombre> Joomla! busca la carpeta 'components/com_<nombre>' e intenta cargar el fichero 'nombre.php' de dondequiera que se haya instalado Joomla!. Así que, si tu componente es 'com_viajes' debieras tener una carpeta 'com_viajes' dentro del directorio 'components' y un fichero llamado 'viajes.php' en su interior. Voy a llamar a este fichero (viajes.php) el 'fichero base' y, será en el en donde tendremos que realizar nuestra primera decisión acerca de si devolver el contenido HTML deseado según el viejo modelo plano o ir hacia el nuevo modelo 'Model-View-Controller' o MVC.
El modelo MVC se apoya sobre dos patas: un fichero y una clase. El entorno de Joomla! usualmente buscará un fichero determinado y, dentro de el, esperará encontrar una clase que registrar. Si alguno de los dos falta la llamada fallará.
Ponemos en marcha el modelo MVC incluyendo el controlador en nuestro fichero base. El fichero del controlador puede llamarse como deseemos pero, por convenio, parece que suele llamarse 'controller.php'. Así que en nuestro fichero base (viajes.php), escribiríamos algo como esto:
Code:
require_once(JPATH_COMPONENT.DS.'controller.php');
Ahora, para ser coherente, hemos de crear un nuevo fichero y llamarlo 'controller.php'. Este fichero puede ser creado donde deseemos ya que lo vamos a incluir por ruta en el fichero base pero, si has usado la línea propuesta anteriormente debe ser creado en la misma carpeta donde se encuentra el fichero base ya que JPATH_COMPONENT contiene la ruta donde se encuentra nuestro componente y DS representa el separador de directorios correcto según el sistema operativo bajo el que se está ejecutando el código, sea este windows o linux.
Así que creamos 'controller.php' y realizamos una referencia dentro de éste a la librería del controlador importándola con:
Code:
jimport('joomla.application.component.controller');
Ya tenemos la primera pata (el fichero) por lo que ahora necesitamos la otra, la clase. Para ello tenemos que definir una clase que extienda la funcionalidad de la clase base del controlador 'JController'. En esta clase es en donde toda la acción va a transcurrir. Puedes llamar a la clase derivada como quieras pero parece ser que por acuerdo el nombre se deriva del nombre del componente así que nuestra clase será:
Code:
class ViajesController extends JController
{
}
En esta etapa ya tenemos nuestros dos primeros ficheros. El fichero base carga el controlador y el fichero del controlador define una clase que extiende la clase base. Hasta aquí fácil. Nuestro siguiente paso será crear un objeto de de esta clase y ponerlo a currar. Así que añadimos las siguientes líneas a nuestro fichero base:
Code:
// Incluir el fichero del controlador
require_once(JPATH_COMPONENT.DS.'controller.php'); // Esta ya estaba
// Crear el controlador
$controller = new ViajesController(); o el nombre que le hayas dado a tu clase de controlador
// realizar la tarea solicitada
$controller->execute(JRequest::getCmd('task'));
A partir de ahora las cosas empiezan a ocurrir solitas. Hasta hora podíamos dar a nuestros ficheros (exceptuando el fichero base) el nombre que queríamos, podíamos ponerlos donde nos diera la gana y podíamos dar a nuestras clases el nombre que quisiéramos porque estábamos incluyendo los ficheros por ruta y estábamos llamando a las clases directamente (bueno, realmente sólo un fichero y sólo una clase pero teníamos la posibilidad de hacerlo). Pero a partir de ahora será el entorno de Joomla! el que empiece a cargar nuestros ficheros y a llamar a nuestras clases automáticamente por lo que debemos ser sumamente cuidadosos acerca de dónde ponemos nuestros archivos, cómo los llamamos y qué clases contienen porque una simple letra de diferencia y Joomla! fallará.
De dónde saca el entorno de Joomla! los datos para funcionar?. Bueno, la respuesta es sencilla: de la petición de página sea ésta una petición tipo GET o una petición tipo POST. Pero, yo no he escrito en mi petición nada más que option=com_viajes. De dónde viene el parámetro 'task' que pasamos en la llamada al controlador?. Realmente tenemos una variable 'task' con un valor correcto?
Si, y este el 'problema': Tanto si realizas como si no realizas una petición completa el entorno de Joomla! usará sus valores por defecto para completar la llamada haciendo el sistema muy cómodo pero también muy complejo de reparar si nos equivocamos en determinados sitios.
La llamada 'controller->execute()' hará que el entorno de Joomla! intente realizar el trabajo solicitado que, en este caso, será la tarea por defecto 'display', simplemente porque no le hemos indicado ninguna otra.
Code:
class ViajesController extends JController
{
function display()
{
echo 'Viajando';
}
}
De tal modo que si nuestra petición hubiese contenido el parámetro 'task=saltar' el controlador hubiese intentado ejecutar una función llamada saltar en nuestra clase controladora:
Code:
class ViajesController extends JController
{
function saltar()
{
echo 'saltando';
}
}
Si has sido observador el nombre de nuestro componente ha sido 'capitalizado' al usarlo como nombre de la clase derivada. Esta es una constante en el entorno y, aunque aquí hubiésemos podido poner otra cosa en esta primera clase no será así en las demás por lo que conviene acostumbrarse lo antes posible para evitar tirones de pelo.
Por el momento hemos jugado con la parte 'Controller' del modelo MVC. Llegamos aquí a un nuevo punto de decisión. Podemos parar aquí o seguir adelante y entrar en la parte 'View' del modelo.
Como se puede ver el modelo MVC puede ser usado por partes según lo que nos interese algo que no he visto que nadie diga en ningún sitio. Parar aquí, al menos, simplifica nuestro fichero base. Hasta ahora teníamos normalmente una sentencia switch que, según la tarea solicitada por una variable dada llamaba a una función escrita más abajo en ese mismo fichero y le pasaba varios argumentos. Esa función era la que devolvía el código HTML deseado.
Ahora el switch ha desaparecido y las diferentes tareas a realizar son funciones en nuestro fichero 'controller.php '. La capacidad de pasar argumentos ha desaparecido pero todas las variables necesarias están disponibles en el entorno así que las podemos recuperar fácilmente.
No hay nada que nos obligue a usar la variable 'task' para controlar el flujo de ejecución ya que podríamos parar cualquier otra variable en la llamada pero para ajustarnos a reglas no escritas (o no encontradas por mi) se suele usar 'task' ya que, además, el entorno la trata de manera especial porque es la escogida por los desarrolladores para realizar este trabajo, así que es buena idea usarla también nosotros.
Para disparar las vistas sólo tenemos que llamar a la función display() de la clase base JController. Hacemos esto insertanto en nuestra función una llamada a parent::display() como última línea. Así, como mínimo, nuestro fichero controller debiera contener lo siguiente:
Code:
jimport('joomla.application.component.controller');
class ViajesController extends JController
{
function display()
{
parent::display();
}
}
Pero, qué es una vista? Una vista es un subconjunto de datos. Es el mismo concepto de vista del lenguaje SQL. Presentamos diferentes partes de nuestros datos con diferentes vistas. Así que podemos tener una vista detallada y una vista resumida, esta última presentando un subconjunto de datos de los presentados en la primera.
Como podemos tener diferentes vistas en nuestro componente, Joomla! usa la carpeta 'views' dentro del directorio base del componente para mantener las cosas ordenadas. Esta carpeta es sólo un almacén para tus vistas.
Dentro de la carpeta 'views' tendrás que tener una carpeta por cada vista que desees. Qué hace el entorno de Joomla! con todo esto?. Pues intentar leer un fichero llamado 'view.html.php' que debiera existir en la carpeta de tu vista. Un poco lioso? A ver si me explico...
Cuando realizamos nuestra petición de página incluimos un parámetro llamado, adivinas?... Si, 'view' que contenía la vista dentro del modelo MVC que deseábamos obtener. O que debiste incluir ya que lo que se que no existe es algo así como una vista por defecto. Así que nuestro URL era algo como:
Code:
http://mi.sitio.com/index.php?option=com_viajes&view=<mivista>[&task=<mitarea>]
La parte correspondiente a la tarea puede obviarse. Recuerda que si no la incluimos la tarea por defecto es display. Con esta URL Joomla! va a buscar e importar un fichero localizado en la carpeta <raíz del sitio>/components/com_viajes/views/<mivista>/view.html.php. Si este fichero o la ruta no existen entonces Joomla! generará un error. Por el simple mecanismo de cambiar el nombre de la vista asociada a la variable 'view' podemos acceder a diferentes vistas casi sin esfuerzo. Genial, eh?
Cada petición de vista requiere también que especifiquemos el formato en el que vamos a servir los datos de la misma. Existen varios formatos bien conocidos como html (el formato por defecto si no especificamos ninguno), feed(rss), raw, etc, pero podemos usar formatos propios. Si no se especifica el formato en la URL mediante el parámetro 'format=<miformat>'el valor por defecto de 'html' es usado.
El formato 'html' hace que el entorno de Joomla! envuelva nuestra respuesta en la plantilla asignada a la página de tal forma que obtenemos una página HTML completa. De esta forma, con muy podo esfuerzo por nuestra parte, obtenemos como respuesta una página completamente cargada con la salida de los módulos y todo lo que hayamos configurado en ella además de nuestros datos en el centro de la misma como contenido.
El formato específico que estamos usando es lo que hemos puesto en el centro del nombre del archivo de la vista que hemos colocado en nuestra carpeta de vista (el fichero 'view.html.php'). Si usamos un formato diferente como 'raw' nuestro fichero debiera llamarse igualmente 'view.raw.php'.
Hay bastante más que decir sobre este tema pero para este primer post voy a dejarlo aquí que ya parece suficientes información.
Será la respuesta y el interés de los posibles lectores el que establecerá si hay segundas partes o este intento se queda en un simple experimento.
Un saludo a todos.