Scripted Lanes
1 Overview
A user will be a member of a Scripted Lane if they satisfy the criteria set for membership by the script which defines how membership should be determined. The criteria can be based on the user's settings, metadata, preferences or current lane membership (or a combination of the three). This document gives details of what can be included in a script.
The script is relevant for execution modes
LIVE
andACCEPTANCE
Once you have created your script it is possible to check it. The result will show you how many users meet the criteria (and so will be members of the lane) and the duration of the query.
Lanes and Roles are essentially the same things. Roles are used in a User context whereas Lanes are used in a Process context i.e. a Role becomes a Lane in a process context.
1.1 Script computation
Membership of a scripted lane is re-computed under the following circumstances:
- Modification of the script for the lane;
- Modification of a user's settings;
- Modification of a user's metadata;
- Modification of a user's preference;
- Modification of one lane referenced in the script.
Only impacted scripted roles (because of a script change or user metadata / preference / settings update) are computed.
Scripts are computed in batch: Therefore it could take up to maximum 5 minutes before being computed.
When a script is computed, all the users matching the script become part of the role.
1.2 Status and last computed date
The status and last computed date of the scripted role are displayed in the Role Management module of the DigitalSuite within the Information section.
The status could be one of the following value:
-
Ready
: The role has been computed properly and is up to date. -
Pending
: Something impacting that specific role has changed (script, user metadata, preference or settings) and the role is waiting for its computation. -
Error
: The role cannot be computed. In this case, contact our support team. -
Invalid script
: The script is invalid (all invalid scripts will result in an empty lane). In this case, update the script to be compliant with the new syntax.
2 Creating a Scripted Lane
Go to the tab Organization and create a new Role. By adding a formula within the Role Script field your lane will become a scripted lane.
A scripted lane is created separately to the process execution, scripts can only therefore involve static data.
The supported structure of a script is (in the following order):
-
An optional static part
-
A dynamic part
2.1 Optional Static part
<#
freemarker static computation >
Here is an example script:
<#-- Computation of the ratio -->
<#assign first_number = 23>
<#assign second_number = 3>
<#assign result = first_number / second_number>
The result could be used as a variable of the dynamic part (to ease the understanding of a computation for example).
2.2 Dynamic part
${
expression }
Rules for the expression:
-
Expression could be a combination of logical parts separated by
&&
or||
-
Supported evaluation order is
variable
operator
value
(value
operator
variable
is not supported) -
Only the listed Properties and FreeMarker Methods or Built-ins are supported
Here are some example scripts:
-
${is_user_in_lane([1111,1112,1113])}
: The scripted lane will contain all the users that belong to any of the lanes 1111, 1112 or 1113. In other words, the scripted lane will be the union of the lanes 1111, 1112 and 1113. -
${is_user_in_lane([1111]) && is_user_in_lane([1112])}
: The scripted lane will contain the users that belong to both lanes - 1111 and 1112. In other words, the scripted lane will be the intersection of the lanes 1111 and 1112. -
${is_user_in_lane([1111]) && color=='red'}
: The scripted lane will contain all of the users that belong to the lane 1111 and have the Metadata or Preference 'color' set to red.
If the script is not recognised as a script e.g. because it does not start with
${
and end with}
or start with<#
then the lane will be empty.
3 Valid Methods and Properties
The following section details the methods and properties that can be used within scripts.
3.1 Freemarker Methods
-
is_user_in_lane()
: Allows you to determine whether or not the current user is a member of at least one of the lanes specified. The lane ids are passed as a list (can be just one lane). -
get_user_metadata()
: Get the metadata for the current user. -
get_user_preferences()
: Get the preferences for the current user. -
get_user_data()
: Get the basic data (e.g. id, name) for the current user. -
has_right()
: Determines if the current user is a member of the lane whose id is passed as a parameter.
If the lane queried by methods
is_user_in_lane()
andhas_right()
is a lane of type everybody, an error will be thrown. These methods should not be used with lanes of type everybody.
3.2 Using Internal Parameter P_user
P_user
can be used in the script to represent the current user.
3.2.2 User Properties
The following properties can be used with P_user
to access the user's data:
Property | Description | Syntax |
---|---|---|
id |
The user's unique identifier | P_user.id |
login |
The user's login id | P_user.login |
name |
The user's name | P_user.name |
profile |
The user's profile | P_user.profile |
status |
The user's current status - Active, Pending or Inactive | P_user.status |
restriction |
Any restriction placed on the user's account e.g. unable to view other users | P_user.restriction |
3.2.1 Metadata and Preferences properties
The following properties can be used with P_user
to access the user's metadata or preferences:
Property | Description | Syntax |
---|---|---|
extended |
Access the current user's metadata | P_user.extended.xxx where xxx would be the name of the metadata required (e.g. P_user.extended.company ). Equivalent of using get_user_metadata() or get_user_data().extended |
preferences |
Access the current user's preferences | P_user.preferences.xxx where xxx would be the name of the preference required (e.g. P_user.preferences.language ). Equivalent of using get_user_preferences() or get_user_data().preferences |
3.2.3 Accessing properties direclty
It is possible to access properties directly within the script e.g. ${my_metadata == value}
In this case, if the property is present in both the metadata and the preferences, the metadata will take preference.
3.3 Freemarker Built-ins
The following Freemarker Built-ins can be used within scripts:
Built-in | Description | Example |
---|---|---|
?? |
This operator determines if a value is missing (result is false) or not (result is true). If the metadata doest not exist, ?? will raise an error |
P_user.ext.company?? |
?default |
This allows you to set a default value if the value is missing. | P_user.ext.company?default("MyCompany") |
?exists |
This operator determines if a value is present (result is true) or missing (result is false). If the metadata doest not exist, ?exists will raise an error |
P_user.ext.company?exists |
?contains |
True if the substring specified as the parameter to this built-in occurs in the string. | P_user.login?contains(".fr") |
?seq_contains() |
True if a sequence contains the value passed as a parameter. | get_user_preferences().languages?seq_contains("Russian") |
?size |
The number of elements in a sequence | languages?size |
Consecutive Freemarker Built-ins are not supported (Ex: P_user.pref.language?default("English")?contains("Russian")
4 Deprecated Freemarker Built-ins
Some Freemarker Built-ins that were previously supported in scripts have now been deprecated. This section identifies these built-ins and suggests alternative ways of achieving the same behaviour with supported Built-ins.
Built-in(s) | Explanation | Example Previous Use | Replacement |
---|---|---|---|
?eval |
This built-in evaluates a string as an expression. For example "2+2"?eval returns 4. | ${language == "English"?eval} |
${language == "English"} |
?default([])?size |
Consecutive Freemarker Built-ins are not supported. | ${(companies?default([])?size > 0)} |
${(companies?size > 0)} |
?index_of |
This built-in was used to determine the presence of a substring within a string. | ${grade?index_of("y") != -1} |
${grade?contains("y") == true} |
?upper_case |
This built-in converted a string to upper case. | ${(country?upper_case == "ENGLAND")} |
No alternative available yet |
?lower_case |
This built-in converted a string to lower case. | ${(country?lower_case == "england")} |
No alternative available yet |
?string |
This built-in returned the value as a string. | ${global_superuser?string =="true"} |
(if global_superuser is a boolean) ${global_superuser == true} |
?has_content |
This returned true if the variable existed and had some value. | ${get_user_metadata().finance?has_content} |
${get_user_metadata().finance?? && get_user_metadata().finance != ""} |
5 Other deprecated functionality
Strings used as booleans
It was previously possible to treat strings that were used for boolean values as though they were booleans e.g. ${support}
where support
was a string used for boolean values (i.e. took the value "true" or "false").
When no operators are used on these strings, they must now be treated as strings rather than booleans. The above example would therefore need to be written as ${support == "true"}
6 Error Codes
The following errors codes are the answer of the server when checking or saving a scripted lane:
Code | Name | Explanation |
---|---|---|
FMT0 | MALFORMED_SCRIPT | No script or assignment block found. |
FMT1 | UNKNOWN_PROPERTY_EXCEPTION | The property(metadata or preferences) is unknown |
FMT2 | SYNTAX_ERROR_EXCEPTION | Syntax problem - an expected character was not found |
FMT3 | NO_SCRIPT_EXCEPTION | The script was not recognized, the ${} was probably missing |
FMT4 | INTERNAL_EXCEPTION | An exception was thrown during the translation of the script |
FMT5 | BUILTINS_EXCEPTION | At least one unsupported built-in was used |
FMT6 | EVERY_BODY_LANE_EXCEPTION | The script used at least one everybody lane |
FMT7 | SEQ_CONTAINS_EXCEPTION | The parameter passed to built-in ?seq_contains() is incorrect |
FMT8 | SYNTAX_OPERATOR_EXCEPTION | A syntax problem was found around an operator (e.g. a single '&' instead of a double '&&') |
FMT9 | PARENTHESIS_EXCEPTION | A parenthesis mismatch, no closing parenthesis found for an opening one |
FMT10 | UNKNOWN_DATA_EXCEPTION | The data(metadata or preferences) is unknown |
FMT11 | NOT_SYNTAX_EXCEPTION | Syntax problem around the use of the NOT ('!') operator |
FMT12 | UNKNOWN_OPERATOR_EXCEPTION | The operator used is not a supported one |
FMT13 | BUILTINS_SIZE_EXCEPTION | The value of the ?size built-in was not found |
FMT14 | WRONG_SIZE_VALUE_EXCEPTION | The size value is not compatible with ?size built_in |
FMT15 | UNKNOWN_SIZE_OPERATOR_EXCEPTION | The operator of the ?size built-ins is not supported |
FMT16 | TYPE_EXCEPTION | Wrong or malformed parameter of builtins ?contains |
FMT17 | DOUBLE_BUILTINS | Consecutive builtins |
FMT999 | OTHER_EXCEPTION | An unknow exception was thrown during the testing of the script |
Please give details of the problem