Working with the CrafterCMS Groovy Sandbox
CrafterCMS supports a powerful Groovy-based scripting layer for server side programming. CrafterCMS's configurable sandbox policies determine what the scripting layer can and cannot do. Some syntax is more likely to trigger sandbox flags than others. In this tutorial, we will offer some convenient tips to work with the Groovy Sandbox. You can also refer to this documentation on how to configure the sandbox.
Tips for coding
In the following examples, we will use a sample site that is created with the blueprint Editorial. Check this documentation on how to create a site.
Looking up a Bean by ID
We will demonstrate how to look up a bean by ID, access a request parameter, and import an external library to your script. Following beans are enabled by default without any additional configuration: https://docs.craftercms.org/en/4.0/developers/projects/engine/api/groovy-api.html#groovy-api
Here is the steps in case you want to include a bean that is not in the list:
-
Add the bean to Engine Site Application Context : In this example, we include the bean crafter.textEncryptor
-
Add a new script bean.get.groovy with the following content:
def result = [:] |
Note that we use applicationContext.getBean(“crafter.textEncryptor”) instead of applicationContext[“crafter.textEncryptor”] to get the new bean which we have included in the previous step.
Using GetBean avoids having to update the sandbox policies to allow the ["..."] syntax which can be unsafe. You can learn more about the groovy sandbox black list polices by referring to this documentation
For reference here is the policy we did not need to modify on the Groovy Sandbox Black list.
# staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods getAt java.lang.Object java.lang.String |
3. Verify the script is running correctly
curl 'http://localhost:8080/api/bean.json' \ |
{ |
Accessing a Request Parameter
Let’s take a look on how to access a parameter from HTTP GET and POST requests.
HTTP GET Request
In order to get parameters from a GET request, use `params` variable which is available by default.
Let take a look at the script `search.get.groovy`:
import org.craftercms.sites.editorial.SearchHelper |
curl 'http://localhost:8080/api/search.json?useTerm=winter&start=0&rows=2&categories%5B%5D=style' \ |
In this example, each variable has following value:
-
userTerm : winter
-
categories : style (Note that [] has been encoded to %5B%5D as a part of the URI)
-
start : 0
-
rows : 2
HTTP POST request
In order to get parameters from a POST body, we must read POST body first. The search example above can be rewrite to use POST as of following:
import org.craftercms.sites.editorial.SearchHelper |
A sample request:
curl --location --request POST 'http://localhost:8080/api/search.json' \ |
Loading Grapes
There are cases that you may want to include an external library to your Groovy script. In order to achieve this, you can use grapes annotation @Grab .
Here is an example script that load the module commons-math3 from org.apache.commons .
First, create a new script under scripts > rest with name grape.get.groovy :
@Grab (group= 'org.apache.commons' , module= 'commons-math3' , version= '3.6.1' , initClass= false ) |
Send an HTTP GET request:
curl 'http://localhost:8080/api/grape.json' \ |
You should get the result:
"15 / 28" |
Note : If your Groovy code need to use external dependencies you can use Grapes, however, when the Groovy sandbox is enabled dependencies can only be downloaded during the initial compilation and not during runtime. For this reason it is required to add an extra parameter initClass=false in the annotations to prevent them to be copied to the classes.