In this post we will show how to use java 8 nashorn, a JavaScript engine developed in the Java programming language, will be used to compile, load and render a template using dustjs.
DustJS is a JavaScript templating engine designed to provide clean separation between presentation logic and isn't constrained how the data is provided to it. It is different than other java template frameworks such as velocity, freemarker, jsps and thymeleaf as it doesn't require a heavy java server running in the background. The project gained its popularity when linkedin cloned dustjs and started providing full backing and support. You can read view client side templating throwdown on their comparison between templating frameworks.
Why?
Why would you want to render a javascript template or javascript file on the JVM?
- If you have core business logic written in javascript that you need to execute and access in java.
- As application architectures progress, it is important to support application developer roles. It used to be ok to have a designer learn a templating engine and force them to use a heavy J2EE servers and tools. As the front end engineer roles continue to become prominent we need to be creative and support ways they can work with the right tools.
- Being able to render a template on the server or client side gives you flexibility. It allows you to create a site completely disconnected from the server by using mock data. This is helpful when you are trying to put together prototypes or ship off production demos.
- It allows roles to be working in parallel. While a front end developer is working on creating a production ready front end, a middle tier developer can be working on assembling or piecing together data. An important piece in this model is that roles must work together on defining a data contract.
Create Nashhorn Script Engine
In order to evaluate JavaScript code from java, you need to create a nashorn script engine by utilizing the javax.script package. By calling ScriptEngineManager.getEngineByName
we will gain reference to the nashorn ScriptEngine
. Next we will load dustjs library by using a FileReader to pass the source of the script to be executed.
Compile template
Once we load the dustjs library we need gain reference to the dust engine by calling the engine.eval("dust")
. Next we will compile a simple template to a JavaScript string that will register the template named "myphrase".
If you were to execute this with straight up JavaScript, it would look like:
Load or register template to dust context
Immediately following the compile process we will register the compiled template with the dust engine.
If you were to execute this with straight up JavaScript, it would look like:
Render template
There is a four steps to render or mesh data with the template.
Define javascript function
After compiling and registering the template with the dust engine we can render the template by defining a string that contains the JavaScript expression to execute. Calling the dust render function we will pass the template, JSON model and a call back function; where data is the rendered output from the running the template and err has any error information. Once the JavaScript function is processed we want the result to come back to java. We can do this by invoking a java method in JavaScript by passing java's StringWriter into the script context. Upon successful render the output will be sent to StringWriter.
Define data to pass to the template
Bind objects to js engine
Create a Bindings object and put elements that should be bound to nashorn.
Execute it!
Output
A verbose way to execute the following render step in JavaScript, it would look like:
All together
Gotcha
At first I defined the render script below, notice the line writer.write( data )
.
StringWriter has a few overloaded methods which I assumed by default it would call write( string )
. When running I received the error below which trigger the change to write(char[] cbuf, int off, int len)
That's it
To some it might feel unnatural calling JavaScript via Java but as I described above it can give you the flexibility to build creative solutions. In addition, I hope this post was helpful in showing how to render dustjs template using the nashorn engine.