Using Scripts and Templates

When building iKnowBase applications, you can use scripts and templates to implement logic and layout in a very efficient manner.

Inside iKnowBase, the term template is used to cover both scripts and templates. In fact, they are very much the same thing: A chunk of text which is evaluated at runtime, performing some kind of logic and producing some kind of output. You are free to implement templates in either FreeMarker, JavaScript or Groovy (where templates implemented using the latter two are typically called scripts).

Template concepts

The basic idea behind templates in iKnowBase can be summarized as follows:

Available components

Templates are available for use with a large number of components:

Model objects

When an iKnowBase component passes control to a template, it also forwards information relevant to the execution. The actual objects available depends on the originating component, and the full list can be found in the API-reference documentation.

Available template languages

iKnowBase support template implementations in several languages:

The choice of language for a template is entirely up to you, but there are some typical guidelines:

FreeMarker

iKnowBase supports the use of FreeMarker templates. When using FreeMarker templates, you will combine static markup, standard FreeMarker functionality and iKnowBase model objects to create the desired output:

In order to best utilize the FreeMarker technology, you should read the FreeMarker documentation available at http://freemarker.org/docs. Some key features are described below, but this covers only a small subset of the capabilities.

Groovy

iKnowBase supports the use of Groovy templates. When using Groovy templates, you will use the power of groovy to create the desired output, or perform the required actions.

Implicit objects

When using Groovy, iKnowBase will always provide you with a number of “implicit objects” available to the script. These are documented in the API Reference, under each component type, and are the same objects that are being made available to FreeMarker templates. However, Groovy templates have access to a number of additional objects.

For templates that run in any sort of viewer or page, the following objects are available:

Object Description
out A PrintWriter representing the output destination
html A MarkupBuilder useful for creating HTML or XML markup to the output destination
json A StreamingJsonBuilder useful for creating JSON markup to the output destination

When running in a web settings, where there is in fact an underlying HTTP servlet, the following objects are also available:

httpServletRequest A HttpServletRequest providing access to the underlying HttpServletRequest
httpServletResponse A HttpServletResponse providing access to the underlying HttpServletResponse

For templates that run as a Script Target, the following additional objects are also available:

Object Description
sout A ServletOutputStream representing the output destination

Examples

This example shows a couple of items. First, how you can use the iknowbase-object to get a Groovy SQL object, and then use that to query the database. Second, it shows how the implicit MarkupBuilder named html can be used to produce well-formatted html output.

 // Prepare some data
def pageTitle = "/SYSTEST/Action/GroovyScript-HtmlBuilder"
def users = iknowbase.sql.rows("select * from all_users where rownum <= 5")

// Output a complete html-document
html.html {
   head {
      title(pageTitle)
      style(type:"text/css","""
      table { border:thin solid black; width:100%; }
      th { background-color: #999 }
      """)
   }
   body {
      h1(pageTitle)
      table {
         tr {
            th("User ID")
            th("Username")
         }
         users.each { user->
            tr {
               td(user.user_id)
               td(user.username.toLowerCase())
            }
         }
      }
   }
}

This example shows how the implict StreamingJsonBuilder named json can automate the production of json:

def dbUsers = iknowbase.sql.rows("select * from all_users where rownum <= 5")

// Output a complete json-document
def userlist = [users:dbUsers.collect { [id:it.user_id, username:it.username.toLowerCase() ] }]
def userinfo = [userinfo:userlist]

json(userinfo)

This example shows how to use the documentService to create a document from an activitiy Script task.

import com.iknowbase.api.contentservices.v2.model.*;
def userref = new UserReference().withUsername(initiator)

def document = new Document()
document.documentIdentity = new DocumentReference(null, null, "activiti_" + execution.getProcessInstanceId(), null, null)
document.title = "Activiti Process - ProcessInstanceId: " + execution.getProcessInstanceId()
document.documentTypeReference = new ObjectReference(null, null, "TEMPDATA", null);

// Create ikb document
def documentReference = iknowbase.documentService.saveDocument (
   userref,
   document,
   SaveOperationEnumeration.INSERT,
   SaveOperationEnumeration.NONE,
   SaveOperationEnumeration.NONE,
   null, null, null, false
);

JavaScript

iKnowBase supports the use of JavaScript templates. When using JavaScript templates, you will use the power of JavaScript to create the desired output, or perform the required actions.

HTML script

You can use valid html. In addition, there is support for <ORACLE> tags to insert PL/SQL code.

Template chaining

iKnowBase allows template chaining, a mechanism where you combine multiple templates in one operation. For example, if you want to implement a search page, you may need to use a script (Groovy or JavaScript) to execute the actual search, but you still want the layout to be done using FreeMarker, which is better suited for that purpose.

Any component in iKnowBase that supports templating allows you to specify multiple templates, which you then name at will. iKnowBase will then proceed as follows:

FreeMarker templates do not support returning a value, so any FreeMarker template will end the process. Groovy and JavaScript-templates, on the other hand, return the value of the last executed expression, so that it is simple to return the name of the next template:

// JavaScript template. Use a random value to choose template, then
// evaluate expression returning either "view-full" or "view-minimal"
var variant = Math.random() < 0.5 ? "full" : "minimal"
"view-" + variant
// Groovy-script
def variant = System.currentTimeMillis() % 2 == 0 ? "even" : "odd"
"view-$variant"

Error handling

All the template languages have their own, internal support for error handling (try-catch in JavaScript, try-catch in Groovy and #attempt/#recover in FreeMarker). However, it is often simpler to use the iKnowBase template error handling mechanism, which avoids the clutter inside each individual template.

If a template fails during execution, iKnowBase will look for a template named “ERROR”. If this template is found, it will be executed. Simple!