Zippy is a minimalistic templating system. It's main use is to generate HTML for emails. It uses the template syntax of Vue.js for simplicity and familiarity.
var templateStr = "<div>{{name}}</div>";
//Compile the template. This is a one-time thing.
var template = Zippy.compile(templateStr);
//Evaluate the template.
var ctx = new HashMap<String, Object>();
ctx.put("name", "Daffy Duck");
var out = Zippy.evalAsString(template, ctx);
This will produce an output like this.
<div>Daffy Duck</div>
- Minimal external dependency.
- Rich expression language using the Apache Commons JEXL library.
- Sufficient to generate good quality dynamic HTML for emails. This may be a more lightweight choice than Thymeleaf, Velocity etc.
Add this dependency to your pom.xml
.
<dependency>
<groupId>io.github.bibhas2</groupId>
<artifactId>zippy</artifactId>
<version>1.1.2</version>
</dependency>
You can supply the template as a plain string.
var templateStr = "<div>{{name}}</div>";
//Compile the template.
var template = Zippy.compile(templateStr);
A common usage is to load a template file from the classpath.
var template = Zippy.compileResource("my-template.html");
Note that a template must be a valid XML. HTML is a relaxed form of XML. A valid HTML is not necessarily a valid XML. For example the HTML below is not a valid XML because the attribute values are not quoted.
<d id=d1 class=footer>Hello</div>
Once a template is compiled it can be evaluated many times from multiple threads. You are encouraged to compile templates only once for better performance.
To evaluate a template you must construct a context HashMap
. This map will have all the variables referred to by the expressions in the template.
var ctx = new HashMap<String, Object>();
ctx.put("firstName", "Daffy");
ctx.put("lastName", "Duck");
You can evaluate the template and obtain a result String
.
var template = Zippy.compile("<div>Hello {{firstName}} {{lastName}}.</div>");
String out = Zippy.evalAsString(template, ctx);
You can evaluate the template and obtain a result DOM Document
.
var template = Zippy.compile("<div>Hello {{firstName}} {{lastName}}.</div>");
Document out = Zippy.eval(template, ctx);
Attributes that need to show a dynamic value must be prefixed with ":". This prefix is stripped out in the output.
var templateStr = "<div><p id='para-1' :class='theClass'>Hello</p></div>";
var template = Zippy.compile(templateStr);
Map<String, Object> ctx = new HashMap<>();
ctx.put("theClass", "footer");
var out = Zippy.evalAsString(template, ctx);
This will produce an output like this.
<div>
<p id="para-1" class="footer">Hello</p>
</div>
To output dynamic data in the element body, use the {{ }}
syntax.
var templateStr = "<div><p>Hello {{name}}!</p></div>";
var template = Zippy.compile(templateStr);
Map<String, Object> ctx = new HashMap<>();
ctx.put("name", "Daffy Duck");
var out = Zippy.evalAsString(template, ctx);
This will produce an output like this.
<div>
<p>Hello Daffy Duck!</p>
</div>
To conditionally evaluate an element and all of its children use v-if
.
Example template:
<div>
<p v-if="name == 'Bugs Bunny'">Hello {{name}}!</p>
</div>
var templateStr = ...;
var template = Zippy.compile(templateStr);
Map<String, Object> ctx = new HashMap<>();
ctx.put("name", "Daffy Duck");
var out = Zippy.evalAsString(template, ctx);
This will produce an output like this.
<div>
</div>
Use v-for
to loop over a List
or array and repeatedly generate elemenets.
var templateStr = "<div><p v-for='name in nameList' :first-name='name'>Hello {{name}}</p></div>";
//Compile the template. This needs to be done only once.
var template = Zippy.compile(templateStr);
//Evaluate the template. This can be done many times.
Map<String, Object> ctx = new HashMap<>();
var nameList = Arrays.asList("Daffy", "Bugs");
ctx.put("nameList", nameList);
var out = Zippy.evalAsString(template, ctx);
This will produce an output like this.
<div>
<p first-name="Daffy">Hello Daffy</p>
<p first-name="Bugs">Hello Bugs</p>
</div>
You can use a List
or an array of objects with v-for
. Array of promitive types are not
supported.
You can use v-for
and v-if
for the same element. Example:
<html>
<body>
<div v-for="name in nameList" v-if="name == 'Daffy'">
<p>{{name}}</p>
</div>
</body>
</html>
The {{ }}
construct escapes any HTML syntax. For example, the following code:
var template = Zippy.compile("<div>{{message}}</div>");
ctx.put("message", "<h1>Hello</h1>");
System.out.println(Zippy.evalAsString(template, ctx));
Will output:
<div><h1>Hello</h1></div>
If you have dynamic HTML in a String and need to show it then use the v-html
attribute.
var template = Zippy.compile("<div v-html=\"message\"></div>");
ctx.put("message", "<h1>Hello</h1>");
System.out.println(Zippy.evalAsString(template, ctx));
This will produce:
<div><h1>Hello</h1></div>
You can insert the content from one template inside the content from another template. This is useful to create shared content used by multiple templates.
Example:
//This is the shared content
var innerTemplate = Zippy.compile("<p id='p1'>Hello</p>");
var innerDoc = Zippy.eval(innerTemplate, ctx);
//Use the shared content
var templateStr = "<div>{{greeting}}</div>";
var template = Zippy.compile(templateStr);
//You must store the shared DOM Document
//to have it inserted.
ctx.put("greeting", innerDoc);
var out = Zippy.eval(template, ctx);
This will produce the following content.
<div>
<p id="p1">Hello</p>
</div>