• Document Up to Date
  • Updated On 4.1.8

Page and Component Controllers

Crafter pages and components can have their own controller scripts too, that are executed before the page or component is rendered, and that can contribute to the model of the template. These scripts, besides the common variables, have the templateModel and the contentModel available.

Model Related Variable
Description
contentModel

The XML descriptor content
It is an instance of the SiteItem class
templateModel

The actual map model of the template
It is an instance of the AllHttpScopesAndAppContextHashModel class

The templateModel is the actual map model of the template, and any variable put in it will be accessible directly in the template, eg. if the script has the line templateModel.var = 5, then in the template the var’s value can be printed with ${var}. The contentModel is the XML descriptor content, of type SiteItem. The scripts don’t have to return any result, just populate the templateModel.

There are 2 ways in which you can “bind” a script to a page or component:

  1. Put the script under Scripts > pages or Scripts > components, and name it after the page or component content type.

  2. When creating the content type for the page or component, add an Item Selector with the variable name scripts. Later when creating a page or component of that type, you can select multiple scripts that will be associated to the page or component.

The following is an example of a component script. The component content type is /component/upcoming-events. We can then place the script in Scripts > components > upcoming-events.groovy so that it is executed for all components of that type.

 1import org.craftercms.engine.service.context.SiteContext
 2import utils.DateUtils
 3import org.opensearch.client.opensearch.core.SearchRequest
 4import org.craftercms.search.opensearch.client.OpenSearchClientWrapper
 5import org.opensearch.client.opensearch._types.SortOrder
 6
 7def now = DateUtils.formatDateAsIso(new Date())
 8def q = "crafterSite:\"${siteContext.siteName}\" AND content-type:\"/component/event\" AND disabled:\"false\" AND date_dt:[${now} TO *]"
 9def start = 0
10def rows = 1000
11def events = []
12
13// Execute the query
14def result = searchClient.search(r -> r
15  .query(q -> q
16    .queryString(s -> s
17      .query(q as String)
18    )
19  )
20  .source(s -> s
21    .filter(f -> f
22      .includes('localId')
23    )
24  )
25  .from(start)
26  .size(rows)
27  .sort(s -> s
28    .field(f -> f
29      .field(date_dt)
30      .order(SortOrder.Asc)
31    )
32  )
33, Map)
34
35result.hits().hits().each {
36  def event = [:]
37  def item = siteItemService.getSiteItem(it.source())
38
39  event.image = item.image.text
40  event.title = item.title_s.text
41  event.date = DateUtils.parseModelValue(item.date_dt.text)
42  event.summary = item.summary_html.text
43
44  events.add(event)
45}
46
47templateModel.events = events

You might notice that we’re importing a utils.DateUtils class. This class is not part of CrafterCMS, but instead it is a Groovy class specific to the project. To be able to use this class, you should place it under scripts > classes and name it DateUtils.groovy, where everything after the groovy directory is part of the class’ package. It’s recommended for all Groovy classes to follow this convention.

 1package utils
 2
 3import java.text.SimpleDateFormat
 4
 5class DateUtils {
 6
 7  static def parseModelValue(value){
 8    def dateFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss")
 9    dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"))
10    return dateFormat.parse(value)
11  }
12
13  static def formatDateAsIso(date) {
14    def dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
15    dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"))
16    return dateFormat.format(date)
17  }
18}

For more information on the FreeMarker (Templating) APIs, please see FreeMarker (Templating) API.

For more information on the Groovy APIs, please see Groovy/Java API

Important

Scripts and Templates Security

CrafterCMS limits access to services when developing templates or scripts, and sandboxes scripts for security by default. CrafterCMS only allows a small list of services available to use when developing templates or scripts. There are some sites that may require services not included by default. To expose other services, follow the guide Configure Custom Services.

Scripts are executed in a sandbox that has a blacklist of insecure expressions to prevent code that could compromise the system. There are some cases though where a site requires access to one or more of the blacklisted expressions.

To override the default script sandbox configuration, follow the guide Groovy Sandbox Configuration.