How to use String as Velocity Template?

There is some overhead parsing template. You might see some performance gain by pre-parsing the template if your template is large and you use it repeatedly. You can do something like this,

RuntimeServices runtimeServices = RuntimeSingleton.getRuntimeServices();
StringReader reader = new StringReader(bufferForYourTemplate);
Template template = new Template();
template.setRuntimeServices(runtimeServices);

/*
 * The following line works for Velocity version up to 1.7
 * For version 2, replace "Template name" with the variable, template
 */
template.setData(runtimeServices.parse(reader, "Template name")));

template.initDocument();

Then you can call template.merge() over and over again without parsing it everytime.

BTW, you can pass String directly to Velocity.evaluate().


The above sample code is working for me. It uses Velocity version 1.7 and log4j.

private static void velocityWithStringTemplateExample() {
    // Initialize the engine.
    VelocityEngine engine = new VelocityEngine();
    engine.setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS, "org.apache.velocity.runtime.log.Log4JLogChute");
    engine.setProperty("runtime.log.logsystem.log4j.logger", LOGGER.getName());
    engine.setProperty(Velocity.RESOURCE_LOADER, "string");
    engine.addProperty("string.resource.loader.class", StringResourceLoader.class.getName());
    engine.addProperty("string.resource.loader.repository.static", "false");
    //  engine.addProperty("string.resource.loader.modificationCheckInterval", "1");
    engine.init();

    // Initialize my template repository. You can replace the "Hello $w" with your String.
    StringResourceRepository repo = (StringResourceRepository) engine.getApplicationAttribute(StringResourceLoader.REPOSITORY_NAME_DEFAULT);
    repo.putStringResource("woogie2", "Hello $w");

    // Set parameters for my template.
    VelocityContext context = new VelocityContext();
    context.put("w", "world!");

    // Get and merge the template with my parameters.
    Template template = engine.getTemplate("woogie2");
    StringWriter writer = new StringWriter();
    template.merge(context, writer);

    // Show the result.
    System.out.println(writer.toString());
}

A similar so question.


This works in Velocity 2.1

// Initialize the engine
VelocityEngine velocityEngine = new VelocityEngine();
velocityEngine.setProperty(Velocity.RESOURCE_LOADERS, "string");
velocityEngine.setProperty("resource.loader.string.class", StringResourceLoader.class.getName());
velocityEngine.setProperty("resource.loader.string.cache", true);
velocityEngine.setProperty("resource.loader.string.modification_check_interval", 60);
velocityEngine.init();

// Add template to repository
StringResourceRepository repository = StringResourceLoader.getRepository()
repository.putStringResource("hello_world", "Hello $w");

// Set parameters
VelocityContext context = new VelocityContext();
context.put("w", "world!");

// Process the template
StringWriter writer = new StringWriter();
velocityEngine.getTemplate('hello_world').merge( context, writer );

System.out.println(writer.toString());

Velocity 2 can be integrated into the JSR223 Java Scripting Language Framework which make another option to transform string as a template:

ScriptEngineManager manager = new ScriptEngineManager();
manager.registerEngineName("velocity", new VelocityScriptEngineFactory());
ScriptEngine engine = manager.getEngineByName("velocity");


System.setProperty(VelocityScriptEngine.VELOCITY_PROPERTIES, "path/to/velocity.properties");
String script = "Hello $world";
Writer writer = new StringWriter();
engine.getContext().setWriter(writer);
Object result = engine.eval(script);
System.out.println(writer);