SLING-6680 - pom tweaks and remove @author tag that we don't use in Sling code

git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1788469 13f79535-47bb-0310-9956-ffa450edef68
2 files changed
tree: db475a550f0c56bec4d62109b6f529965af3387f
  1. src/
  2. pom.xml
  3. README.md
README.md

Apache Sling ESX Scripting Engine

A Node JS (like) module loader for Apache Sling.

Description

This module implements a Nashorn Apache Sling Script Engine for the “esx” extension.

It requires a function named render in the esx script that processes the request.

To activate this script engine you must first enable Nashorn support in the sling.properties file of your Sling instance:

jre-1.8=jdk.nashorn.api.scripting;version\="0.0.0.1_008_JavaSE"

attention

currently this implementation only works with java version “1.8.0_92” and higher

Once the bundle is active, you can try the engine with this minimal (and not very interesting) example:

First create a node with some content:

curl -u admin:admin \
  -F"sling:resourceType=foo" \
  -Ftitle="Hello ESX" \
  -Ftext="Here's some example text" \
  http://localhost:8080/apps/foo

Then create an ESX script to render it:

$ cat << EOF > /tmp/foo.esx
var foo = {
  render: function () {
    var output  = "<h1>" + currentNode.properties.title + "</h1>";             
    output += currentNode.properties.text;
    return output;     
  }
}  
module.exports = foo;
EOF

$ curl -u admin:admin -T /tmp/foo.esx http://localhost:8080/apps/foo/foo.esx

$ curl http://localhost:8080/apps/foo.html
<h1>Hello ESX</h1>Here's some example text

An ESX file is a regular java script file.

The NodeJS module resolution (https://nodejs.org/api/modules.html) is implemented to give access to the rich collection of Node modules.

There's currently no priority handling of global modules.

The engine searches for scripts in the following order, if the regular module resolution does not find a module: - /apps/esx/node_modules - /apps/esx/esx_modules - /libs/esx/node_modules - /libs/esx/esx_modules

Additionally, ESX will try to resolve the folder esx_modules prior to node_modules.

Special Loaders

Require Extensions are deprecated (see https://nodejs.org/api/globals.html#globals_require_extensions), therefore we have not implemented/used the extension loaders api and .bin extension cannot be used.

We have borrowed the requirejs loader plugin syntax instead (see http://requirejs.org/docs/api.html#text). Additionally to the standard JS loader following two loaders are existing:

  • text (e.g. require("text!./templates/header.html")))

    • will return a javascript native string containing the content of the file
  • resource (e.g. require("resource!./content/blogposts)) following will be exposed:

    • properties (resource valuemap)
    • path (jcr path)
    • simpleResource (has getChildren method with resolved simpleresoruce in an array)
    • array with list of children (simpleResource)
  • json loader (e.g. require("./dict/en.json)

    • the json as a whole will be exported as a javascript Object

Installing Demo Application

Currently the demo application is bundles with the engine bundle. To install the engine with the demo application, follow this steps:

  • switch to directory src/main/resources/libs/esx/demo
  • run: npm install
  • go back to package root directory
  • run mvn clean install sling:installĀ“

open http://localhost:8080/libs/esx/demo/content/demo.html

Writing a module

You can actually follow the NODE JS description on https://nodejs.org/api/modules.html for more detailed explanation.

A module has access to following variables:

  • __filename
  • __dirname
  • console (console.log is a log4j logger registered to the resolved module path and is not a 1:1 console.log implementation for now)
  • properties (valuemap)
  • simpleResource
  • currentNode
  • currentNode.path
  • currentNode.resource
  • currentNode.properties
  • sling (SlingScriptHelper)

Example

Caluclator Module

Path: /apps/demo/components/test/helper/calculator/index.js

function calculate(a, b) {
  return a + b;
}
exports.math = calculate;

Test components

Path: /apps/demo/components/test/test.esx

var calculator = require("./helper/calculator");

exports.render = function () {
  return calculator.math(2,2);
}