Joomla: Usando JLayouts para fields
Este artículo explica cómo utilizar JLayouts para evitar ensuciar el código HTML, JS y CSS en campos (fields) complejos.
Para ilustrar el problema utilizaremos el campo del core ya existente para seleccionar usuarios:
libraries/cms/form/field/user.php
Este es el contenido de la función getInput() dentro de ese field:
/**
* Method to get the user field input markup.
*
* @return string The field input markup.
*
* @since 1.6.0
*/
protected function getInput()
{
$html = array();
$groups = $this->getGroups();
$excluded = $this->getExcluded();
$link = 'index.php?option=com_users&view=users&layout=modal&tmpl=component&field=' . $this->id
. (isset($groups) ? ('&groups=' . base64_encode(json_encode($groups))) : '')
. (isset($excluded) ? ('&excluded=' . base64_encode(json_encode($excluded))) : '');
// Initialize some field attributes.
$attr = $this->element['class'] ? ' class="' . (string) $this->element['class'] . '"' : '';
$attr .= $this->element['size'] ? ' size="' . (int) $this->element['size'] . '"' : '';
// Initialize JavaScript field attributes.
$onchange = (string) $this->element['onchange'];
// Load the modal behavior script.
JHtml::_('behavior.modal', 'a.modal_' . $this->id);
// Build the script.
$script = array();
$script[] = ' function jSelectUser_' . $this->id . '(id, title) {';
$script[] = ' var old_id = document.getElementById("' . $this->id . '_id").value;';
$script[] = ' if (old_id != id) {';
$script[] = ' document.getElementById("' . $this->id . '_id").value = id;';
$script[] = ' document.getElementById("' . $this->id . '_name").value = title;';
$script[] = ' ' . $onchange;
$script[] = ' }';
$script[] = ' SqueezeBox.close();';
$script[] = ' }';
// Add the script to the document head.
JFactory::getDocument()->addScriptDeclaration(implode("\n", $script));
// Load the current username if available.
$table = JTable::getInstance('user');
if ($this->value)
{
$table->load($this->value);
}
else
{
$table->username = JText::_('JLIB_FORM_SELECT_USER');
}
// Create a dummy text field with the user name.
$html[] = '';
$html[] = ' ';
// Create the user select button.
if ($this->element['readonly'] != 'true')
{
$html[] = ' ';
$html[] = '';
}
$html[] = '';
// Create the real field, hidden, that stored the user id.
$html[] = '';
return implode("\n", $html);
}
Como podrás observar, hay algo de código HTML y JS embedido y desordenado con el PHP. La primera razón para evitarlo o reemplazarlo es por cuestiones de legibilidad. Además imagina que tienes una plantilla que no utiliza resaltado Bootstrap como Hathor o quieres cargar un modal diferente que no usa Mootools.
Puede JLayouts ayudarnos en esta tarea? Si. De hecho es probablemente la mejor solución. Manos a la obra.
Primero moveremos casi todo el código al layout. Nuestra nueva función getInput() quedará así:
/**
* Method to get the user field input markup.
*
* @return string The field input markup.
*
* @since 1.6.0
*/
protected function getInput()
{
$this->groups = $this->getGroups();
$this->excluded = $this->getExcluded();
return JLayoutHelper::render("libraries.cms.forms.fields.user", $this);
}
Solo lo básico para obtener la información requerida y pasarsela al layout. Ahora tenemos que crear el layout. Probablemente has notado por la llamada a la función render que vamos a crearla en:
layouts/libraries/cms/forms/fields/user.php
El contenido del archivo es el siguiente:
id
. (isset($data->groups) ? ('&groups=' . base64_encode(json_encode($data->groups))) : '')
. (isset($data->excluded) ? ('&excluded=' . base64_encode(json_encode($data->excluded))) : '');
// Initialize some field attributes.
$attr = $data->element['class'] ? ' class="' . (string) $data->element['class'] . '"' : '';
$attr .= $data->element['size'] ? ' size="' . (int) $data->element['size'] . '"' : '';
// Initialize JavaScript field attributes.
$onchange = (string) $data->element['onchange'];
// Load the modal behavior script.
JHtml::_('behavior.modal', 'a.modal_' . $data->id);
// Build the script.
$script = "
function jSelectUser_" . $data->id . "(id, title) {
var old_id = document.getElementById('" . $data->id . "_id').value;
if (old_id != id) {
document.getElementById('" . $data->id . "_id').value = id;
document.getElementById('" . $data->id . "_name').value = title;
" . $onchange . "
}
SqueezeBox.close();
}
";
// Add the script to the document head.
JFactory::getDocument()->addScriptDeclaration($script);
// Load the current username if available.
$table = JTable::getInstance('user');
if ($data->value)
{
$table->load($data->value);
}
else
{
$table->username = JText::_('JLIB_FORM_SELECT_USER');
}
?>
Ahora el código HTML está separado del PHP. También los usuarios pueden sobresribirla facilmente creando un fichero en la plantilla activa como:
templates/TEMPLATE_NAME/html/layouts/libraries/cms/forms/fields/user.php
Todo puede cambiarse dentro de la plantilla excepto la información de entrada..