Generar enlaces a páginas y de eventos en Apache Tapestry

Escrito por picodotdev el .
tapestry planeta-codigo
Enlace permanente Comentarios

Una de las partes esenciales de una aplicación web es generar enlaces a otras páginas, enlaces a los manejadores de los formularios que procesan los datos enviados, enlaces a manejadores de solicitudes AJAX. Generar enlaces no solo es necesario para ser usados dentro de la misma aplicación web sino también para ser usados en el código JavaScript, en correos electrónicos u informes.

La ventaja de utilizar un framework es que estos facilitan el desarrollo y en el caso de generar enlaces suelen incluir soporte. Pero también es importante que la facilidad que proporcionan los frameworks para generarlos no sea concatenando y hardcodeado cadenas. Si es así en el momento de querer renombrar una página o manejador de evento se convierte en un problema por la inseguridad que plantea para realizar el refactor, más en una aplicación grande. Y esto puede dar el caso de que algunos refactors no se aborden por miedo a romper cosas, a la larga es un problema para el desarrollo futuro y el mantenimiento de la aplicación.

En el caso del framework Apache Tapestry se proporciona un amplio soporte para generar enlaces y evitar concatenaciones y hardcodeos al menos en el código Java. Por otra parte al ser el framework el encargado de construir las URLs si por una nueva versión de framework las URLs cambiar no es necesario realizar ningún cambio en el código.

Lo más básico son los componentes PageLink, ActionLink, EventLink y From con los que generar enlaces a páginas, acciones y eventos en las plantillas de las páginas y componentes.

En las plantillas que generan el contenido HTML solo en el caso de un enlace a una página hay que hacer un hardcodeo con el nombre de la página. En el caso del formulario es el propio framework el encargado de generar la URL y en caso de los eventos hacen referencia a la página y componente donde están incluidos.

1
2
3
4
5
6
7
8
9
<a t:type="pagelink" page="user/view" context="user.id">${user.lastname}</a>

<a t:type="actionlink" t:id="delete" context="user.id">Delete</a>
<a t:type="eventlink" t:event="event" t:zone="zone" t:parameters="prop:{'t:sid':'id'}">Delete</a>

<t:form t:id="form" clientValidation="none">
    ...
    <t:submit value="Seleccionar"/>
</t:form>
Page.tml

Mediante código también se pueden generar enlaces en el caso de querer incluirlos en un coreo electrónico para uso fuera de la aplicación, para las páginas con la clase PageRenderLinkSource, para acciones y eventos con la clase ComponentResources. En el caso de PageRenderLinkSource tiene métodos para hacer referencia a las páginas con su clase de modo que si se hiciese un renombrado de la página el IDE se encargaría de hacer el renombrado, en el caso de usar ComponentResources solo hace falta indicar el nombre del evento el framework se encarga de establecerlo según la página en la que se realiza la acción.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
...

import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.Link;

public class Component {
    ...

    @Inject
    private ComponentResources resources;

    ...

    public void method() {
        ...
        Link actionLink = resources.createEventLink(EventConstants.ACTION, contextArray);
        Link eventLink = resources.createEventLink("event", contextArray);
        ...
    }
}
Events.java

Para generar enlaces de eventos a páginas hay que inyectar esa página y obtener su ComponentResources, el enlace se genera de la misma forma que los casos anteriores.

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

public class Page {

    @Inject
    private PageRenderLinkSource pageLinkSource;

    @Inject
    private AnotherPage anotherPage;

    ...

    public AnotherPage void onActionFromDelete(Long id) {
        Link anotherPageLink = pageLinkSource.createPageRenderLink(AnotherPage.class);

        ComponentResources anotherPageResources = anotherPage.getRootComponent().getComponentResources();
        Link actionLink = anotherPageResources.createEventLink("delete");

        ...

        return AnotherPage.class;
    }
}
Page.java

Todos estos métodos devuelven una clase del tipo Link que con los métodos toAbsoluteURI(), toRedirectURI(), toRedirectURI(bool) y toURI() permiten obtener la cadena que representa el enlace. Esta clase tiene otros métodos para en caso de necesidad acceder a los diferentes elementos del enlace evitando tener que interpretarlo para acceder a ellos. Estos cadenas son las que se incluirían en los correos electrónicos, informes y otras aplicaciones puede que también otras páginas y JavaScript.

Desde el lado del cliente en JavaScript también puede ser necesario lanzar eventos, pare evitar generar algunos de los enlaces en lado de servidor y enviarlos al lado del cliente para que estos los usen. En el lado del cliente también se ofrece soporte para lanzar eventos lo que simplifica algunos casos.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
require(["t5/core/ajax", "jquery"], function (ajax, $) {
    $('#result').click(function() {
        ajax('answer', { 
            element: null, // $('#result')
            success: function(response) {
                $('#result').text(response.json.origin);
            }
        });
    });
});
events.js
Referencia:
Comparte el artículo: