¿Trucos de JSP para facilitar la creación de plantillas?

En el trabajo, me han encargado que convierta un montón de archivos HTML en un proyecto JSP simple. En realidad, es todo estático, no hay lógica en el servidor para progtwigr. Debo mencionar que soy completamente nuevo en Java. Los archivos JSP parecen facilitar el trabajo con inclusiones y variables comunes, al igual que PHP , pero me gustaría saber una forma simple de obtener algo así como la herencia de la plantilla (estilo Django ) o al menos poder tener una base.jsp archivo que contiene el encabezado y el pie de página, por lo que puedo insertar contenido más tarde.

Ben Lings parece ofrecer algo de esperanza en su respuesta aquí: herencia de la plantilla JSP ¿Puede alguien explicar cómo lograr esto?

Dado que no tengo mucho tiempo, creo que el enrutamiento dynamic es un poco demasiado, por lo que me complace que las URL se asignen directamente a los archivos .jsp , pero estoy abierto a la sugerencia.

Gracias.

editar: no quiero usar ninguna biblioteca externa, porque boostía la curva de aprendizaje para mí y para otros que trabajan en el proyecto, y la compañía para la que trabajo ha sido contratada para hacer esto.

Otra edición: no estoy seguro de si las JSP tags serán útiles porque mi contenido realmente no tiene ninguna variable de plantilla. Lo que necesito es una forma de poder hacer esto:

base.html:

  { content.body }  

somepage.html

  

Welcome

con el resultado siendo:

  

Welcome

Creo que esto me daría la suficiente versatilidad para hacer todo lo que necesito. Se podría lograr con includes pero luego necesitaría incluir un top y un bottom para cada wrapper, lo cual es un poco complicado.

Como sugirió skaffman , los archivos de tags JSP 2.0 son las rodillas de la abeja.

Tomemos su ejemplo simple.

Coloque lo siguiente en WEB-INF/tags/wrapper.tag

 <%@tag description="Simple Wrapper Tag" pageEncoding="UTF-8"%>    

Ahora en tu página example.jsp :

 <%@page contentType="text/html" pageEncoding="UTF-8"%> <%@taglib prefix="t" tagdir="/WEB-INF/tags" %>  

Welcome

Eso hace exactamente lo que crees que hace.


Por lo tanto, vamos a ampliar eso a algo un poco más general. WEB-INF/tags/genericpage.tag

 <%@tag description="Overall Page template" pageEncoding="UTF-8"%> <%@attribute name="header" fragment="true" %> <%@attribute name="footer" fragment="true" %>    

Para usar esto:

 <%@page contentType="text/html" pageEncoding="UTF-8"%> <%@taglib prefix="t" tagdir="/WEB-INF/tags" %>   

Welcome

Hi I'm the heart of the message

¿Qué te compra eso? Mucho en realidad, pero se pone aún mejor …


WEB-INF/tags/userpage.tag

 <%@tag description="User Page template" pageEncoding="UTF-8"%> <%@taglib prefix="t" tagdir="/WEB-INF/tags" %> <%@attribute name="userName" required="true"%>   

Welcome ${userName}

Para usar esto: (supongamos que tenemos una variable de usuario en la solicitud)

 <%@page contentType="text/html" pageEncoding="UTF-8"%> <%@taglib prefix="t" tagdir="/WEB-INF/tags" %>  

First Name: ${user.firstName}
Last Name: ${user.lastName}
Phone: ${user.phone}


Pero resulta útil utilizar ese bloque de detalles de usuario en otros lugares. Entonces, lo refaccionaremos. WEB-INF/tags/userdetail.tag

 <%@tag description="User Page template" pageEncoding="UTF-8"%> <%@tag import="com.example.User" %> <%@attribute name="user" required="true" type="com.example.User"%> First Name: ${user.firstName} 
Last Name: ${user.lastName}
Phone: ${user.phone}

Ahora el ejemplo anterior se convierte en:

 <%@page contentType="text/html" pageEncoding="UTF-8"%> <%@taglib prefix="t" tagdir="/WEB-INF/tags" %>  


La belleza de los archivos de tags JSP es que básicamente le permite etiquetar marcas genéricas y luego refactorizarlas al contenido de su corazón.

JSP Tag Files prácticamente han usurpado cosas como Tiles , etc., al menos para mí. Las encuentro mucho más fáciles de usar ya que la única estructura es lo que le das, nada preconcebido. Además, puede usar archivos de tags JSP para otras cosas (como el fragmento de detalles del usuario anterior).

Aquí hay un ejemplo similar al DisplayTag que he hecho, pero todo esto está hecho con Tag Files (y el framework Stripes , esas son las tags s: ..). Esto da como resultado una tabla de filas, colores alternos, navegación de página, etc.

          Edit      

Por supuesto, las tags funcionan con las JSTL tags (como c:if , etc.). Lo único que no puede hacer dentro del cuerpo de una etiqueta de archivo de etiqueta es agregar el código scriptlet de Java, pero esto no es una limitación tan grande como podría pensar. Si necesito algo de scriptlet, simplemente pongo la lógica en una etiqueta y coloco la etiqueta. Fácil.

Entonces, los archivos de tags pueden ser lo que usted quiera que sean. En el nivel más básico, es simple refactorización de cortar y pegar. Tome un pedazo de diseño, recórtelo, realice parametrizaciones simples y reemplácelo con una invocación de tags.

