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>You can group a number of elements inside a <template> tag. Then, apply v-for or v-if to that tag. The <template> tag itself is not added to the output document. This avoids the need to use an unnecessary <div> tag to group elements.
Example:
<div>
<template v-for="p in productList">
<p>{{p.name}}</p>
<p>{{p.price}}</p>
</template>
</div>This will output something like:
<div>
<p>Baseball Bat</p>
<p>$93.88$</p>
<p>Basketball</p>
<p>$16.93$</p>
</div>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>