1.  Create a REST client component definition:

    /rewe/templates/components/jokes.yaml

    title: Jokes Client
    templateScript: /rewe/templates/components/jokes.ftl
    #modelPath: /rewe/templates/components/jokes.js
    renderType: freemarker
    class: info.magnolia.module.jsmodels.rendering.JavascriptTemplateDefinition

    This property is class not modelClass ... if you use the latter, you will get a class cast exception.

  2.  Create a REST client component script:

    /rewe/templates/components/jokes.ftl

    [#assign posts = model.getPosts()!]
    [#assign data = {"title": "bar", "body": "hello", "userId": 1}]
    [#assign newPost = model.createPost(data)!]
    
    <div class="row">
        <div class="col-md-12">
            <h2>All posts:</h2>
            [#list posts as post]
                <h3>${post.title!}</h3>
                <p>${post.body!}</p>
                <hr/>
            [/#list]
            <h2>New post created:</h2>
            <h3>${newPost.title!}</h3>
            <p>${newPost.body!}</p>
        </div>
    </div>
  3.  Now add the Javascript Model:

    /rewe/templates/components/jokes.js

    // load rest client lib
    loadScript("/rewe/templates/js/restClient.js");
    
    /**
     * Javascript model.
     *
     * @constructor
     */
    var Model = function () {
    
        /**
         * See https://jsonplaceholder.typicode.com/
         *
         * @type {string}
         */
        var baseUrl = "https://jsonplaceholder.typicode.com";
    
        var restClient = new RestClient();
    
        /**
         * Returns all posts from the JSON Placeholder service.
         *
         * @returns {JSON object}
         */
        this.getPosts = function () {
            return JSON.parse(restClient.get(baseUrl + "/posts"));
        };
    
        /**
         * Creates new post in the JSON Placeholder service.
         *
         * @param data
         * @returns {JSON object}
         */
        this.createPost = function (data) {
            return JSON.parse(restClient.post(baseUrl + "/posts", data));
        };
    }
    
    new Model();
  4.  Add the REST client javascript:

    /rewe/templates/js/restClient.js

    /**
     * Simple implementation of REST library. Since Nashorn doesn't support XMLHttpRequest, it's implemented using
     * Apache HTTP client.
     *
     * Be aware that this implementation of http requests is synchronous.
     * Using these methods could have negative performance implications for your site.
     *
     * Consider making http requests from the client side if possible.
     * Consider a more sophisticated implementation in Java with caching, buffering requests, etc.
     *
     * @constructor
     */
    var RestClient = function () {
    
        var HttpClients = Java.type("org.apache.http.impl.client.HttpClients");
        var HttpGet = Java.type("org.apache.http.client.methods.HttpGet");
        var HttpPost = Java.type("org.apache.http.client.methods.HttpPost");
    
        var ArrayList = Java.type("java.util.ArrayList");
        var UrlEncodedFormEntity = Java.type("org.apache.http.client.entity.UrlEncodedFormEntity");
        var BasicNameValuePair = Java.type("org.apache.http.message.BasicNameValuePair");
        var EntityUtils = Java.type("org.apache.http.util.EntityUtils");
    
        this.get = function (url) {
            var httpClient = HttpClients.createDefault();
            var httpGet = new HttpGet(url);
            var response = httpClient.execute(httpGet);
    
            try {
                entity = response.getEntity();
                return EntityUtils.toString(entity, "utf-8");
            } finally {
                response.close();
            }
        }
    
        this.post = function (url, params) {
            var httpClient = HttpClients.createDefault();
            var httpPost = new HttpPost(url);
            var data = new ArrayList();
    
            for (var key in params) {
                data.add(new BasicNameValuePair(key, params[key]));
            }
    
            httpPost.setEntity(new UrlEncodedFormEntity(data));
            response = httpClient.execute(httpPost);
    
            try {
                entity = response.getEntity();
                return EntityUtils.toString(entity, "utf-8");
            } finally {
                response.close();
            }
        }
    }
  5.  Make that component available on some page, then add it:

    ~/Desktop/REWE/__DAY__TWO__/daytwo/light_modules/rewe\-> vi ../symlinktest/templates/pages/symlinky.yaml
    ~/Desktop/REWE/__DAY__TWO__/daytwo/light_modules/rewe\-> tail -n 2 ../symlinktest/templates/pages/symlinky.yaml
          jokes:
            id: rewe:components/jokes
    ~/Desktop/REWE/__DAY__TWO__/daytwo/light_modules/rewe\->



  6. If something fails to work at this point, you might be missing the JavaScript Models module ... install it by adding the following to your webapp pom:

    <dependency>
      <groupId>info.magnolia.javascript-models</groupId>
      <artifactId>magnolia-module-javascript-models</artifactId>
      <version>1.1.1</version>
    </dependency>
  7. If you still can't get it to work, simple download http://pvnp.us/REWE/javascript-model-samples.tgz, and unpackage it into your light-modules directory.  Make sure you make the service available on your page template:

    rest:
      id: javascript-model-samples:components/rest
  8. Try it out - add a rest component to your symlinky page:




  • No labels

2 Comments

  1. You could do other / more things with the Jokes Client.  For example, if the API we are calling has different methods available; or, we can use restfn to parse the results further - we don't need to collect all the entries.  We could even decorate the rendering module to point to a different Java class which overrides restfn and adds functionality.