Plantillas con etiquetas no balanceadas en Apache Tapestry

Escrito por el .
java planeta-codigo programacion tapestry
Enlace permanente Comentarios

Apache Tapestry es uno de los mejores frameworks web para Java que he usado, sin embargo, también tiene algún incordio o curiosidad. Una de ellas es que las plantillas han de ser XML bien formado y en este caso que comento en el que necesitaríamos una plantilla con etiquetas desbalanceadas nos obliga a buscar una solución, esta es la que uso.

Apache Tapestry

Las plantillas en Apache Tapestry son XHTML, esto quiere decir que al ser archivos xml han de estar bien formados con sus etiquetas bien balanceadas y anidadas. Esto tiene la ventaja de que Tapestry nos avisará cuando se intente generar código HTML mal formado con el contenido de plantilla, una especie de compilación que si no es correcta no pasará desapercibida como en otros frameworks y que puede generar otro tipo de errores. Sin embargo, también tiene una desventaja y es que si necesitamos generar una etiqueta de inicio dentro de un componente if la plantilla no será válida.

Supongamos que queremos generar un contenido a tres columnas de una serie de elementos, en cada tercer elemento de la fila tendremos que cerrar la fila anterior y abrir una nueva. El ejemplo de lo que no se puede hacer es el siguiente:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<t:loop source="elements" value="element" index="i">
    <t:if test="open">
        <div class="row"><div class="col-xs-12 col-md-4">
    </t:if>

    ...

    <t:if test="close">
        </div></div>
    </t:if>
</t:loop>
template-1.tml

En este ejemplo las etiquetas div de apertura y cierre hacen que el XML de la plantilla no esté bien balanceado. No se si habrá otra forma mejor pero esta es el rodeo que uso para tener una plantilla bien balanceada y generar el contenido HTML necesario. En el código Java del componente creo un método que devuelve un mapa de trozos de HTML que no podría incluir en la propia plantilla, cada trozo de HTML tiene una clave asociada por la que identificarlo, en este caso open y close.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public Component {

   ...

    public boolean isOpen() {
        return (i % 3 == 0);
    }

    public boolean isClose() {
        return (i + 1 % 3 == 0 || isLast());
    }

    public boolean isLast() {
        return elements.indexOf(element) == elements.size() - 1;
    }

    @Cached
    public Map getTags() {
        Map<String, String> m = new HashMap<>();
        m.put("open", "<div class=\"row\"><div class=\"col-xs-12 col-md-4\">");
        m.put("close", "</div></div>");        
        return m;
    }
}
Component.java

Usando estos métodos en la plantilla el código de la plantilla tml ya bien formado quedaría de la siguiente manera, usando el componente OutputRaw se emite el trozo HTML de apertura o cierre:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<t:loop source="elements" value="element" index="i">
    <t:if test="open">
        <t:outputraw value="tags.get('open')"/>
    </t:if>

    ...

    <t:if test="close">
        <t:outputraw value="tags.get('close')"/>
    </t:if>
</t:loop>
template-2.tml

Esta pequeña «ñapa» que no es muy habitual en las plantillas pero que en algún caso puede ser necesario emplear es una forma de hacer las plantillas tml bien formadas en circunstancias donde incluyéndolo en la plantilla no lo sería.

Prefiero que Tapestry me valide que el XML de la plantilla esté bien formado evitando que se pudiera generar HTML con etiquetas no balanceadas y me obligue a hacer este rodeo que la posibilidad de generar HTML con etiquetas mal balanceadas que los navegadores aceptan pero que en algún caso podría provocar una desmaquetación, aunque en los casos que se aplique esta solución hay que tener especial cuidado ya que como no se realiza ninguna validación al emitir etiquetas de forma «cruda» el HTML generado podría estar mal balanceado.

Portada libro: PlugIn Tapestry

Libro PlugIn Tapestry

Si te interesa Apache Tapestry descarga gratis el libro de más de 300 páginas que he escrito sobre este framework en el formato que prefieras, PlugIn Tapestry: Desarrollo de aplicaciones y páginas web con Apache Tapestry, y el código de ejemplo asociado. En el libro comento detalladamente muchos aspectos que son necesarios en una aplicación web como persistencia, pruebas unitarias y de integración, inicio rápido, seguridad, formularios, internacionalización (i18n) y localización (l10n), AJAX, ... y como abordarlos usando Apache Tapestry.



Comparte el artículo: