Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Table of Contents
| §§ Exercise: JavaScript Models |





The Java 8 release included a JavaScript engine called Nashorn.  Nashorn allows us to run dynamic JavaScript code natively on the JVM.


Prerequisites


  • Java 8
  • Magnolia 5.5+


What you need to do


  • in your YAML template: modelClass property pointing to info.magnolia.module.jsmodels.rendering.JavascriptRenderingModel (required)
  • in your YAML template: modelPath property pointing to where you have stored the JavaScript code (optional - useful for model re-use among different templates).  If you don't do this, the system will look for a file with the same name as your template, only with a .js extension.


What Magnolia provides



Those classes allow invoking of methods and property access on our JavaScript objects.  We can limit this behavior in a couple of ways:



Example


Code Block
languageyaml
titleadd this to your webapp pom
<dependency>
  <groupId>info.magnolia.javascript-models</groupId>
  <artifactId>magnolia-module-javascript-models</artifactId>
  <version>1.0-SNAPSHOT</version>
</dependency>

If you are using M 5.6.*, try this instead:

Code Block
<dependency>
  <groupId>info.magnolia.javascript-models</groupId>
  <artifactId>magnolia-module-javascript-models</artifactId>
  <version>1.1.1</version>
</dependency>


If your bundle doesn't already include it, and if you are unable to include this, the jar file is attached: magnolia-module-javascript-models-1.0.jar Simply drop it in your author instance WEB-INF/lib and restart Magnolia.  Otherwise, you could download it from here.




Code Block
languageyaml
titlenew-module/templates/components/contacts.yaml
templateScript: /new-module/templates/components/contacts.ftl
renderType: freemarker
modelClass: info.magnolia.module.jsmodels.rendering.JavascriptRenderingModel




Code Block
languageyaml
titlenew-module/templates/components/contacts.ftl
[#assign allContacts = model.getContacts()]
 
<ul>
[#list allContacts as contact]
    <li>${model.format(contact)}</li>
[/#list]
</ul>




Code Block
languagejs
titlenew-module/templates/components/contacts.js
var MyModel = function () {
 
    this.getContacts = function () {
        var result = new Array();
        var nodes = ctx.getJCRSession("contacts").getRootNode().getNodes();
        while (nodes.hasNext()) {
            node = nodes.next();
            if (node.getPrimaryNodeType().getName() == 'mgnl:contact') {
                result.push(node);
            }
        }
        return result;
    };
 
    this.format = function (contact) {
        return contact.getProperty("firstName").getString() + ' ' + contact.getProperty("lastName").getString();
    };
};
 
new MyModel();




Code Block
languageyaml
titleadd this to the availableComponents of some area definition
      contacts:
        id: new-module:components/contacts


The result


Image Added


Nashorn - Pros and Cons


Pros:


  • No need to know Java to implement models
  • May inject and use any Java class into the JavasScript model


  • Front-end developers may load external libraries in their model and use them (see load function here)
  • The models work immediately (no need to compile/restart/etc) - they use Magnolia's resource-loader API


Cons:


  • Front-end developers will need Javadoc for Node APIs
  • Model inheritance is not possible in JavaScript
  • Maybe JavaScript models are slower than Java models




Page Turner
button-linkstrue








This page originally adapted from here.


The main Magnolia documentation for this topic is JavaScript Models module.


Some more examples may be found here.





Page Turner
button-linkstrue