En un nivel superior, puedes hacer cosas sofisticadas como esta etiqueta de tabla que tengo aquí.

Hice bastante fácil, Django style JSP Template inheritance tag library. https://github.com/kwon37xi/jsp-template-inheritance

Creo que es fácil administrar diseños sin curva de aprendizaje.

código de ejemplo:

base.jsp: diseño

 <%@page contentType="text/html; charset=UTF-8" %> <%@ taglib uri="http://kwonnam.pe.kr/jsp/template-inheritance" prefix="layout"%>    JSP Template Inheritance  

Head

header

Contents

Contents will be placed under this h2

view.jsp: contenido

 <%@page contentType="text/html; charset=UTF-8" %> <%@ taglib uri="http://kwonnam.pe.kr/jsp/template-inheritance" prefix="layout"%>   

This is an example about layout management with JSP Template Inheritance

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin porta, augue ut ornare sagittis, diam libero facilisis augue, quis accumsan enim velit a mauris.

Basado en la misma idea básica que en la respuesta de @Will Hartung , aquí está mi motor mágico de plantillas extensibles de una sola etiqueta. Incluso incluye documentación y un ejemplo 🙂

WEB-INF / tags / block.tag:

 <%-- The block tag implements a basic but useful extensible template system. A base template consists of a block tag without a 'template' attribute. The template body is specified in a standard jsp:body tag, which can contain EL, JSTL tags, nested block tags and other custom tags, but cannot contain scriptlets (scriptlets are allowed in the template file, but only outside of the body and attribute tags). Templates can be full-page templates, or smaller blocks of markup included within a page. The template is customizable by referencing named attributes within the body (via EL). Attribute values can then be set either as attributes of the block tag element itself (convenient for short values), or by using nested jsp:attribute elements (better for entire blocks of markup). Rendering a template block or extending it in a child template is then just a matter of invoking the block tag with the 'template' attribute set to the desired template name, and overriding template-specific attributes as necessary to customize it. Attribute values set when rendering a tag override those set in the template definition, which override those set in its parent template definition, etc. The attributes that are set in the base template are thus effectively used as defaults. Attributes that are not set anywhere are treated as empty. Internally, attributes are passed from child to parent via request-scope attributes, which are removed when rendering is complete. Here's a contrived example: ====== WEB-INF/tags/block.tag (the template engine tag)  ====== WEB-INF/templates/base.jsp (base template) <%@ page trimDirectiveWhitespaces="true" %> <%@ taglib prefix="t" tagdir="/WEB-INF/tags" %>  Template Page  .footer { font-size: smaller; color: #aaa; } .content { margin: 2em; color: #009; } ${moreStyle}        ${title}    

${title}

${content}
${footer}
====== WEB-INF/templates/history.jsp (child template) <%@ page trimDirectiveWhitespaces="true" %> <%@ taglib prefix="t" tagdir="/WEB-INF/tags" %>

${shooter} shot first!

====== history-1977.jsp (a page using child template) <%@ page trimDirectiveWhitespaces="true" %> <%@ taglib prefix="t" tagdir="/WEB-INF/tags" %> ====== history-1997.jsp (a page using child template) <%@ page trimDirectiveWhitespaces="true" %> <%@ taglib prefix="t" tagdir="/WEB-INF/tags" %> .revised { font-style: italic; } Greedo --%> <%@ tag trimDirectiveWhitespaces="true" %> <%@ tag import="java.util.HashSet, java.util.Map, java.util.Map.Entry" %> <%@ tag dynamic-attributes="dynattributes" %> <%@ attribute name="template" %> <% // get template name (adding default .jsp extension if it does not contain // any '.', and /WEB-INF/templates/ prefix if it does not start with a '/') String template = (String)jspContext.getAttribute("template"); if (template != null) { if (!template.contains(".")) template += ".jsp"; if (!template.startsWith("/")) template = "/WEB-INF/templates/" + template; } // copy dynamic attributes into request scope so they can be accessed from included template page // (child is processed before parent template, so only set previously undefined attributes) Map dynattributes = (Map)jspContext.getAttribute("dynattributes"); HashSet addedAttributes = new HashSet(); for (Map.Entry e : dynattributes.entrySet()) { if (jspContext.getAttribute(e.getKey(), PageContext.REQUEST_SCOPE) == null) { jspContext.setAttribute(e.getKey(), e.getValue(), PageContext.REQUEST_SCOPE); addedAttributes.add(e.getKey()); } } %> <% if (template == null) { // this is the base template itself, so render it %> <% } else { // this is a page using the template, so include the template instead %> <% } %> <% // clean up the added attributes to prevent side effect outside the current tag for (String key : addedAttributes) { jspContext.removeAttribute(key, PageContext.REQUEST_SCOPE); } %>

Usa fichas Me salvó la vida.

Pero si no puedes, está la etiqueta de inclusión , que lo hace similar a php.

Es posible que la etiqueta corporal no haga lo que usted necesita, a menos que tenga un contenido súper simple. La etiqueta del cuerpo se utiliza para definir el cuerpo de un elemento especificado. Echa un vistazo a este ejemplo :

  ${content.lang} ${content.body}  

Usted especifica el nombre del elemento, cualquier atributo que ese elemento pueda tener (“lang” en este caso), y luego el texto que lo incluye: el cuerpo. Así que si

  • content.headerName = h1 ,
  • content.lang = fr , y
  • content.body = Heading in French

Entonces la salida sería

 

Heading in French