Magnolia 5.6 reached end of life on June 25, 2020. This branch is no longer supported, see End-of-life policy.
The JavaScript Models module adds the ability to develop and use models written in JavaScript. JavaScript Models can be done via Light development, enabling fast development and deployment without the need for Java, Maven or WAR deployment. JavaScript Models represent a type of Magnolia Resources.
This module requires Java 8 (support for Nashorn).
Java 8 brought in support for a JavaScript engine called Nashorn, which can interpret Javascript code in a Java application. Nashorn currently follows edition 5.1 of the ECMAScript specification, but edition 6 is planned to be supported in future releases. For more information see the Further reading section.
Since the release of Magnolia 5.5.6, the JavaScript Models module is bundled with the magnolia-community-webapp
. All the other webapps and bundles inherit the module from this webapp (see also preconfigured Magnolia bundles and webapps.).
<dependency> <groupId>info.magnolia.javascript-models</groupId> <artifactId>magnolia-module-javascript-models</artifactId> <version>2.0</version> </dependency>
The JavaScript Models module can be configured in Configuration > /modules/javascript-models
in order to:
However, there is little need for any configuration since the module provides helpful rendering context objects out of the box.
Without any configuration, the following objects are available in all models:
content
def
ctx
state
i18n
Learn more about these objects on Rendering context objects.
You can expose (custom) components to the models in the module's configuration. A typical use case is adding Templating functions. If you want to use cmsfn
, you have to configure it under exposedComponents
:
Node name | Value |
---|---|
modules | |
javascript-models | |
config | |
engineConfiguration | |
exposedComponents | |
cmsfn | |
name | cmsfn |
componentClass | info.magnolia.templating.functions.TemplatingFunctions |
Properties:
| optional The exposed components configuration node can be omitted. |
| required An arbitrary name of an exposed object |
| required The name of the object which will be used to reference it. |
| required A fully qualified class name of the exposed object. |
The class filter is one of the options with which you can limit the access to the Java API.
Node name | Value |
---|---|
config | |
engineConfiguration | |
classFilter | |
class | com.example.MyCustomClassFilterImpl |
The value of the class
property has to be a fully qualified class name of the class implementing
jdk.nashorn.api.scripting.ClassFilter
.
Use the engineOptions
to configure the options passed to Nashorn when it is initialized.
Fo instance, you can limit the access to Java API by disabling Nashorn extensions or by implementing a ClassFilter.
Node name | Value |
---|---|
config | |
engineConfiguration | |
engineOptions | |
--no-java | --no-java |
--no-syntax-extensions | --no-syntax-extensions |
Properties:
| optional The engine options configuration node can be omitted. |
| required An arbitrary name of an exposed object |
| required The name of the object which will be used to reference it. |
| required A fully qualified class name of the exposed object. |
Example engine options:
Option | Meaning |
---|---|
--no-java | Turns off Java specific syntax extensions like "Java", "Packages", etc. |
--no-syntax-extensions | Only standard ECMAScript syntax is supported. |
Below you can find a simple example with a template definition, a JavaScript Model class and and a FreeMarker template script. For further explanations, please read also How to work with JavaScript models or study the sample code provided on Bitbucket.
title: Rhino templateScript: /js-test/templates/pages/rhino.ftl renderType: freemarker modelClass: info.magnolia.module.jsmodels.rendering.JavascriptRenderingModel #class: info.magnolia.module.jsmodels.rendering.JavascriptTemplateDefinition #modelPath: /js-test/templates/another-location/rhino.js
modelClass | Required The value must be |
When omitting class
and modelPath
, the system expects the model file to be in the same location as the template definition, the expected name is <template-name>.js
. See How to work with JavaScript models - Defining and referencing.
Please also read Template definition to learn more information about the other properties.
The JavaScript model file must define a JS class which can contain properties and methods.
var Dumbo = function () { this.getRandomNumber = function () { return Math.random(); } }; new Dumbo();
In the template script, reference the model object with model
.
<div>Here you have a random number: ${model.getRandomNumber()}</div>
In order to interpret JavaScript, Nashorn creates a compiled version of a JS model. For performance reasons, Magnolia is caching the compiled scripts. Cache entries are flushed based on the lastModified
timestamp. Changes are detected by Magnolia's Resources observation mechanism.
The JavaScript model cache is enabled by default but it can be disabled by setting the Magnolia property magnolia.develop
to true
(see Configuration management - Properties).
A few samples can be found on our Bitbucket.
4 Comments
Fadi Wissa
Great module, but I have a very basic question as I get started; how can I debug scripts?
Any errors completely break the model but I'm not able to get mode details about the exact error.
Christoph Meier
Hi
My first advice is: Look carefully at the log when an error happens - this already helps in many cases.
And: you could try this: https://blogs.oracle.com/sundararajan/remote-debugging-of-nashorn-scripts-with-netbeans-ide-using-debugger-statements ... actually there is a way to debug the Nashorn scripts, but I have never tried it out.
Cheers,
Christoph
Fadi Wissa
Thanks Christoph Meier
I used a "try/catch" and added the error.message to the model to be able to print it out in the associated template (ftl).
It turned out that the javascript dependency I was using uses the "window" object which does not exist in nashorn; so I won't use JavaScript models at this point - though they're very convenient.
Christoph Meier
Since Nashorn is executed on the server side - for sure it cannot print log messages in your browser.
But you can use something like
System.out.println("foobar")
to add messages to your magnolia log file.(shrug)