En este tutorial vas a aprender a crear el backend básico de un componente de Joomla 1.6 programando directamente con el Framework de Joomla 1.6 y el lenguaje de programación PHP. Es un ejemplo sencillo para desarrollar el clásico programa "Hola Mundo".
Backend básico
Lo primero que haremos será definir el punto de entrada del componente.
Para ello cree un archivo administrator / components / com_hello / helloworld.php que contiene:
administrator / components / com_hello / helloworld.php
{codecitation}
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
// import joomla controller library
jimport('joomla.application.component.controller');
// Get an instance of the controller prefixed by HelloWorld
$controller = JController::getInstance('HelloWorld');
// Perform the Request task
$controller->execute(JRequest::getCmd('task'));
// Redirect if set by the controller
$controller->redirect();
?>
{/codecitation}
Crear el controlador general
El punto de entrada creará una instancia del controlador que hemos definido en la classe HelloWorld. Entoces creamos un controlador básico y para ello creamos el archivo administrator / components / com_hello / controller.php que contiene:
administrator / components / com_hello / controller.php
{codecitation}
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
// import Joomla controller library
jimport('joomla.application.component.controller');
/**
* General Controller of HelloWorld component
*/
class HelloWorldController extends JController{
/*
*
* display task
*
* @return void */
function display($cachable = false) {
// set default view if not set
JRequest::setVar('view', JRequest::getCmd('view', 'HelloWorlds'));
// call parent behavior
parent::display($cachable);
}
}
{/codecitation}
Este controlador mostrará la vista HelloWorlds por defecto
Crear la vista
Creamos el archivo administrator / components / com_hello / views / helloworlds / view.html.php que contiene:
administrator / components / com_hello / views / helloworlds / view.html.php
{codecitation}
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
// import Joomla view library
jimport('joomla.application.component.view');
/**
* HelloWorlds View
*/
class HelloWorldViewHelloWorlds extends JView{
/*
*
* HelloWorlds view display method
* @return void */
function display($tpl = null) {
// Get data from the model
$items = $this->get('Items');
$pagination = $this->get('Pagination');
// Check for errors.
if (count($errors = $this->get('Errors'))) {
JError::raiseError(500, implode('<br />', $errors));
return false;
}
// Assign data to the view
$this->items = $items;
$this->pagination = $pagination;
// Display the template
parent::display($tpl);
}
}
{/codecitation}
En Joomla, las vistas se muestran usando layouts. Creamos el archivo administrator / components / helloworlds / tmpl / default.php que contiene:
administrator / components / helloworlds / tmpl / default.php
{codecitation}
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted Access');
// load tooltip behavior
JHtml::_('behavior.tooltip');
?>
<form action="<?php echo JRoute::_('index.php?option=com_helloworld'); ?>" method="post" name="adminForm">
<table class="adminlist">
<thead><?php echo $this->loadTemplate('head');?></thead>
<tfoot><?php echo $this->loadTemplate('foot');?></tfoot>
<tbody><?php echo $this->loadTemplate('body');?></tbody>
</table>
</form>
{/codecitation}
Este layout llamará a distintos sub-layouts (head, foot y body). Estos sub-layouts los definiremos con el nombre de default_ seguido del nombre del sub-layout.
Creamos el archivo administrator / components / com_hello / helloworlds / tmpl / default_head.php que contiene:
administrator / components / com_hello / helloworlds / tmpl / default_head.php
{codecitation}
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted Access');
?>
<tr>
<th width="5">
<?php echo JText::_('COM_HELLOWORLD_HELLOWORLD_HEADING_ID'); ?>
</th>
<th width="20">
<input type="checkbox" name="toggle" value="" onclick="checkAll(<?php echo count($this->items); ?>);" />
</th>
<th>
<?php echo JText::_('COM_HELLOWORLD_HELLOWORLD_HEADING_GREETING'); ?>
</th>
</tr>
{/codecitation}
checkAll es una función de javascript definida en el core de Joomla que marcará todos los checkboxes con un sólo click.
Creamos un archivo asministrator / components / com_hello / helloworlds / tmpl / default_body.php que contiene:
asministrator / components / com_hello / helloworlds / tmpl / default_body.php
{codecitation}
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted Access');
?>
<?php foreach($this->items as $i => $item): ?>
<tr class="row<?php echo $i % 2; ?>">
<td> <?php echo $item->id; ?> </td>
<td> <?php echo JHtml::_('grid.id', $i, $item->id); ?> </td>
<td> <?php echo $item->greeting; ?> </td>
</tr>
<?php endforeach; ?>
{/codecitation}
JHtml::_ es una función helper que mostrará el HTML. En este caso mostrará un checkbox por cada elemento.
Creamos un archivo asministrator / components / com_hello / helloworlds / tmpl / default_foot.php que contiene:
asministrator / components / com_hello / helloworlds / tmpl / default_foot.php
{codecitation}
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted Access');
?>
<tr>
<td colspan="3">
<?php echo $this->pagination->getListFooter(); ?>
</td>
</tr>
{/codecitation}
JPagination es una clase de Joomla para generar el objeto paginador con el que podremos navegar por las diferentes páginas del listado.
Crear el modelo
Como hemos visto en la clase anterior, la vista hace una llamada al modelo para recoger los datos. En Joomla! 1.6 hay una clase para gestionar la información de la base de datos: JModelList. Esta clase tiene un metodo llamado getListQuery, que nos devolvera un listado de objetos, es decir, un listado con la información que en la vista hemos pedido.
Además tiene varios estados:
-
list.start: para determinar el desplazamiento de la lista.
-
list.limit: para determinar la medida de la lista, es decir, el número de elementos de la lista.
Los métodos getItems y getPagination están definidos en la clase JModelList.
{} administrator / components / com_hello / models / helloworlds.php {}
{codecitation}
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
// import the Joomla modellist library
jimport('joomla.application.component.modellist');
/*
*
* HelloWorldList Model
*/
class HelloWorldModelHelloWorlds extends JModelList{
/*
*
* Method to build an SQL query to load the list data.
*
* @return string An SQL query */
protected function getListQuery() {
// Create a new query object.
$db = JFactory::getDBO();
$query = $db->getQuery(true);
// Select some fields
$query->select('id,greeting');
// From the hello table
$query->from('#__helloworld');
return $query;
}
}
{/codecitation}
Añadir la barra de herramientas
En Joomla 1.6!, el administrador interacciona con los componentes utilizando la barra de herramientas. En el archivo administrator / components / com_hello / views / helloworlds / view.html.php añadimos este contenido. Esto añadira una barra de herramientas básica y el título del componente.
{codecitation}
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
// import Joomla view library
jimport('joomla.application.component.view');
/**
* HelloWorlds View
*/
class HelloWorldViewHelloWorlds extends JView{
/**
* HelloWorlds view display method
* @return void
*/
function display($tpl = null) {
// Get data from the model
$items = $this->get('Items');
$pagination = $this->get('Pagination');
// Check for errors.
if (count($errors = $this->get('Errors'))) {
JError::raiseError(500, implode('<br />', $errors));
return false;
}
// Assign data to the view
$this->items = $items;
$this->pagination = $pagination;
// Set the toolbar
$this->addToolBar();
// Display the template
parent::display($tpl);
}
/*
*
* Setting the toolbar
*/
protected function addToolBar() { JToolBarHelper::title(JText::_('COM_HELLOWORLD_MANAGER_HELLOWORLDS')); JToolBarHelper::deleteListX('', 'helloworlds.delete');
JToolBarHelper::editListX('helloworld.edit');
JToolBarHelper::addNewX('helloworld.add');
}
}
{/codecitation}
Podrás encontrar las diferentes acciones del backend en el archivo administrator / includes / toolbar.php en tu instalación de Joomla! 1.6
Añadimos también las líneas siguientes en administrator / componentes / com_hello / views / helloworlds / tmpl / default.php
administrator / components / com_hello / views / helloworlds / tmpl / default.php
{codecitation}
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted Access');
// load tooltip behavior
JHtml::_('behavior.tooltip');
?>
<form action="<?php echo JRoute::_('index.php?option=com_helloworld'); ?>" method="post" name="adminForm">
<table class="adminlist">
<thead><?php echo $this->loadTemplate('head');?></thead>
<tfoot><?php echo $this->loadTemplate('foot');?></tfoot>
<tbody><?php echo $this->loadTemplate('body');?></tbody>
</table>
<div>
<input type="hidden" name="task" value="" />
<input type="hidden" name="boxchecked" value="0" />
<?php echo JHtml::_('form.token'); ?>
</div>
</form>
{/codecitation}
Añadir los controladores específicos
Añadiremos tres acciones.
- Borrar un elemento
- Editar un elemento
- Añadir un elemento
Para ello crearemos tareas en el controlador específico para después poder llamarlas de la manera controller.tarea
Crearemos dos nuevos controladores en _administrator / components / com_hello / controllers /
administrator / components / com_hello / controllers / helloworlds.php
{codecitation}
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
// import Joomla controlleradmin library
jimport('joomla.application.component.controlleradmin');
/*
*
* HelloWorlds Controller
*/
class HelloWorldControllerHelloWorlds extends JControllerAdmin{
/*
*
* Proxy for getModel.
* @since 1.6
*/
public function getModel($name = 'HelloWorld', $prefix = 'HelloWorldModel') {
$model = parent::getModel($name, $prefix, array('ignore_request' => true));
return $model;
}
}
{/codecitation}
administrator / components / com_hello / controllers / helloworld.php
{codecitation}
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
// import Joomla controllerform library
jimport('joomla.application.component.controllerform');
/**
* HelloWorld Controller
*/
class HelloWorldControllerHelloWorld extends JControllerForm
{
}
{/codecitation}
Creamos la vista para editar los elementos
Creamos un archivo en administrator / components / com_hello / views / helloworld / view.html.php
administrator / components / com_hello / views / helloworld / view.html.php
{codecitation}
<php
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
// import Joomla view library
jimport('joomla.application.component.view');
/**
* HelloWorld View
*/
class HelloWorldViewHelloWorld extends JView
{
/**
* display method of Hello view
* @return void
*/
public function display($tpl = null)
{
// get the Data
$form = $this->get('Form');
$item = $this->get('Item');
// Check for errors.
if (count($errors = $this->get('Errors')))
{
JError::raiseError(500, implode('
', $errors));
return false;
}
// Assign the Data
$this->form = $form;
$this->item = $item;
// Set the toolbar
$this->addToolBar();
// Display the template
parent::display($tpl);
}
/**
* Setting the toolbar
*/
protected function addToolBar()
{
JRequest::setVar('hidemainmenu', true);
$isNew = ($this->item->id == 0);
JToolBarHelper::title($isNew ? JText::_('COM_HELLOWORLD_MANAGER_HELLOWORLD_NEW') : JText::_('COM_HELLOWORLD_MANAGER_HELLOWORLD_EDIT'));
JToolBarHelper::save('helloworld.save');
JToolBarHelper::cancel('helloworld.cancel', $isNew ? 'JTOOLBAR_CANCEL' : 'JTOOLBAR_CLOSE');
}
}
Esta vista mostrará el layaut por defecto en caso que no le digamos lo contrario, por lo tanto, crearemos un archivo en administrator / components / com_hello / views / helloworld / tmpl / edit.php
administrator / components / com_hello / views / helloworld / tmpl / edit.php
<?php
// No direct access
defined('_JEXEC') or die('Restricted access');
JHtml::_('behavior.tooltip');
?>
<form action="<?php echo JRoute::_('index.php?option=com_helloworld&layout=edit&id='.(int) $this->item->id); ?>" method="post" name="adminForm" id="helloworld-form">
<fieldset class="adminform">
<legend><?php echo JText::_( 'COM_HELLOWORLD_HELLOWORLD_DETAILS' ); ?></legend>
<ul class="adminformlist">
<?php foreach($this->form->getFieldset() as $field): ?>
<li><?php echo $field->label;echo $field->input;?></li>
<?php endforeach; ?>
</ul>
</fieldset>
<div>
<input type="hidden" name="task" value="helloworld.edit" />
<?php echo JHtml::_('form.token'); ?>
</div>
</form>
{/codecitation}
Añadimos el modelo que obtendrá el elemento
Creamos un archivo en administrator / ccomponents / com_hello / models / helloworld.php
administrator / ccomponents / com_hello / models / helloworld.php
{codecitation}
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
// import Joomla modelform library
jimport('joomla.application.component.modeladmin');
/**
* HelloWorld Model
*/
class HelloWorldModelHelloWorld extends JModelAdmin
{
/**
* Returns a reference to the a Table object, always creating it.
*
* @param type The table type to instantiate
* @param string A prefix for the table class name. Optional.
* @param array Configuration array for model. Optional.
* @return JTable A database object
* @since 1.6
*/
public function getTable($type = 'HelloWorld', $prefix = 'HelloWorldTable', $config = array())
{
return JTable::getInstance($type, $prefix, $config);
}
/**
* Method to get the record form.
*
* @param array $data Data for the form.
* @param boolean $loadData True if the form is to load its own data (default case), false if not.
* @return mixed A JForm object on success, false on failure
* @since 1.6
*/
public function getForm($data = array(), $loadData = true)
{
// Get the form.
$form = $this->loadForm('com_helloworld.helloworld', 'helloworld', array('control' => 'jform', 'load_data' => $loadData));
if (empty($form))
{
return false;
}
return $form;
}
/**
* Method to get the data that should be injected in the form.
*
* @return mixed The data for the form.
* @since 1.6
*/
protected function loadFormData()
{
// Check the session for previously entered form data.
$data = JFactory::getApplication()->getUserState('com_helloworld.edit.helloworld.data', array());
if (empty($data))
{
$data = $this->getItem();
}
return $data;
}
}
{/codecitation}
Además tendremos que crear un archivo XML que nos permitira definir los diferentes campos del formulario. Esto lo a incorporado el nuevo Joomla! 1.6.
Creamos un archivo en administrator / components / com_hello / models / form / helloworld.xml
administrator / components / com_hello / models / form / helloworld.xml
{codecitation}
<?xml version="1.0" encoding="utf-8"?>
<form>
<fieldset>
<field
name="id"
type="hidden"
/>
<field
name="greeting"
type="text"
label="COM_HELLOWORLD_HELLOWORLD_GREETING_LABEL" description="COM_HELLOWORLD_HELLOWORLD_GREETING_DESC"
size="40"
class="inputbox"
default=""
/>
</fieldset>
</form>
{/codecitation}
Además en cada carpeta del componente se suele introducir un archivo index.html vació que se utiliza para evitar que el servidor web pueda listar los archivos del directorio. Por lo que la estructura final del componente sería la siguiente:
Estructura final del componente
• administrator/components/com_hello/index.html
• administrator/components/com_hello/helloworld.php
• administrator/components/com_hello/controller.php
• administrator/components/com_hello/models/index.html
• administrator/components/com_hello/models/forms/index.html
• administrator/components/com_hello/models/forms/helloworld.xml
• administrator/components/com_hello/models/helloworld.php
• administrator/components/com_hello/models/helloworlds.php
• administrator/components/com_hello/views/index.html
• administrator/components/com_hello/views/helloworlds/index.html
• administrator/components/com_hello/views/helloworlds/view.html.php
• administrator/components/com_hello/views/helloworlds/tmpl/index.html
• administrator/components/com_hello/views/helloworlds/tmpl/default.php
• administrator/components/com_hello/views/helloworlds/tmpl/default_head.php
• administrator/components/com_hello/views/helloworlds/tmpl/default_body.php
• administrator/components/com_hello/views/helloworlds/tmpl/default_foot.php
• administrator/components/com_hello/views/helloworld/index.html
• administrator/components/com_hello/views/helloworld/view.html.php
• administrator/components/com_hello/views/helloworld/tmpl/index.html
• administrator/components/com_hello/views/helloworld/tmpl/edit.php
• administrator/components/com_hello/tables/index.html
• administrator/components/com_hello/tables/helloworld.php
• administrator/components/com_hello/controllers/index.html
• administrator/components/com_hello/controllers/helloworld.php
• administrator/components/com_hello/controllers/helloworlds.php
En éste enlace puedes descargar una versión más compleja de este componente que cuanta con la parte de backend y de frontend.
Sobre el autor
Jordi Vila es Ingeniero Técnico en Informática de Gestión. Forma parte del equipo de Web Actualizable (www.webactualizable.com), empresa especializada en el desarrollo de proyectos sobre Joomla.