Javascript Models

This module is a Beta module. The existing Magnolia Bundle comes packaged with Javascript Models 1.2.

Edition CE

License

MLA, GPL

Issues

Git

Git

Maven site

Latest

2.0-beta1

Compatible with Magnolia 6.2.17.

The Magnolia Javascript Models module allows developers to build JavaScript functionality that executes on the server. This could only be done using Java code, and required complex deployment configurations. This version of Javascript Models allows the ability to develop and use models written in Javascript.

Now, you can write your business logic, save it, and see it in action immediately. No more downtime to your authors, and more importantly, to your customers.

Another awesome bonus is that now, with Magnolia’s Javascript Models v2, you are no longer limited to using Java 14 and below. You can now use the latest and greatest JDK.

This version (2.0-beta1) does not work with early versions of the JDK.

Installing with Maven

Maven is the easiest way to install the module. Add the following to your bundle:

javascript-models
<dependency>
  <groupId>info.magnolia.javascript-models</groupId>
  <artifactId>magnolia-module-javascript-models</artifactId>
  <version>2.0-beta1</version>
</dependency>

Your Maven build may include the original Javascript Models 1.2 module until v2 is officially released. In order to prevent this from happening, you can simply exclude the old version from your Webapp’s POM file under dependencies, like this:

your-webapp-maven-project/pom.xml
<project>
  ...
  <dependencies>
    <dependency>
      <groupId>info.magnolia.bundle</groupId>
      <artifactId>magnolia-community-webapp</artifactId>
      <type>war</type>
      <exclusions>
        <exclusion>
          <groupId>info.magnolia.javascript-models</groupId>
          <artifactId>magnolia-module-javascript-models</artifactId>
        </exclusion>
      </exclusions>
    </dependency>

Installing to a Bundle

If you have an existing bundle, perhaps obtained by using the Magnolia CLI, you will need to add the Javascript Models 2.0 module, as well as its dependencies to each webapps /WEB-INF/lib directories:

Using a standard Magnolia Bundle, these directories would be:

  • apache-tomcat/webapps/magnoliaAuthor/WEB-INF/lib/

  • apache-tomcat/webapps/magnoliaPublic/WEB-INF/lib/

Configuration

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.

Default available objects

Without any configuration, the following objects are available in all models:

  • content

  • parent

  • root

  • def

  • ctx

  • state

  • i18n

  • log

For more information, see Rendering context objects.

Exposing components

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:

image

Property Description

exposedComponents

optional

The exposed components' configuration node can be omitted.

     <object-name>

required

An arbitrary name of an exposed object

         name

required

The name of the object which will be used to reference it.

         componentClass

required

A fully qualified class name of the exposed object.

Class filter

The class filter is one of the options with which you can limit access to the Java API.

image

Within the /modules/javascript-models/config/engineConfiguration, simply create the classFilter content node, adding a separate node with a property type with the fully qualified class path for each class you wish to allow.

GraalVM engine options

Use the engineConfiguration to configure the options passed to GraalVM when it is initialized.

For a full list of Engine Options that you can configure, see the Context Builder API.

image

Usage

Below you can find a simple example with a template definition, a JavaScript Model class 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.

Template definition

/js-test/templates/pages/rhino.yaml
title: Rhino
class: info.magnolia.module.jsmodels.rendering.ConfiguredJavascriptTemplateDefinition (1)
templateScript: /js-test/templates/pages/rhino.ftl
renderType: freemarker
modelClass: info.magnolia.module.jsmodels.rendering.JavascriptRenderingModel (2)
modelPath: /js-test/templates/another-location/rhino.js (3)
parameters: (4)
  myBoolParam: true
  myIntParam: 10
Property Description

class

Required

The class must be info.magnolia.module.jsmodels.rendering.ConfiguredJavascriptTemplateDefinition or a class that extends it.

modelClass

Required

The value must be info.magnolia.module.jsmodels.rendering.JavascriptRenderingModel.

When omitting 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.

Please also read Template definition to learn more information about the other properties.

modelPath

If the path does not match the name of the template, as specified above, you will need to declare the path to the Javascript class here. This is the resources path reference.

parameters

This is a free-form set of parameters that you can use within your Javascript class that would look like this:

var Dumbo = function () {
    this.getMyInt = function () {
        return this.parameters.myIntParam;
    }
};
new Dumbo();

Model class

The JavaScript model file must define a JS class which can contain properties and methods.

/js-test/templates/pages/rhino.js
var Dumbo = function () {
    this.getRandomNumber = function () {
        return Math.random();
    }
};
new Dumbo(); (1)
1 At the end of the file you must create an instance!

You should understand the difference of when to use this, and when not to. Simply, if you are accessing something within the context of your Javascript class, you use this. If you are accessing and exposedComponent, you do not.

In Default available objects, those variables are within the context of your Javascript code. Things defined in config under exposedComponents are global. Here is an example:

var Dumbo = function () {
    this.getRandomNumber = function () {
        this.log.info('Getting a Random Number'); (1)
        cmsfn.getContentById(id); (2)
        return Math.random();
    }
};
new Dumbo();
1 log is within the context of the Javascript object.
2 cmsfn is exposed as a global object.

Template script

In the template script, reference the model object with model.

/js-test/templates/pages/rhino.ftl
<div>Here you have a random number: ${model.getRandomNumber()}</div>

Cache

In order to interpret JavaScript, GraalVM 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).

Samples

A few samples can be found in our Bitbucket repo.

Currently, you will need to check out the branch JSMODELS-24 with Javascript Models 2.0.

cd javascript-model-samples
git checkout JSMODELS-24

If using the Magnolia Bundle provided by the Magnolia CLI’s Jumpstart, you will also need to download and add MTK 2.0.2 JAR to your webapps /WEB-INF/lib directories.

Feedback