- is "heavy": can be difficult to get into a project and functional, has some quirks with classloaders and logger systems, etc
- is old: last updates were back in 2010
Velocity is also loaded with features like control constructs, loops, branches, etc, which seem like overkill when all I really need to do is format email notifications with some variables (I've already gone the route of client-side view templates for my UI stuff these days).
I know there are a million ways to solve this using homegrown regex's and other such things, but I found a convenient helper in Commons Lang3: StrSubstitutor. It allows you to replace variables in a string, denoted by:
${varName}I've written a simple wrapper around it, which can pull a template string from a file on the classpath, caching it using a simple WeakHashMap. This could be extended to use the nicer caching framework found in the fantastic Google Guava project, perhaps.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.sungard.testtracker.util; | |
import java.util.Map; | |
import java.util.WeakHashMap; | |
import org.apache.commons.io.IOUtils; | |
import org.apache.commons.lang3.text.StrSubstitutor; | |
import com.google.common.collect.Maps; | |
public class Templates { | |
private static final WeakHashMap<String, String> templateCache = new WeakHashMap<String, String>(); | |
private String template; | |
private Map<String, String> values; | |
private Templates(String template) { | |
this.template = template; | |
this.values = Maps.newHashMap(); | |
} | |
public static Templates template(String template) { | |
return new Templates(template); | |
} | |
public Templates value(String name, String value) { | |
values.put(name, value); | |
return this; | |
} | |
public String render() { | |
String actualTemplate = loadTemplate(template); | |
return StrSubstitutor.replace(actualTemplate, values); | |
} | |
String loadTemplate(String template) { | |
String t = templateCache.get(template); | |
if (t == null) { | |
try { | |
t = IOUtils.toString(getClass().getClassLoader() | |
.getResourceAsStream(template)); | |
templateCache.put(template, t); | |
} catch (Exception e) { | |
throw new IllegalStateException("Error loading template: " | |
+ template, e); | |
} | |
} | |
return t; | |
} | |
} |
An example use of this class might be to stick a template text file into src/main/resources/templates/foo.template (for all of you fellow Maven'rs out there!), and invoke it like:
String output = Templates.template("templates/foo.template") .value("foo", "bar") .value("other", "val") .render();
No comments:
Post a Comment