Script Macro

Last modified by Alex Cotiugă on 2024/07/05 18:05

cogExecutes a script implementing the Java Scripting API (JSR-223)
TypeJAR
Category
Developed by

XWiki Development Team

Rating
0 Votes
LicenseGNU Lesser General Public License 2.1
Bundled With

XWiki Standard

Description

Executes a script implementing the JSR-223 API.

The following macros wrap this generic script macro for a specific language:

Usage

{{script language="<script engine name>"}}
<some code written in the corresponding language>
{{/script}}

By default the "xwiki" and "xcontext" variables are bound and respectively represent a XWiki and Context API objects. See below for the full list of bindings.

Parameters definition

NameOptionalAllowed valuesDefault valueDescriptionSince version
languageyesthe identifier of the JSR 223 engine Indicate which engine to use to execute the provided script 
outputyestrue/falsetrueIndicate the output result has to be inserted back in the document1.8.1, 1.9M1
wikiyestrue/falsetrueIndicates whether the macro content will be considered as wiki syntax or not2.0 M1
jarsyescomma-separated list of JARs that will be added to the script execution class loadernonesee below2.0RC1

Specifying extra JARs

If you have programming rights, it's possible to add JARs that will be available to the script's execution by using the jars parameters. The format is a comma-separated list of entries of the following types:

  • a URL of the type http://server/path/to/some.jar
  • a reference to a JAR attachment on the current page: attach:some.jar
  • a reference to a JAR attachment located on another page: attach:wiki:space.page@some.jar
  • a reference to all jars located on a give page: attach:wiki:space.page

Bindings

Here are some of the important bindings/variables which are automatically provided: 

NameClassDescription
xwikicom.xpn.xwiki.api.XWikiUtility APIs
xcontextcom.xpn.xwiki.api.ContextContains contextual informations
requestcom.xpn.xwiki.web.XWikiRequestThe servlet request. Generaly used to get URL parameters.
responsecom.xpn.xwiki.web.XWikiResponseThe servlet response
doccom.xpn.xwiki.api.DocumentThe current document

Return

There are two ways to display the content returned by the Script Macro:

  • By writing the content to return into a binding. The binding to use depends on the Scripting Engine used. For example for Groovy:
    {{groovy}}
    out.print('something')
    {{/groovy}}
  • By just returning the value (needs XWiki 2.4M2+)
    • Before XWiki 7.1M1 Returned values of type XDOM, Block or List of Block are supported.

      That allow to cover some use case where you already have the block (you got from a parsing for example) and want to insert them into the document or when you want to do safest escaping possible.

      The way to return a value from a script totally depends on the language and the engine used. Note that this is available only for JSR 223 based macro for now which mean pretty much all macros except velocity one.

      Here is an example with groovy macro:

      {{groovy}}
      return java.util.Arrays.asList(new org.xwiki.rendering.block.WordBlock("Hello"), org.xwiki.rendering.block.SpaceBlock.SPACE_BLOCK, new org.xwiki.rendering.block.WordBlock("world"));
      {{/groovy}}
    • XWiki 7.1M1+, other types of returned values are also supported and will be converted to String and displayed if no content has been written using the binding method described above. Otherwise, the value returned through the binding will be used instead. For example:

      In Groovy:

      {{groovy}}
      1+2
      {{/groovy}}

      In Javascript:

      {{script language="javascript"}}
      1+2
      {{/script}}

Nested scripts

Since XWiki 2.4M2 it is no longer possible to directly nest script macros inside each other. For example, this would NOT work any more:

{{velocity}}
#set($data = "test")

## nested groovy, forbidden!
{{groovy}}
println("$data");
{{/groovy}}

{{/velocity}}

Nested scripts present a serious security risk, because they can be used to bypass security checks. We strongly advise to write your scripts so that the data is passed through variables. If you really need the old behavior, you can remove NestedScriptMacroValidator from components.txt in xwiki-rendering-macro-script component.

Rights

Since XWiki 7.2M1 it is now possible to specify which users are allowed or not allowed to execute the scripts they have written. To do so, you can use the Script right for a user or a group or users on the wiki/space/page you are interested restricting or allowing.

Depending on the type of script you are trying to execute, other additional rights may be needed besides Script rights. The current/default requirements are:

  • Velocity - Script right
  • Groovy - Programming Rights (by default). However, if a secure Customizer is configured and active, only Script rights are needed.
  • others - Programming Rights

Note: The Script right, just like the Programming right are checked on the content author of the document containing the script and not the context user that is currently trying to run it. In other words, the author of a script needs to have the proper rights for the script to be executable by anyone viewing it.

For custom script macro permissions, a new MacroPermissionPolicy java component can be implemented for the macro in question.

Example

{{script language=groovy}}
def list = ["one", "two"]
list.each { item ->
  println "* ${item}"
}
{{/script}}

Result

  • one
  • two

Get Connected