Help Center

CheckMarket Scripting Language (CSL)

CheckMarket offers a powerful scripting language to enhance your surveys and reports called the CheckMarket Scripting Language or CSL for short.

You can use it in your emails, surveys and reports.

Our scripting language gives you tremendous freedom to use variables (placeholders), make calculations, show or hide certain blocks of text and much more. So put on your computational thinking cap and let’s dig in…

Variables

Variables in the scripting language are wrapped with double curly brackets, like this: {{someVariable}}. They are case-insensitive, so {{SomeVariable}} is the same as {{someVariable}}.

Hierarchy

The variables are hierarchical, so you can navigate through them by using dot notation from top level objects working your way down. Here are some examples:

  • Questions in survey: {{survey.questions}}
  • The text of the 1st question in survey: {{survey.questions.1.text}}
  • Text of the second answer choice in question 1: {{survey.questions.1.answerChoices.2.text}}

Where to find

Survey variables: can be found in the ‘variables’ dropdown in the text editor of your questions, emails, notifications, …
Here is a list of survey interface variables.

Report variables: In the ReportBuilder, you can find these variables inside the text editor by using the expand button expand icon in the properties pane under ‘Comment’ on the right. Here you’ll find the ‘Variables’ menu:

Where can CSL be used?

CSL can be used almost everywhere. In surveys, reports and emails. You can even use it in the subject line or ‘from’ field or ‘to’ field of emails. And by emails, we mean all emails: invitations, reminders, thank-you emails, and notifications. You just type the CSL code directly in your text. A good way to start is to copy and paste an example and then adjust it to meet your needs.

Operators

Our scripting language, CSL, supports more than just variables. Using special operators you can implement your own logic.

In CSL the operator comes first!

To write 1=1 in CSL is:

{{eq 1 1}}

The ‘eq’ stands for ‘equals’. behind it we place the two arguments to be checked, separated by a space. All CSL operators work this way!

The ‘eq’ operator expects two arguments. If you need to first do some additional operations, you need to use parentheses to group the arguments like this:

{{eq (add 1 1) 2}}

When you have parentheses, the contents inside them are done first. So in this case the ‘add’ is done first and then the result is evaluated by the ‘eq’ operator.

Here is an example using an ‘if’ statement:

