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[] = '<div class="input-append">'; $html[] = ' <input class="input-medium" type="text" id="' . $this->id . '_name" value="' . htmlspecialchars($table->name, ENT_COMPAT, 'UTF-8') . '"' . ' disabled="disabled"' . $attr . ' />'; // Create the user select button. if ($this->element['readonly'] != 'true') { $html[] = ' <a class="btn btn-primary modal_' . $this->id . '" title="' . JText::_('JLIB_FORM_CHANGE_USER') . '" href="' . $link . '"' . ' rel="{handler: \'iframe\', size: {x: 800, y: 500}}">'; $html[] = '<i class="icon-user"></i></a>'; } $html[] = '</div>'; // Create the real field, hidden, that stored the user id. $html[] = '<input type="hidden" id="' . $this->id . '_id" name="' . $this->name . '" value="' . (int) $this->value . '" />'; 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:
<?php /** * @package Joomla.Site * @subpackage Layout * * @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('JPATH_BASE') or die; $data = $displayData; $html = array(); $link = 'index.php?option=com_users&view=users&layout=modal&tmpl=component&field=' . $data->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'); } ?> <?php // Create a dummy text field with the user name. ?> <div class="input-append"> <input class="input-medium" type="text" id="<?php echo $data->id; ?>_name" value="<?php echo htmlspecialchars($table->name, ENT_COMPAT, 'UTF-8'); ?>" disabled="disabled" <?php echo $attr; ?> /> <?php // Create the user select button. if ($data->element['readonly'] != 'true') : ?> <a class="btn btn-primary modal_<?php echo $data->id; ?>" title="<?php echo JText::_('JLIB_FORM_CHANGE_USER'); ?>" href="/<?php echo $link; ?>" rel="{handler: 'iframe', size: {x: 800, y: 500}}"> <i class="icon-user"></i> </a> <?php endif; ?> </div> <?php // Create the real field, hidden, that stored the user id. ?> <input type="hidden" id="<?php echo $data->id; ?>_id" name="<?php echo $data->name; ?>" value="<?php echo (int) $data->value; ?>" />
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..