Creación de librerías de tags


1. (FAQS)
Como ejercicio de esta sesión vamos a crear un tag propio dentro de una librería nueva, que llamaremos faqtags. El tag se va a llamar datosfaq, y mostrará los datos de una FAQ concreta. Tendrá la siguiente sintaxis:

<datosfaq id="id" pregunta="pregunta" respuesta="respuesta" fecha="fecha"/>

donde:

Lo que hará el tag internamente es mostrar la información de la FAQ en un formato determinado. Para ello, lo que se pide es:

a) Escribir la clase que implementa el tag

La clase que implementa el tag es FAQTag, que se encuentra dentro del paquete faqs.tags en la plantilla del ejercicio. Deberemos rellenar esta clase para que:

private PageContext contexto; 
private Tag padre;

Utilizaremos cuatro campos más, uno para cada atributo del tag:

int id = -1; 
String pregunta = null;
String respuesta = null;
String fecha = null;
public String getPregunta()
{
	return pregunta;
}

public void setPregunta(String pregunta)
{
	this.pregunta = pregunta;
}
return SKIP_BODY;
try 
{ 
   if (respuesta != null && fecha != null)
   {
	// Se muestran todos los datos de la FAQ
	contexto.getOut().write("<b>Id:</b>" + id + "<br>");
	contexto.getOut().write("<b>Pregunta:</b>" + pregunta + "<br>");
	contexto.getOut().write("<b>Respuesta:</b>" + respuesta + "<br>");
	contexto.getOut().write("<b>Fecha:</b>" + fecha + "<br>");
   } else {
	// Solo se muestran los campos requeridos
	// En la pregunta ponemos un enlace a faq.jsp para ver todos los datos
	contexto.getOut().write("<b>Id:</b>" + id + "<br>");
	contexto.getOut().write("<b>Pregunta</b>:<a target=\"_blank\"" + 
			  " href=\"/faqs/faqs?pagina=faq.jsp" + 
			  "&id=<jsp:getProperty name=\"faq\" property=\"id\"/>\">" + 
			  pregunta + "</a><br>");	
   }
} catch(java.io.IOException e) { 
   throw new JspException("Error"); 
} 
return EVAL_PAGE;

b) Escribir el fichero TLD

Ya tenemos hecho el tag, ahora necesitamos definir el fichero TLD (que se da vacío como faqtags.tld en la plantilla), que define nuestra nueva librería de tags, con el tag implementado. Dicho fichero contendrá:

<?xml version="1.0" encoding="ISO-8859-1" ?> 
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, 
Inc.//DTD JSP Tag Library 1.1//EN" 
"http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd"> 

<taglib>
	... resto de elementos
</taglib>
<tlibversion>1.0</tlibversion> 
<jspversion>1.1</jspversion> 
<shortname>ft</shortname> 
<uri>faqtags</uri> 
<info>Librería de tags propia para aplicacion de FAQs</info>

Como hemos dicho, la librería se llamará faqtags, y utilizaremos el prefijo abreviado ft para referenciarla en las páginas jsp.

<tag> 
	<name>datosfaq</name> 
	<tagclass>faqs.tags.FAQTag</tagclass>
	<bodycontent>empty</bodycontent>
	<info>Muestra los datos de la FAQ</info>
	<attribute> 
		<name>id</name>
		<required>true</required>
		<rtexprvalue>true</rtexprvalue>
	</attribute> 	
	<attribute> 
		<name>pregunta</name>
		<required>true</required>
		<rtexprvalue>true</rtexprvalue>
	</attribute> 	
	<attribute> 
		<name>respuesta</name>
		<required>false</required>
		<rtexprvalue>true</rtexprvalue>
	</attribute> 	
	<attribute> 
		<name>fecha</name>
		<required>false</required>
		<rtexprvalue>true</rtexprvalue>
	</attribute> 	
</tag>

El tag se llama faq, y no tiene cuerpo (bodycontent=empty). Se definen los cuatro atributos: id, pregunta, respuesta y fecha. De ellos, sólo los dos primeros son obligatorios (en algunos casos sólo mostraremos la pregunta, y en otros toda la información).

c) Incorporar la librería a la aplicación de FAQs

Para incorporar esta nueva librería a nuestra aplicación de FAQs, hacemos lo siguiente:

<taglib>
	<taglib-uri>faqtags</taglib-uri>
	<taglib-location>faqtags.tld</taglib-location>
</taglib>

NOTA: consultar la configuración de aplicaciones Web para ver dónde debe ir colocada la marca taglib.

d) Probar la librería en alguna página

Podemos probar a utilizar algún tag faq en alguna página.

<%@ taglib uri="faqtags" prefix="ft" %>

No utilizaremos los beans, así que no necesitamos las líneas:

<jsp:useBean ... />
<jsp:setProperty name="faq" property="id" .../>
<jsp:setProperty name="faq" property="pregunta" .../>
<jsp:setProperty name="faq" property="respuesta" .../>
<jsp:setProperty name="faq" property="fechaModif" .../>

... etc.

En su lugar nos guardaremos el parámetro faqs (para faqs.jsp) o faq (para faq.jsp) en una variable JSP del mismo tipo:

<% FAQBean[] faqs = 
   (FAQBean[])request.getAttribute("faqs"); %>
<% FAQBean faq = 
   (FAQBean)request.getAttribute("faq"); %>

y para mostrar los datos tendremos, respectivamente para cada fichero:

<ft:datosfaq id="<%= faqs[i].getId() %>"
     pregunta="<%= faqs[i].getPregunta() %>"/>
<ft:datosfaq id="<%= faq.getId() %>"
     pregunta="<%= faq.getPregunta() %>"
     respuesta="<%= faq.getRespuesta() %>"
     fecha="<%= faq.getFechaModif().toString() %>"/>
Vemos que se omiten los atributos no requeridos en faqs.jsp, para que se muestre el enlace que lleva a faq.jsp para ver los datos de la FAQ.

 

2. (FAQS) Opcionalmente, añadir un quinto atributo estilo al tag anterior. Dicho atributo será opcional, y en función de su  valor, se presentarán los datos del tag en uno u otro formato. Por ejemplo, estilo podría valer:

Para añadir este atributo, se recomienda seguir los pasos:

String estilo = null;
public String getEstilo()
{
	return estilo;
}

public void setEstilo(String estilo)
{
	this.estilo = estilo;
}
...
	<attribute> 
		<name>estilo</name>
		<required>false</required>
		<rtexprvalue>true</rtexprvalue>
	</attribute> 	
...
<ft:datosfaq id="<%= faqs[i].getId() %>"
     pregunta="<%= faqs[i].getPregunta() %>"
     estilo="tabla"/>
<ft:datosfaq id="<%= faq.getId() %>"
     pregunta="<%= faq.getPregunta() %>"
     respuesta="<%= faq.getRespuesta() %>"
     fecha="<%= faq.getFechaModif().toString() %>"
     estilo="lista"/>