{{#if (eq contact.customFields.department 'HR')}}
  You work in HR!
{{/if}}

In the example above, we check if the custom field called ‘Department’ of the current contact equals ‘HR’. If so, we display a text. If not, nothing is shown.

List of operators

You can use block operators to show/hide content depending on your own logic.

OperatorDescription
ifUse the if helper to conditionally display a block. If its argument returns false, null, “”, 0 or [], the block will not be visible.
{{#if (and title description)}}
  This text is only visible if there's a title AND a description.
{{/if}}
if + elseSpecify an else block to be displayed if the first condition is not met.
{{#if contact}}
  <h1>{{contact.firstName}} {{contact.lastName}}</h1>
{{else}}
  <h1>Unknown respondent</h1>
{{/if}}
else ifCombine multiple #if blocks using else if. The system will evaluate each ‘if’ in order until it finds one that is true or it reaches the ‘else’. Once one of the ‘if’ blocks is true, the others are ignored even if they are true too.
{{#if contact}}
  <h1>{{contact.firstName}} {{contact.lastName}}</h1>
{{else if respondent.questions.yourName}}
  <h1>{{respondent.questions.yourName}}</h1>
{{else}}
  <h1>Unknown respondent</h1>
{{/if}}
unlessUse the unless helper as the inverse of the if helper. Its content will be displayed if the condition is not met (if the value is either false, null, “”, 0 or [])
{{#unless response}}
  <h3 class="warning">Warning: There's no response!</h3>
{{/unless}}
eachIterate over a list using the built-in each helper. Inside the block, you can use this to reference the element being iterated over, or immediately use underlying properties.
<ul>
  {{#each report.elements}}
    <li>{{title}}</li>
  {{/each}}
</ul>
each + elseTogether with an each operator, you can optionally provide an else section which will display only when the list is empty.
{{#each report.elements}}
  <h2>{{title}}</h2>
{{else}}
  <p>No elements in this list!</p>
{{/each}}
commentsUse a comment block to add an internal remark, or temporarily prevent some CSL from executing.
{{!-- Everything inside this block will not be shown or executed --}}

 

Using logical operators you can check and compare variables. These operators are most often used inside block operators like #if or in display logic.

A CSL condition is a statement that is either true or false.

Here is a simple example that will return true:

{{eq 1 1}}

Translation: The ‘eq’ stands for ‘equals’. In CSL, the operator is always placed first. The other two items are what is being compared so it says ‘1 is equal to 1’. This is true.

Here is an example that will return false:

{{eq 1 2}}

It says ‘1 is equal to 2’. This is false.

OperatorDescription
eqReturns true if two arguments are equal.
eq 1 1
neReturn true if two arguments are not equal.
ne 1 2
ltReturns true if the first argument is less than the second.
lt 9 12
gtReturns true if the first argument is greater than the second.
gt 15 12
leReturns true if the first argument is less than or equal to the second.
le 12 12
geReturns true if the first argument is greater than or equal to the second.
ge 12 12
containsReturns true if the text of the first argument contains the second argument.
contains respondent.questions.comment "unhappy"
andReturns true if all arguments are true.
and (eq 1 1) (lt 2 3)
orReturns true if any of the arguments are true.
or (eq 1 1) (eq 1 3)
notReverses the result. Returns true if the inner condition is false and false if the inner condition is true. For example check if a respondent is a contact. This will return true, if they are not a contact.
not contact

Use math operators to work with numbers. You can perform calculations or control how numbers are presented.

OperatorDescription
addAdd two or more numbers.
10 + 5 = {{add 10 5}}
Result: 10 + 5 = 15
subtractSubtract two or more numbers.
10 - 5 = {{subtract 10 5}}
Result: 10 - 5 = 5
multiplyMultiply two or more numbers.
10 * 5 = {{multiply 10 5}}
Result: 10 * 5 = 50
divideDivide two or more numbers.
10 / 5 = {{divide 10 5}}
Result: 10 / 5 = 2
averageAverage two or more numbers.
The average of the numbers 1,2,3,4 = {{average 1 2 3 4}}
Result: (1+2+3+4) / 4 = 2.5
sqrtCalculate the square root of a number.
The square root of 25 is {{sqrt 25}}
Result: The square root of 25 is 5
powCalculate the first argument raised to the power of the second argument.
Three to the power of two is {{pow 3 2}}
Result: Three to the power of two is 9
modCalculate the remainder after dividing the first argument by the second.
5 % 4 = {{mod 5 4}}
Result: 5 % 4 = 1
absReturn the absolute value of a number.
The absolute value of -10 is {{abs -10}}
Result: The absolute value of -10 is 10
roundRound a number to the amount of digits specified. If no digits are specified, the number is rounded to 0 digits.
The first rounded value is {{round 25.9999}}, the second is {{round 12.123456 2}}
Result: The first rounded value is 26. The second is 12.12
floorRound a number downward to its nearest whole number.
{{floor 25.9999}}
Result: 25
ceilingRound a number upward to the next whole number.
{{ceiling 25.13}}
Result: 26
randomGenerate a random number between the numbers specified.
A random number between 5 and 10 is {{random 5 10}}
Result: A random number between 5 and 10 is e.g. 8
random + excludeGenerate a random number, excluding certain values. You can add as many excluded values as you like.
A random number between 5 and 10, excluding 7 and 8 is {{random 5 10 exclude="7,8"}}
Result: A random number between 5 and 10, excluding 7 and 8 is e.g. 9
countGet a count of the number of items in a list/array.
There are {{count report.elements}} elements in this report
Result: There are 3 elements in this report
kFormat a number to the K notation.
{{k 12468}}
Result: 12K
decExplicitly choose the decimal separator.
{{dec 12.3 ","}}
Result: 12,3
expReturns the constant e = 2.71828… raised to the power of a given number.
{{exp 5}}
Result: 148.4132 (e raised to the power 5 equals 148.4132)
logIf you pass two arguments, the log operator returns the logarithm of a number to the base you specify.
{{log 30 5}}
number = 30 and base = 5
Result: 2.1133 (5 raised to the power 2.1133 equals 30)

If you pass one argument, the log operator returns the natural logarithm of a number.

{{log 25}}
Result: 3.2189 (the constant e=2.71828 raised to the power 3.2189 equals 25)

Use date operators to display or manipulate dates and times.

OperatorDescription
currentDateReturn the current date and time in the date format and timezone of the survey owner.
Today is {{currentDate}}.
Result: Today is 08/17/2000 4:14 PM.
.isoAdd to any date to get the date in ISO format. This format is machine readable. Use for prefilling and post-filling.
Today is {{currentDate.iso}}.
Result: Today is 2000-08-17 16:14.
.utcAdd to any date to get the date in ISO 8601 format in the UTC timezone. This format is machine readable. Use when sending a date to a database or API.
Today is {{currentDate.utc}}.
Result: Today is 2000-08-17T14:14Z.
.dateAdd to any date to get only get the date portion of a date excluding the time.
Today is {{currentDate.date}}.
Result: Today is 08/17/2000.
.timeAdd to any date to get only get the time portion of a date excluding the date.
The time now is {{currentDate.time}}.
Result: The time now is 4:14 PM.
.relativeAdd to any date to get the relative date, described in words.
You were born {{contact.dateOfBirth.relative}}.
Result: You were born 30 years ago.

Tip: use .relative.styled to get the relative date, with the original date as a tooltip.

.year
.month
.month.text
.day
.dayOfWeek
.dayOfWeek.text
.hour
Add to any date to get only that portion of the date.
You were born in {{contact.dateOfBirth.year}}.
Result: You were born in 1970.
regionalSettings.timezoneOffsetHoursGet the time difference between the survey owner’s local timezone and UTC (Coordinated Universal Time). This is based on the user profile of the survey owner.
My UTC offset is {{regionalSettings.timezoneOffsetHours}} hours.
Result: My UTC offset is 4 hours.
dateFormatDisplay a date using a specified format.
Your birthdate: {{dateFormat contact.dateOfBirth "MMM d yy"}}
Result: Your birthdate: Feb 12 87

Some examples of the formats you can use:

i: 2000-08-17
I: 2000-08-17 16:32:32
a: 2000-08-17 16:32
d: 08/17/2000
D: Thursday, August 17, 2000
f: Thursday, August 17, 2000 16:32
F: Thursday, August 17, 2000 16:32:32
g: 08/17/2000 16:32
G: 08/17/2000 16:32:32
m: August 17
r: Thu, 17 Aug 2000 23:32:32 GMT
s: 2000-08-17T16:32:32
t: 16:32
T: 16:32:32
u: 2000-08-17 23:32:32Z
U: Thursday, August 17, 2000 23:32:32
y: August, 2000
dddd, MMMM dd yyyy: Thursday, August 17 2000
dddd, MMMM dd: Thursday, August 17
M/yy: 8/00
dd-MM-yy: 17-08-00
dateAddAdd a certain timespan to a date.
Specify the date, number of units to add (subtracting can be done by using a negative value) and the unit.
The unit can be one of the following: year, month, day, hour, minute and second.
We'll reply before {{dateFormat (dateAdd respondent.dateResponded 3 "day") "D"}}.
Result: We'll reply before Thursday, August 17, 2000.

Note: the date is always returned in the ISO 8601 format. Use dateFormat if you’d like to render it in a pretty way.

dateDiffCalculate the difference between two dates.
Specify the start and end date, along with the unit. The unit can be year, month, day, hour, minute or second.
We've invited you {{dateDiff contact.dateInvited currentDate "day"}} days ago.
Result: We've invited you 3 days ago.
dateInTimeZoneShow a date in a specific time zone.
{{dateInTimeZone respondent.dateResponded "Mountain Standard Time"}}
Result: 2020-12-09 10:05

Tip: to show the date in a format that is easier to read, also use a dateFormat operator:

{{dateFormat (dateInTimeZone respondent.dateResponded "Mountain Standard Time") "g"}}
Result: 12/9/2020 10:05 AM (depending on your date and time settings)

All supported time zones can be found in our list of time zones.

Use text operators to change how text is rendered.

OperatorDescription
upperCaseConvert the text to upper case letters.
{{upperCase "Some text"}}
Result: SOME TEXT
lowerCaseConvert the text to lower case letters.
{{lowerCase "Some TEXT"}}
Result: some text
trimRemove whitespace at the start and end of text.
{{trim "  Some text  "}}
Result: Some text
replaceReplace a sequence of characters in a string with another set of characters. This operator accepts three terms: The text to be searched, the text to find, and the replacement text: {{replace textToSearch textToFind replaceWith}}
{{replace "I love blue." "blue" "red"}}
Result: I love red.

This operator is case insensitive and will replace all occurrences of the search term.

splitSplit text based on a character and returns one part. This operator accepts three terms: The text to split, the character to split the text by (delimiter), index of the part to return: {{split textToSplit characterToSplitOn index}}
Here is an example of a comma-delimited string for which we extract a second item:
{{split "Blue,Red,Green" "," 2}}
Result: Red.
leftExtract the first characters of a piece of text.
{{left "Some text" 2}}
Result: So
rightExtract the last characters of a piece of text.
{{right "Some text" 3}}
Result: ext
substringExtract characters from a piece of text. This operator accepts three arguments: the text, the index of the first character and the number of characters to extract. Omit the last argument to extract the rest of the text.
{{substring "Some text" 3}} / {{substring "Some text" 3 5}}
Result: me text / me te
.unformattedRemove formatting from text.
{{survey.questions.myDataLabel.text.unformatted}}
Result: Example text with a part in italics.

Place this at the end of a variable to strip the HTML formatting and display everything as plain text

urlEncodeMake text suitable for URLs.
{{urlEncode "Some text?"}}
Result: Some%20text%3F

This should be used when using variables in URLs that may contain spaces, slashes or other special characters. Numbers do not need to be url encoded.
For instance, use this operator in a branch to an external URL or in a link placed on the thank-you page. You can also add ‘.urlEncoded’ to the end of a variable. For example:

{{survey.questions.myDataLabel.text.urlEncoded}}
jsonEncodeMake text suitable for JSON.
{{jsonEncode 'Test "123"'}}
Result: Test \"123\"

This should be used when creating JSON, and the text might contain backslashes, double quotes or other special characters. You can also add ‘.jsonEncoded’ to the end of a variable. For example:

{{survey.questions.myDataLabel.text.jsonEncoded}}
hashConvert text to a 64 character hash code.
{{hash "Some text"}}
Result: 4C2E9E6DA31A64C70623619C449A040968CDBEA85945BF384FA30ED2D5D24FA3

This operator generates a 64 character hash using the SHA-256 hashing algorithm.
If you pass multiple values, they will be joined as one string and then hashed. This way, you can add a so-called salt value to make your hashes harder to guess. Combine with post-filling. An example:

{{hash respondent.questions.name respondent.questions.birthdate "some salt value"}}

You can also use the HMAC SHA256 hashing algorithm. For this, you will need to pass HMAC-SHA256 as the first argument, followed by the text to be hashed and finally the secret key. For example:

{{hash "HMAC-SHA256" "something" "secret"}}

 

Use modals and popovers to display extra information when the respondent clicks a link. Use modals for longer text or images, use popovers for small bits of information or to explain a word.

Note: these operators are only supported in the survey interface and reports.

OperatorDescription
iconDisplay a small icon. Specify an identifier from Font Awesome.
{{icon "far fa-star"}}
modalDisplay a link to open a modal window.
Click {{modal "here" "This text is inside the modal window."}} for more info.
Result: Click here for more info. 
Result inside the modal window: This text is inside the modal window.

Adding an icon is also possible.

Click {{modal "here" "This text is inside the modal window." icon="fas fa-info-circle"}}!

If your text inside the modal window is long, you can also use the #modal variant:

{{#modal "click here"}}
This text can be longer and contain markup, quotes and variables.
{{/modal}}
tooltipDisplay a tooltip or text balloon when moving your mouse over something.
This is a {{tooltip "NPS" "Net Promotor Score"}} question. 
Result: This is a NPS question.
Result inside tooltip: Net Promotor Score

Note: since there’s no mouse on mobile, it’s activated by clicking.

By default tooltips are displayed above the link. You can override this position by specifying “left” “right” or “bottom”.

{{tooltip "Click here" "Displayed on the right" position="right"}}

Adding an icon is also possible. Add the FontAwesome class of the icon that you want to use as the last parameter.

{{tooltip "Click here" "Some text" position="top" icon="fas fa-info-circle"}}

If your text inside the tooltip is long, you can also use the #tooltip variant:

{{#tooltip "Click here"}}
This text can be longer and contain markup, quotes and variables.
{{/tooltip}}
popoverThe same as a tooltip, but only activated by clicking, not by moving your mouse over it.
This is a {{popover "NPS" "Net Promotor Score"}} question. 
Result: This is a NPS question.
Result inside popover: Net Promotor Score
lightboxShow a small version of an image. When it is clicked on, a large version of the image is displayed by filling the screen, and dimming out the rest of the page.
{{#lightbox}}CheckMarket Logo{{/lightbox}}

Add {{#lightbox}} before and {{/lightbox}} after the image to make it clickable. When clicked, the image is shown full screen. Optionally add multiple images inside the same lightbox to create a gallery.

You can also show an image inside a lightbox without using an image, but using text instead:

{{lightbox "CheckMarket logo" "https://www.checkmarket.com/wp-content/
uploads/2016/03/CheckMarket-logo.png"}}
qrCodeShow a QR code of a URL or text snippet. You can optionally provide the size in pixels. The max size is 270.
{{qrCode "https://www.checkmarket.com/" 100}}

Result:
QR code

You can also use variables. For instance, if you have a coupon code, in a contact custom field called ‘coupon’, use:

{{qrCode contact.customFields.coupon 100}}

 

 

See the following article for more examples and information:
Tooltips, popovers and modal windows

Use custom temporary variables to split big functions into smaller parts. These variables are not stored anywhere, they’re only temporarily available within the same page.

OperatorDescription
setSave a temporary value. You need to specify a name and the value.
{{set "mySum" (add 1 2)}}

To save a large piece of text, you can also use the #set variant:

{{#set "myText"}}
This sample text can be longer and contain markup, quotes and variables.
{{/set}}

You can combine text by passing multiple values like this:

{{set "greeting" "Hello " contact.firstName "!"}}

Note: no result is returned at this time. Use the function below to retrieve this variable.

get
{{get "mySum"}}
Result: 3

Retrieve a temporary value using the name you specified with the set operator.

Look up information from a contact list as if it was a database and return that information to surveys, notifications, reports.

OperatorDescription
contactListLookupMany users want to look something up in a database. This function lets you use contact lists as a sort of database. For instance, an employee enters their employee number and their department, level and manager are retrieved from a contact list.
The contactListLookup function has 4 terms:
  1. Contact list id to search
  2. Field to search
  3. Value to search for (case insensitive)
  4. Field to return
{{contactListLookup 1234 "customFields.1" "Emp4574" "email"}}
Result: [email protected]

You can optionally specify an extra term “contains” to look for a partial match instead of an exact match. For example, “ACME” would also match “ACME Corporation”.

{{contactListLookup 1234 "customFields.2" "ACME" "email" "contains"}}
Result: [email protected]

But it can go further than contacts (people). Think more abstractly and you can lookup anything. For instance, place a list of stores in a contact list and when someone enters their city, you return the address of the location in that city or someone selects their store and the email address of the store manager is placed in the ‘to’ field for a notification of an unhappy customer. Any kind of lookup becomes possible!

queryStringLookupExtract a querystring parameter from a URL.
{{queryStringLookup "https://example.com?code=123" "code"}}
Result: 123
USStateToAbbreviationGet the abbreviation for a given US state.
{{USStateToAbbreviation "Texas"}}
Result: TX
USStateFromAbbreviationGet the name of a US state from its abbreviation.
{{USStateFromAbbreviation "TX"}}
Result: Texas

You can combine all these operators to create more advanced logic.  The most common example, is combining ‘and’, ‘or’ and ‘not’. To do that, you really have to think in terms of true or false. Each item is evaluated and then compared using the operators.

For example:

{{eq 1 1}}

This is true. 1 equals 1.

Using and:

{{and (eq 1 1) (eq 2 2)}}

This is true. 1 equals 1 and 2 equals 2.

Using or:

{{or (eq 1 2) (eq 2 2)}}

This is true. 1 does not equal 1, but 2 does equal 2. ‘or’ is true if any of the terms are true.

Using not:

{{not ( or(eq 1 3) (eq 2 2))}}

This is false. 1 does not equals 3 but 2 does equal 2. the ‘not’ reverses the result. Simplified, the code can then be seen as:

{{not (or false true)}}

The or is true since one of the terms is true, so you get:

{{not (true)}}

‘Not’ makes the true become false:

{{false}}

Examples

You can combine all these operators to create more advanced logic. We have a page with useful snippets of CSL code that you can use in your surveys. They are a great starting off point. Even if you do not find code that does exactly what you want, there is often something there, that you can change slightly to achieve what you want.

Survey CSL snippets

2 comments

Join the conversation
  • allan cheung - April, 2019 reply

    Is there example of how to use the checkmarket scripting language in the survey?

    Pieter De Witte - April, 2019 reply

    Yes, there’s a page about using CSL in surveys.
    You can use these variables in questions, text/media, notifications, etc.

Leave a Reply

Your email address will not be published.