java templates velocity

java - Cómo#incluir un archivo de una plantilla de Velocity usando ClasspathResourceLoader



templates (1)

Con respecto al código de muestra, el problema se resuelve agregando una propiedad más a la instancia de Properties utilizada para inicializar el motor:

properties.setProperty(RuntimeConstants.EVENTHANDLER_INCLUDE, IncludeRelativePath.class.getName());

Esto permite hacer referencia a la ruta del archivo que se incluirá como una ruta relativa a la carpeta donde se encuentra la plantilla. Entonces, si ambos archivos están en la misma carpeta, no es necesario especificar una ruta en la directiva #include : simplemente #include("MyInclude.vm") .

También esperaba aprender algo sobre el oscuro TEMPLATE_ROOT (para mí), como por ejemplo. Lo que es, ya que es sorprendentemente difícil para mí encontrar esta información documentada en cualquier lugar. Pero sea lo que sea, al menos en mi caso corresponde al paquete raíz del proyecto Java (el paquete "predeterminado"). Esto significa que si no utilizo la propiedad adicional mencionada anteriormente, luego se coloca el archivo MyInclude.vm en el paquete raíz.

Estoy tratando con un código Java donde Velocity 1.7 está configurado para recuperar plantillas a través del ClasspathResourceLoader. A continuación se muestra una muestra simplificada del código. Es de una aplicación web de Tapestry que se ejecuta en un servidor Jetty.

La clase de Java, las plantillas y el archivo a incluir están todos en la misma carpeta "testpackage", por lo que en el JAR resultante están todos en el mismo paquete "testpackage".

El problema es que si la plantilla contiene un

#include("MyInclude.vm")

directiva, Velocity no puede encontrar "MyInclude.vm" y lanza una excepción ResourceNotFoundException.

Dado que en el argumento de getTemplate debo anteponer el nombre del paquete al nombre de la plantilla, también intenté hacer lo mismo en el #include dentro de la plantilla:

#include("testpackage/MyInclude.vm")

pero la única diferencia es que la última funciona si ejecuto la aplicación web desde Eclipse, mientras que la primera no funciona ni desde Eclipse. Si compilo, implemento los JAR y ejecuto la aplicación web desde el despliegue, ambas sintaxis fallan con la misma excepción ResourceNotFoundException.

El documento de Velocity en http://velocity.apache.org/engine/releases/velocity-1.7/user-guide.html#Include dice:

"Por razones de seguridad, el archivo que se va a incluir solo puede estar bajo TEMPLATE_ROOT"

Definitivamente, esto podría ser la causa de mi problema, pero no he podido encontrar más información sobre lo que realmente es TEMPLATE_ROOT.

Suena como una variable de entorno, pero no sé a qué debo configurarlo, ya que estoy usando un ClasspathResourceLoader, y el archivo que se incluirá no es un archivo real ubicado en una carpeta, está dentro del JAR que contiene las plantillas y la clase Java (y todas en el mismo paquete).

Encontré TEMPLATE_ROOT mencionado en otra pregunta, ¿Dónde debo colocar los archivos de plantilla de Velocity para una utilidad de línea de comandos creada con Maven? , pero está relacionado con el uso de un FileResourceLoader. Necesito seguir usando ClasspathResourceLoader y necesito que todos los archivos estén en el JAR, no fuera de ellos como archivos normales en alguna carpeta.

TestVelocity.java

package testpackage; import java.io.StringWriter; import java.util.Properties; import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.VelocityEngine; public class TestVelocity { public static String getText() { String text = ""; Properties properties = new Properties(); properties.setProperty("resource.loader", "class"); properties.setProperty("class.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader"); VelocityEngine engine = new VelocityEngine(); VelocityContext context = new VelocityContext(); StringWriter writer = new StringWriter(); try { engine.init(properties); // This works because the template doesn''t contain any #include Template template = engine.getTemplate("testpackage/TemplateWithoutInclude.vm"); // This causes ResourceNotFoundException: Unable to find resource ''TemplateWithInclude.vm'' // Template template = engine.getTemplate("testpackage/TemplateWithInclude.vm"); template.merge(context, writer); text = writer.toString(); } catch (Exception e) { e.printStackTrace(); } return text; } }

TemplateWithoutInclude.vm

<!DOCTYPE html> <html> <head></head> <body> <p>Hello</p> </body> </html>

TemplateWithInclude.vm

<!DOCTYPE html> <html> <head></head> <body> #include("MyInclude.vm") </body> </html>

MyInclude.vm

<p> Hello </p>