What is the best way to create Velocity Template from a String?
I'm aware of Velocity.evaluate method where I can pass String or StringReader, but I'm curios is there a better way to do it (e.g. any advantage of creating an instance of Template).
What is the best way to create Velocity Template from a String?
I'm aware of Velocity.evaluate method where I can pass String or StringReader, but I'm curios is there a better way to do it (e.g. any advantage of creating an instance of Template).
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);
RuntimeServices rs = RuntimeSingleton.getRuntimeServices();
StringReader sr = new StringReader("Username is $username");
SimpleNode sn = rs.parse(sr, "User Information");
Template t = new Template();
t.setRuntimeServices(rs);
t.setData(sn);
t.initDocument();
VelocityContext vc = new VelocityContext();
vc.put("username", "John");
StringWriter sw = new StringWriter();
t.merge(vc, sw);
System.out.println(sw.toString());
If you are looking for just variable substitution then following works
public String velocityEvaluate(final String template, final NotificationDTO notificationDTO) {
final Map<String, String> context = getContextMap(notificationDTO);
final VelocityContext velocityContext = new VelocityContext(context);
final StringWriter stringWriter = new StringWriter();
final StringReader reader = new StringReader(template);
Velocity.evaluate(velocityContext, stringWriter, "Velocity String Template Evaluation", reader);
return stringWriter.toString();
}
In case if any one looking to transform from json string to json object, in that case, need to convert json string to JsonNode & store it in context. For Ex:
String jsonDataAsString = "{"name": "Aps"}";
JsonNode nodes = new ObjectMapper().readTree(jsonDataAsString );
VelocityContext velocityContext = new VelocityContext();
velocityContext.put("root", nodes);
then in your template, you can refer originating data which are set as "root" via "$root."+property
$root.name
Hope it helps someone.