I'm currently trying to use the lodash template engine in Java using nashorn and I'm facing an issue.
Here's the code :
ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine nashorn = mgr.getEngineByName("nashorn");
ScriptContext ctx = nashorn.getContext();
Bindings bindings = ctx.getBindings(ScriptContext.ENGINE_SCOPE);
nashorn.eval(readFileToString("externallibs/lodash.min.js"), bindings);
String tpl = readFileToString("hello.tpl");
bindings.put("tpl", tpl);
nashorn.eval("compiled = _.template(tpl);", bindings);
ScriptObjectMirror compiled = (ScriptObjectMirror)nashorn.get("compiled");
System.out.println("compiled = " + compiled);
Map<String, String> props = new HashMap<String, String(1);
props.put("name", "world");
bindings.put("props", props);
System.out.println(compiled.call(this, bindings.get("props"));
The template is well compiled by Nashorn, if you look at the console you'll see :
compiled = function(obj){obj||(obj={});var __t,__p='';with(obj){__p+='Hello, '+((__t=( name ))==null?'':__t);}return __p}
But when I'm trying to call the compiled template function above with a map as parameter (the props), as you would do in JS :
tpl.call(this, {name:'world'})
It fails with the following error :
TypeError: Cannot apply "with" to non script object
And indeed, we can see that the compiled version of the function uses the 'with' keyword.
Does anyone have an idea on how to workaround this issue ? How should I send the parameters to render the compiled template ?
Thanks a lot for any help.
You need to pass a JS script object to "with" statement. Arbitrary Java object (which is not a JS object - say a java.util.Vector or object of your class Foo) can not be used as "with" expression. You could create an empty script using code like
and pass emptyScriptObj to your ScriptObjectMirror.call method call for example.