Extensions :: Script Invoker

Disclaimer: This extension depends on a working JSR 223 environment as provided in Java 6 and newer.

Reference

ScriptInvoker is a 'source-class' compatible helper class providing a runtime environment that allows to load and execute script code using the JSR-223 interface (scripting for java).

Scripts can provide input for velocity templates or they can produce content directly. When invoked, this extension first populates all given macro parameters within the script context, evaluates the script and copies any changes or newly allocated variables back into the original parameters map. When an additional source was specified these resulting parameters are available in the template via $paramName.
Any text output that is produced by scripts is set into "source-content" and is displayed when no source is given.

The following global variables are exposed in the script context, in addition to the standard template parameters:
  • "globals" points to an instance of "Globals" which allows to access base path, path resolution logic, loading & attaching content, etc.
  • "scriptName" is a string that is filled with the absolute path to the script file.

This extension is only useful when JSR-223 is available. Starting from Java 6, JavaScript is the only script engine that is available by default. Adding other script engines to the dependency set of module or site-plugin enables scripting languages like: Groovy, Ruby, Python and others that offer integration with JSR-223.

Usage:
%{include|source=template.vm|source-class=org.tinyjee.maven.dim.extensions.ScriptInvoker|script=my-script.js}
%{include|source-class=org.tinyjee.maven.dim.extensions.ScriptInvoker|script=my-script.js}
or when using the alias:
%{include|source=template.vm|source-script=my-script.js}
%{include|source-script=my-script.js}

Notes:
  • Under normal circumstances it is preferable to create your own 'source-class' compatible helper class using Java as it adds unit testing and compiler checks. Scripting however, when combined with "site:run" allows to create content with scripts very quickly as no additional compilation step is needed to see live changes to the site.
  • Scripts run in a request scope with global bindings (global variables) being shared amongst executions and script engines. Whether this has an effect on the scripts depends on the implementation of the script interpreter and the language itself.

Parameters:

Parameter Name Description
Input Parameters (set with the macro call)
"source-script" Defines a shortcut for the request properties 'source-class' and 'script'.

If this parameter is present inside the request parameters list, the system will effectively behave as if 'source-class' and 'script' where set separately.
"script" Sets the URL or local path to the script file to load and evaluate.

The specified file is resolved in exactly the same way as when using the parameter "source" (see Macro reference).

Notes:
  • In addition to setting a file path, the parameter can be used to define an inline script snippet using the syntax "eval[type]:script...". E.g. for javascript this looks like %{include|source-script=eval[js]:print("Hello World");}.
  • When no further source is specified, any text output produced by the script (e.g. via print "some text") is included into the current page. STDERR is always sent to both locations, the build logs and the page. Unhandled script errors will break the build.
  • As velocity template processing is applied at a later stage, the script output is processed by velocity unless the parameter "source-is-template" is set to false or another "source" was specified. Thus a script can dynamically generate a velocity template and provide the parameters for the template context (though this might be kind of a overkill).
Implementation "org.tinyjee.maven.dim.extensions.ScriptInvoker": ApiDoc | Source

Usage Examples

JavaScript

Inline Script
%{include|source-script=eval[js]:println("Hello World 1");}
Hello World 1
%{include|source-content=$out|source-script=eval[js]:var out\="Hello World 2";}
Hello World 2

Note: The use of inline scripts in combination with APT is limited as "{}|=" are special characters that require escaping. The script in the example above wouldn't work as expected without the backslash in front of "=".

Script File - 'samples/test-content-script.js'
1
2
print("Hello World - printed from JavaScript (output-is-HTML: " + globals.HTMLCapableSink + ")");
var out = "Hello World - set to 'out' by JavaScript";
%{include|source-script=samples/test-content-script.js}
Hello World - printed from JavaScript (output-is-HTML: true)
%{include|source-content=$out|source-script=samples/test-content-script.js}
Hello World - set to 'out' by JavaScript

Groovy

Setup
134
135
136
137
138
153
154
155
156
157
<dependency>
    <groupId>org.codehaus.groovy</groupId>
    <artifactId>groovy</artifactId>
    <version>1.8.6</version>
</dependency>
<dependency>
    <groupId>org.tinyjee.dim</groupId>
    <artifactId>doxia-include-macro</artifactId>
    <version>${project.version}</version>
</dependency>
Hello World
%{include|source-script=eval[groovy]:println "Hello World in Groovy (output-is-HTML: " + globals.HTMLCapableSink + ")";}
Hello World in Groovy (output-is-HTML: true)

Ruby

Setup
140
141
142
143
144
153
154
155
156
157
<dependency>
    <groupId>org.jruby</groupId>
    <artifactId>jruby</artifactId>
    <version>1.6.6</version>
</dependency>
<dependency>
    <groupId>org.tinyjee.dim</groupId>
    <artifactId>doxia-include-macro</artifactId>
    <version>${project.version}</version>
</dependency>
Hello World
%{include|source-script=eval[rb]:puts 'Hello World in Ruby (output-is-HTML: ' + $globals.isHTMLCapableSink().to_s + ')';}
Hello World in Ruby (output-is-HTML: true)

Python

Setup
146
147
148
149
150
153
154
155
156
157
<dependency>
    <groupId>org.python</groupId>
    <artifactId>jython-standalone</artifactId>
    <version>2.5.2</version>
</dependency>
<dependency>
    <groupId>org.tinyjee.dim</groupId>
    <artifactId>doxia-include-macro</artifactId>
    <version>${project.version}</version>
</dependency>
Hello World
%{include|source-script=eval[py]:print "Hello World in Python (output-is-HTML: " + str(globals.HTMLCapableSink) + ")"}
Hello World in Python (output-is-HTML: True)