I create e-mails from templates via Velocity in a Spring Web Application. Now I need to HTML escape SOME of the values. I found the Velocity Escape Tool. But I did not get the configuration working.
What I have tryed so fare is (spring applicationContext.xml):
<bean id="velocityEngine" class="org.springframework.ui.velocity.VelocityEngineFactoryBean">
<property name="resourceLoaderPath" value="classpath:/velocity/emailTemplates" />
<property name="preferFileSystemAccess" value="false" />
<property name="overrideLogging" value="true" />
<property name="velocityProperties">
<util:properties>
<prop key="input.encoding">UTF-8</prop>
<prop key="output.encoding">UTF-8</prop>
<prop key="tools.toolbox">application</prop>
<prop key="tools.application.esc">org.apache.velocity.tools.generic.EscapeTool</prop>
</util:properties>
</property>
</bean>
Template (htmlEscapeTest.vm):
with escape: $esc.html($needEscape)
TestCase:
@Test
public void testHtmlEscapingSupport() {
final String needEscape = "<test>";
ModelMap model = new ModelMap();
model.addAttribute("needEscape", needEscape);
String result = VelocityEngineUtils.mergeTemplateIntoString(velocityEngine, HTML_ESCAPING_TEMPLATE_FILE, model);
assertThat(result, StringContains.containsString("<test>"));
}
But the Test failed, ...got: "with escape: $esc.html($needEscape)"
Can anybody give me a hint what I am doing wrong?
If I add new EscapeTool()
explicite in the test:
VelocityContext velocityContext = new VelocityContext(model);
velocityContext.put("esc", new EscapeTool());
StringWriter writer = new StringWriter();
velocityEngine.mergeTemplate(HTML_ESCAPING_TEMPLATE_FILE, velocityContext, writer);
String result = writer.toString();
then it is working. But as far as I understand the documentation, the tools should be configured once in the properties file.
I am using Velocity Engine 1.7 and Velocity Tools 2.0.
You can not configure the Tools directly in the VelocityEngine. What you do instead, is that when you use the VelocityEngineUtils that you pass any Tools within the model map:
ModelMap model = new ModelMap();
model.put("esc", new EscapeTool());
VelocityEngineUtils.mergeTemplateIntoString(
velocityEngine, "template.vm", "UTF-8", model)
Or if you use the VelocityEngine directly you could do:
VelocityContext velocityContext = new VelocityContext(model);
velocityEngine.mergeTemplate(templateLocation, encoding, velocityContext, writer);
Warning: I'm basing this on somewhat vague memories from a while ago. Mileage may vary.
Some of the Velocity documentation should be read from the perspective of "how do I use this in a VelocityView
?" If you want to use the same features directly from java code, then you need to change a few details. In this case, I believe that you're not creating the Context
properly. Try to follow the standalone example here, making sure that you "ask [the ToolManager] to create a context for you":
ToolManager manager = ...
Context context = manager.createContext();
Something similar probably is done under the covers for you if you use VelocityView
.
Here's some code that I just got working. I found the standard tools are set up automatically by the ToolManager.
@Autowired
private VelocityEngine velocityEngine;
public void createHtml(String templateLocation, Map<String, Object> model) throws Exception {
ToolManager toolManager = new ToolManager();
ToolContext toolContext = toolManager.createContext();
VelocityContext velocityContext = new VelocityContext(model, toolContext);
StringWriter resultWriter = new StringWriter();
velocityEngine.mergeTemplate(templateLocation, "UTF-8", velocityContext, resultWriter);
String html = resultWriter.toString();
// use the HTML here
}
And my template has this
<p>Dear $esc.html($customer.firstname)</p>
change this:
<property name="velocityProperties">
<util:properties>
<prop key="input.encoding">UTF-8</prop>
<prop key="output.encoding">UTF-8</prop>
<prop key="tools.toolbox">application</prop>
<prop key="tools.application.esc">org.apache.velocity.tools.generic.EscapeTool</prop>
</util:properties>
</property>
to:
<property name="velocityProperties">
<value>
input.encoding=UTF-8
output.encoding=UTF-8
tools.toolbox=application
tools.application.esc=org.apache.velocity.tools.generic.EscapeTool
</value>
</property>