Escrito por

Roberto Segura

Categoría:

Blog

23 Octubre 2013

Índice

  1. Breve historia
  2. Beneficios de usar layouts
    1. Reusabilidad
    2. Separar diseño y código
    3. Fácil integración con 2.5.x
  3. Anterior sistema de layouts
  4. Nuevos requisitos
  5. Nuevas características
    1. Override de layouts en componentes
    2. Forzar componente
    3. Forzar cliente
    4. Añadiendo include paths
    5. Sufijos
    6. Sublayouts
    7. Modo debug
  6. ¿Dónde no usar layouts?
  7. Otros usos
  8. Conclusión

1. Breve historia

Usemos un ejemplo: en Joomla! tenemos artículos que tienen tags, contactos que tienen tags categorías que tienen tags...

En el sistema de plantillas previo a JLayouts (lo que seguimos usando para las vistas) mostrar los tags requeriría copiar y pegar el mismo código HTML en tantos sitios como componentes tengamos que usan tags. Pero eso no es tan difícil ¿no? No. Pero un día aparece un bug, alguien lo arregla para los artículos pero olvida hacerlo para categorías. Alguien introduce una mejora pero sólo para contactos ..... Los problemas empiezan y el sistema se hace más difícil de mantener.

Yannick Gaultier contribuyó JLayouts para solucionar este problem. Un sistema genial detrás del simple concepto de trozos de código reutilizables que permiten create HTML a partir de objetos/arrays de datos.

2. Beneficios de usar layouts

Gracias al sistema de JLayout podemos renderizar los tags de un item con:

echo JLayoutHelper::render('joomla.content.tags', $itemTags);

Eso incluiría el archivo /layouts/joomla/content/tags.php pasando $itemTags como parámetro para uso interno. Lo que usamos en los módulos pero de una forma más global. El único requisito es que $itemTags tenga la misma estructura para todos los items.

¿Qué beneficios tiene esto?

2.1. Reusabilidad

Los programadores sólo tienen que que mantener un layout. Los diseñadores sólo tienen que personalizar un layout.

2.2. Separar diseño y código

Otro de los grandes beneficions de JLayouts es pasar a ser otra herramienta para que separar el código HTML del código PHP. En un mundo ideal el 100% del código de una página debería ser overridable por un diseñador/desarrollador sin tocar el núcleo de Joomla! Eso implica que si cargas un archivo Javascript deberías hacerlo en un lugar en el que un diseñador pueda personalizarlo si decide no usar to javascript o reemplazarlo por otra librería.

Este es en la actualidad uno de los problemas más importantes que hay en Joomla! y la razón por la qu ela mayoría de los diseñadores corren asustados tras intentar colaborar durante algún tiempo.

2.3. Fácil integración con 2.5.x

Todo el sistema de layouts son 4 archivos. Puedes incluirlos en tu librería para 2.5 o extenderlos con tus propias clases.

3. Anterior sistema de layouts

Con el anterior sistema de JLayout una lamada como esta:

$layout = new JLayoutFile('joomla.content.tags');

$layout->render($itemTags);

Buscaría un layout en:

    [0] => templates/mytemplate/html/layouts

[1] => layouts

Genial! Eso significa que puedo crear mi propia versión dentro de mi plantilla. Además puedes forzar la búsqueda de layouts a una determinada carpeta:

$layout = new JLayoutFile('joomla.content.tags', JPATH_SITE . '/components/com_mycomponent/layouts');

$layout->render($itemTags);

Eso buscaría layouts en:

    [0] => templates/mytemplate/html/layouts
    
[1] => components/com_mycomponent/layouts

Genial porque es aún personalizable.

4. Nuevos requisitos

Con el anterior sistema aún tenemos algunos problemas:

  • Si los desarrolladores quieren tener layouts en sus componentes tienen que especificar la ruta a sus layouts en cada llamada o crear sus propias classes extendidas.
  • ¿Qué pasa si un diseñador quiere mostrar de un modo distinto los tags en una vista de blog de una vista de categoría?
  • ¿Cómo puede un diseñador personaliza cómo quiere mostrar algo específicamente para un componente?

A mi me surgieron esos problemas en mi trabajo diario y de ahí surgeron mis propuestas para mejorar el sistema. Algunas de esas cosas tienen una "difícil" solución usando el sistema anterior pero yo quería un sistema sencillo y automático que pudiera también cubrir escenarios más complejos.

5. Nuevas características

Después de mi propuesta inicial la magia de Joomla! comenzó y surgieron nuevas propuestas. El resultado final es un sistema mucho mejor de lo que yo había pensado originalmente. La mágia del código abierto.

Como pista de las nuevas mejoras un ejemplo de llamada de layout ahora:

$layout = new JLayoutFile('joomla.content.tags', null, array('debug' => true, 'client' => 1, 'component' => 'com_tags'));

5.1. Override de layouts en componentes

Una de las modificaciones es que ahora el sistema automáticamente busca layouts en el componente activo.

La llamada usada en nuestro anterior ejemplo:

$layout = new JLayoutFile('joomla.content.tags');

$layout->render($itemTags);

Buscaría layouts en los siguientes directorios (ordenados por prioridad):

    
[0] => templates/mytemplate/html/layouts/com_mycomponent
[1] => components/com_mycomponent/layouts
[2] => templates/mytemplate/html/layouts
[3] => layouts

Eso significa que puedes usar layouts estándar, personalizarlos dentro de tu componente y un diseñador puede personalizar tu personalización dentro de la plantilla.

En nuestro ejemplo un desarrollador puede personalizar la forma en la que los tags se muestran dentro de su componente y un diseñador puede personalizar los tags para ese componente en la plantilla.

5.2. Forzar componente

El ejemplo anterior detecta el componente activo cuando el layout es cargado. Pero ¿qué pasa si quiero mostrar mis tags del mismo modo en que se muestran en com_tags? Esto se consigue con una llamada como:

$layout = new JLayoutFile('joomla.content.tags', null, array('component' => 'com_tags'));

Para no buscar layouts dentro de ningún componente se puede usar 'component' => 'none'

5.3. Forzar cliente

Otra de las cosas que el sistema detecta automáticamente es el cliente desde el que se hace la llamada a los layouts. Si estás en el frontend el sistema buscará layouts en el frontend.

Pero yo quiero mostrar los tags en la administración del mismo modo en el que com_tags los muestra en el frontend! Esto puede hacerse con una llamada como:

$layout = new JLayoutFile('joomla.content.tags', null, array('client' => 0, 'component' => 'com_tags'));

El parámetro client soporta estos valores:

  • 0, 'site' > frontend
  • 1, 'admin' > backend

5.4. Añadir include paths

Digamos que acabas teniendo una carpeta con layouts pero no quieres almacenarlos todos allí. Sólo quieres que el sistema busque automáticamente layouts en ese directorio antes de los directorios por defecto. Por ejemplo en mi empresa tenemos una librería que contiene nuestros layouts compartidos para todos nuestros componentes.

Esto se hace con el nuevo método:

$layout = new JLayoutFile('joomla.content.tags');

$layout->addIncludePaths(JPATH_LIBRARIES . '/hacknsa');

Eso añadiría /libraries/hacknsa con la más alta prioridad para la búsqueda de layouts. Este método también soporta un array the directorios. Cuando le pases arrays recuera que el último tendrá la más alta prioridad.

5.5. Sufijos

Otra de las propuestas (en este caso de Robert Deutz) era ser capaz de especificar sufijos para los layouts. Esto es "versiones" del mismo layout que buscar. La idea origina era permitir a las extensiones buscar un layout específico para esta version de Joomla! y si no usar la estándar. Ejemplo:

$layout = new JLayoutFile('joomla.content.tags', null, array('suffixes' => array('j3x', 'j25')));

echo $layout->render($this->item->tags->itemTags);

Pero este es sólo uno de los usos. Imagina que necesitas un layout diferente para idiomas RTL (del inglés Right To Left - idiomas que se leen the derecha a izquierda). Puedes agregarlo como sufijo para automáticamente buscar un layout específico para RTL en caso de estar activo. O imagina la dirección de un cliente cuyo código zip se muestra de forma diferente dependiendo del país. Puedes agregar un sufijo para el idioma activo por ejemplo y en caso de no existir usará la versión por defecto.

5.6. Sublayouts

Una de las cosas molestas de JLayouts era que no puedes heredar la configuración de un layout para usarla en layouts "hijos". Para hacerlo tenías hacer una llamada que contendría otra vez todas las opciones.

Expliquemos la nueva característica con otro ejemplo: una de las cosas que necesitábams en redCOMPONENT era facturas personalizables. Enseguida pensé en los layouts. Gracias a ellos puedo tener una llamada como:

echo JLayoutHelper::render('invoice', $invoiceData);

Y dentro de ese layout tener algo como:

<div class="invoice">
    <div class="customer">
        <?php echo $this->sublayout('shopper', $displayData['shopper']); ?>
    </div>
    <div class="header">
        <?php echo $this->sublayout('header', $displayData); ?>
    </div>
    <div class="products">
        <?php echo $this->sublayout('products', $displayData['products']); ?>
    </div>
    <div class="footer">
        <?php echo $this->sublayout('footer', $displayData); ?>
    </div>
</div>

Que es un layout principal para la factura que dentro llama a varios sublayouts. Así un usuario puede personalizar la cabecera de la factura sin tener que editar el resto.

Cuando llamas a un sublayout el sistema trata de encontrar un directorio llamado como el layout padre y dentro los sublayouts. En nuestro ejemplo tendríamos un layout principal invoice.php y en su mismo directorio un directorio llamado invoice que contiene los sublayouts (shopper.php, header.php, products.php y footer.php).

Los sublayouts heredarán toda la configuración del layout padre. Usarán los mismos include paths, el mismo cliente, el mismo componente y los mismos sufijos.

5.7. Modo debug

Cuando empiezas a tratar con layouts en varios include paths, clientes, componentes... Es fácil acabar sin saber desde dónde se están cargando los layouts. Es por eso que incluí un sistema de debug algo cutre pero útil :D. Para activar el modo debug sólo hay que pasar esa opción debug como en este ejemplo:

$layout = new JLayoutFile('joomla.content.tags', null, array('suffixes' => array('j3x', 'j25'), 'debug' => true));

echo $layout->render($this->item->tags->itemTags);

Veríamos algo como:

 Modo debug en JLayout

6. ¿Dónde no usar layouts?

Los layouts son muy útiles cuando los usamos apropiadamente pero pueden ser un terrible error si lo hacemos en sitios donde carecen de sentido. Y ahora todo el mundo quiere convertir todo a layouts! Así podemos encontrar fáclmente layouts que son usados en artículos, banners, contacts, clientes, weblinks, newsfeeds... Pero eso es bueno ¿no?. No! Sólo estamos creando un layout único con un montón de ifs dentro para cubrir todas las diferencias de los componentes.

En mi opinion no hay ningún beneficio en usar un layout para renderizar 4 campos. Eso se debe de hacer en una plantilla de vista porque no se va a usar fuera del núcleo. Y ese es mi consejo: si algo puede usarse fuera del núcleo entonces tiene sentido como layout (como los tags). Ejemplos de layouts: renderizar una lista, un botón, un menú, la paginación.... Otro buen consejo es: si no se puede personalizar sin editar el núcleo de Joomla! es mejor usar un layout.

Los layouts no son la solución a todo.

7. Otros usos

Imagina la carga de jQuery que se hace nativamente en Joomla! Esto se hace desde las clases JHtml. ¿Por qué no hacer que JHtml busque automáticamente versiones personalizadas dentro de los componentes? Así podría tener mi propia versión de jQuery comprobada con el resto de librerías que uso en mi componente. Sí, puede entrar en conflicto con requerimientos de los módulos pero ¿no es eso mismo lo que pasa en la actualidad? Como mínimo evitaríamos sencillamente cargar jQuery muchas veces.

Ahora imagina que el menú superior del backend tiene un bug y se han usado layouts para renderizarlo. Puedes arreglarlo dentro de tu componente sin necesidad de esperar a un parche oficial. Lo mismo si tienes una librería que entra en conflicto con el núcleo de Joomla! Ahorramos un montón de tiempo de soporte explicando que el problem está en el core, no en nuestra extensión.

Y esto son solo algunas ideas!!

8. Conclusión

Los layouts son una herramienta poderosíma y es una de esas cosas que nos ayudaría a reconciliar a desarrolladores y diseñadores. Hay muchos sitios donde usar layouts, algunos aún no se han descubierto y otros están ahí esperando que alguien haga el trabajo. ¿Nos ayudas?