I recently had the need to develop a Java application that allowed the creation of HTML templates that could contain some basic if-else logic as well as bind some calculated parameters. The key around this was to make the templates editable, since they contained a lot of frequently changing content.
What I found to use was the MVEL 2.0 expression language.
What is MVEL, well I think their site says it best, “MVEL is a powerful expression language for Java-based applications.”
Why MVEL?
Why did I choose MVEL, well, simply because it is fast, light weight, and did exactly what I needed it to with the ability to add in a lot more functionality down the road. For the initial phase of the project I was working on, basic if-else logic and property binding was all I needed, so this was a real easy implementation.
My Implementation
First things first, I’m assuming you know how to create a Java project and know how to add jar files to that project, etc…
Before you get too far in, you will want to download the latest MVEL version from their site, (version 2.2.0 a the time of this writing), here.
The application that I created is a GUI application that is unfortunately proprietary, so I can’t actually any of it, but the basics are that it takes some user input, processes a database or two, and then generates an html report of a sort and saves it to disk.
This is just one aspect of what you can do with MVEL and java working together. There are a lot of other possible applications, but this implementation worked really well for me.
MVEL Template Syntax
MVEL uses a Java-like syntax, so a lot will be very familiar in one respect or another. So all of your operators and other math and control functionality will look familiar, but where things start to diverge a little is when you start in on the templating functionality of MVEL.
In a template setup, MVEL code is wrapped in @{ }
containers. So for example, you could display a persons name using something like @{name}
. And for an if statement, something like this can be used @if{my_value > 0} ... @end{}
.
You can find some more detail on MVEL templating syntax, here. But for now I’m going to jump right in to what I created.
My Template Files
I created all of my templates in .html files (since this application basically spits out HTML).
To do this I created a file, and just added the html and MVEL template code that I needed.
Sample template.html file.
<div class="row"> <div class="col-md-12"> <h1>@{title}</h1> <p>@{content}</p> </div> </div>
This is a very simple MVEL template that has two rendered properties, the @{title}
and @{content}
. In these cases, the values passed will simply be inserted into the html. These properties are set using code that I will get into more detail on below.
Processing the Templates
Now that you have your template file, processing it can be a bit of a drag, but I created some simple helper functions to make it easy (I had to process quite a few different templates and then combine them).
First I created a simple function to read the template from the file:
public static String readTemplate(String fileName) throws IOException { InputStream tStream = ReportBuilder.class.getClass().getResourceAsStream(fileName); Scanner tScanner = new Scanner(tStream); String template = tScanner.useDelimiter("\\Z").next(); tScanner.close(); tStream.close(); return template; }
Then using that code, I was able to create a function that wrapped it all together and passed in a Map
of values that are passed to the MVEL rendering code.
public static String readTemplate(String fileName, Map<String, Object> params) throws IOException { // Read the template file String template = readTemplate(fileName); // Render the template CompiledTemplate t = TemplateCompiler.compileTemplate(template); // Execute the template with parameters, as needed. if(params.isEmpty()) { template = (String)TemplateRuntime.execute(t); } else { template = (String)TemplateRuntime.execute(t, params); } return template; }
So now that we have that code, we can use it in as many places as we need to… Using our template as an example:
Map<String, Object> valueMap = new HashMap<String, Object>(); String title = "Test Template"; String content = "Template content!"; valueMap.put("title", title); valueMap.put("content", content); String sOut = readTemplate("template.html", valueMap);
If everything works, sOut
would contain the contents of the rendered template. All of the mapped parameters would be populated, the logic would be run, etc.
Once you have that you can perform other operations on the data directly in Java, or write the data to a file, or send it to a server, or … whatever else you can think of.
Templates with MVEL are as simple as that, there is a lot of functionality that I didn’t cover, this is just something to get you started.
You can find some more resources on more advanced templating using “orb tags”, here. This includes some more details on if-else statements, silent code tags, foreach loops, etc.
Any questions, comments, concerns? Leave them in the comments below and I’ll do my best to get back to you in a timely manner!