Formulas in Knackly can be thought of as "named expressions": with a formula, you can do anything you can do in an expression, but you can attach it to a type and give it your own name so it can easily be reused across the apps you create. Formulas, like all expressions, involve a combination of functions, operators, literal values, filters, and identifiers referring to variables, templates or other formulas.
In a formula, you can reference variables, templates, or other formulas by name. For example, if you wanted a formula that calculated the total based on the price and quantity, the formula would look like:
Price * Quantity
Formulas may include parentheses () to change the order of operations:
(Apples + Oranges) / Guests
Note: operators and functions designated with this icon: indicate a standard function or operator that is built into JavaScript – in these cases, additional documentation and examples can easily be found elsewhere on the Internet.
Text operators, filters and functions
Text operators
Operator  Description  Examples 
+  Concatenate text values into a single text value. To concatenate static text, surround it with double quotation marks. To concatenate double quotation marks, you need to use a backslash (\) as an escape character. Equivalent to the concat(text) function.  Name + "  " + Age => Jane  28 "\""+ProductName+"\"" => "GreatProduct" 
[ ]  Extracts a single character from a text value. Equivalent to the charAt(number) function.  "John Smith"[0] => J 
Comparison operators (text specific usage)
Operator  Description  Examples 
==  Is equal to. Determines whether two text values are the same or not. Case sensitive comparison.  "yes" == "no" => false "yes"[0] == "y" => true 
!=  Not equal to. Determines whether two text values are different. Case sensitive comparison.  "yes" != "no" => true "yes"[0] != "y" => false 
<  Determines whether one text value precedes another in alphabetical order. Roughly corresponds to the localeCompare(text) function returning 1.  "ant" < "boy" => true "boy" < "ant" => false 
<=  Determines whether one text value precedes or matches another in alphabetical order. Roughly corresponds to the localeCompare(text) function returning either 0 or 1.  "ant" <= "ant" => true "ant" <= "boy" => true 
>  Determines whether one text value follows another in alphabetical order. Roughly corresponds to the localeCompare(text) function returning a positive 1.  "ant" > "boy" => false "boy" > "ant" => true 
>=  Determines whether one text value follows or matches another in alphabetical order. Roughly corresponds to the localeCompare(text) function returning either 0 or 1.  "ant" >= "ant" => true "ant" >= "boy" => false 
Text filters
Filter  Description  Examples 
upper  Makes a text value uppercase. Equivalent to the toUpperCase() function.  "Hello!"upper => HELLO! 
lower  Makes a text value lowercase. Equivalent to the toLowerCase() function.  "Hello!"lower => hello! 
initcap : forceLower  Capitalizes the first character in a text value and (optionally) makes the rest of the text lowercase.  "macDonald"initcap => MacDonald "macDonald"initcap:true => Macdonald 
titlecaps : forceLower  Capitalizes each word in a text value and (optionally) makes the rest of the text lowercase.  "marty mcFly"titlecaps => Marty McFly "marty mcFly"titlecaps:true => Marty Mcfly 
contains : textToFind  Determines if a text value contains another text value. The search is case sensitive. Equivalent to the includes(text) function.  "MacDonald"contains:"Don" => true "MacDonald"contains:"old" => false 
else : text  Tests whether a text value is empty, and if so, supplies an alternative text value.  ClientNameelse:"client" => John ""else:"client" => client 
Text "methods" and properties (advanced)
Method  Description  Examples 
textValue.charAt(number)  Extracts a single character from a text value at the position indicated by number. Equivalent to use of the [ ] operator.  "John Smith".charAt(5) => S 
textValue.charCodeAt(number)  Returns an integer between 0 and 65535 representing the UTF16 code unit at the position indicated by number.  "ABC".charCodeAt(0) => 65 
textValue.codePointAt(number)  Returns a nonnegative integer that is the Unicode code point value at the position indicated by number.  "☃★♲".codePointAt(1) => 9733 
textValue.concat(text1[, text2, …])  Concatenates the text arguments onto the "calling" text value. To concatenate static text, surround it with double quotation marks. To concatenate double quotation marks, you need to use a backslash (\) as an escape character. Roughly equivalent to use of the + operator.  Name.concat(" – ", Age) => Bob  43 "".concat("\"", ProductName, "\"") => "GreatProduct" 
textValue.endsWith(text)  Determines whether textValue ends with text. Case sensitive.  "brown fox".endsWith("fox") => true 
textValue.first(count)  Extract count characters from the beginning of textValue.  "quick brown fox".first(5) => quick 
textValue.includes(text[, startAt])  Determines whether textValue contains a specific substring (text) or not. The search is case sensitive. If startAt is specified, it searches textValue only from that position onwards. Similar to the contains filter.  "quick fox".includes("ick") => true "quick ox".includes("ick",3) => false 
textValue.indexOf(text[, start])  Finds an occurrence of text in textValue starting from an optional start position. (start is 0 by default.) If no occurrence of text is found, the result will be 1. The search is case sensitive.  "brown fox".indexOf("fox") => 6 "brown fox".indexOf("o", 3) => 7 
textValue.last(count)  Extract count characters from the end of textValue.  "quick brown fox".last(3) => fox 
textValue.lastIndexOf(text[, start])  Finds the last occurrence of text in textValue starting from an optional start position. (start is the full length of textValue by default.) If no occurrence of text is found, the result will be 1. The search is case sensitive.  "brown fox".lastIndexOf("o") => 7 "brown fox".lastIndexOf("o", 6) => 2 
textValue.localeCompare(text)  Determines whether textValue comes before, or after, or is the same as, the given text string in sort order.  "ant".localeCompare("boy") => 1 => ant precedes boy "boy".localeCompare("boy") => 0 => no difference in sort order "boy".localeCompare("ant") => 1 => boy follows ant 
textValue.length  Returns the length in characters of a text value.  "quick brown fox".length => 15 
textValue.padEnd(length[, padding])  Pads textValue by appending a given padding string (repeated, if needed) so the resulting value reaches the given length. If padding is omitted, spaces are used by default.  "boy".padEnd(5, "y") => boyyy 
textValue.padStart(length[, padding])  Pads textValue by prepending a given padding string (repeated, if needed) so the resulting value reaches the given length. If padding is omitted, spaces are used by default.  "hat?".padStart(7, "wh") => whwhat? 
textValue.repeat(count)  Causes textValue to be repeated count times.  "beep ".repeat(3) => beep beep beep 
textValue.replace(oldText, newText)  Replaces a single occurrence (within textValue) of oldText with newText. Comparison is case sensitive.  "how now".replace("ow", "at") => hat now 
textValue.replaceAll(oldText, newText)  Replaces all occurrences (within textValue) of oldText with newText. Comparison is case sensitive.  "big dig".replace("i", "o") => bog dog 
textValue.search(pattern)  Searches within textValue for a substring that matches pattern, and returns the position in the string (if found) or 1 (if not found). pattern is a text value containing a JavaScript regular expression, although RegExp flags (g, i, m, etc.) are not allowed.  "356".search("^[09]+$") => 0 "35a6".search("^[09]+$") => 1 
textValue.slice(start[, end])  Extracts the part of textValue that begins at start and ends before end. If start or end is negative, it counts backwards from the end of textValue rather than from the beginning. If end is omitted, the extracted value will go from start to the end of textValue.  "abcde".slice(1) => bcde "abcde".slice(1, 4) => bcd "abcde".slice(0, 2) => abc 
textValue.split([separator[, limit]])  Turns a text value into a list of text values by splitting it at each instance of separator. If separator contains multiple characters, that entire character sequence must be found in order to split. If separator is omitted or does not occur in textValue, the returned list will contain only one item (textValue). If separator appears at the beginning or end of textValue, or both, the array begins, ends, or both begins and ends, respectively, with an empty text value. If separator is an empty text value (""), the result is a list of text values, each a single character of textValue.  "a/b/c".split("/") => [ "a", "b", "c" ] "Hello there world".split(" ", 3) => [ "Hello", "there", "" ] (Two spaces after "there" causes an empty text value in the list, and the limit of 3 caps the number of items returned.) 
textValue.startsWith(text)  Determines whether textValue starts with text. Case sensitive.  "brown fox".startsWith("fox") => false 
textValue.strip(characters, fromStart, fromEnd)  Strips any occurrences of the given characters from the start, the end, or both the start and end of textValue. If fromEnd is omitted, it defaults to true. If both fromStart and fromEnd are omitted, they both default to true.  "aaabccc".strip("ac") => b "aaabccc".strip("ac", false) => aaab "aaabccc".strip("ac", true, false) => bccc 
textValue.substr(start[, count])  Extract a substring of count characters starting at start. If count is omitted, the extracted substring goes from start to the end of textValue.  "an old fox".substr(3,3) => old "an old fox".substr(3) => old fox 
textValue.substring(start[, end])  Extract a substring beginning at position start and ending before position end.  "an old fox".substring(3,6) => old "an old fox".substring(3) => old fox 
textValue.toInt()  Parses textValue and returns an integer.  2 * ("32".toInt()) => 64 
textValue.toLowerCase()  Makes textValue lowercase. Equivalent to lower filter.  "Hello!".toLowerCase() => hello! 
textValue.toUpperCase()  Makes textValue uppercase. Equivalent to upper filter.  "Hello!".toUpperCase() => HELLO! 
textValue.trim()  Removes whitespace from both the beginning and end of textValue. Whitespace includes spaces, nonbreaking spaces, tabs, and line termination characters.  " Hello world! ".trim() => Hello world! 
textValue.trimEnd()  Removes whitespace from the end of textValue. trimRight() is an alias to this method. 

textValue.trimStart()  Removes whitespace from the beginning of textValue. trimLeft() is an alias of this method. 

Text "helper" functions
Function  Description  Examples 
text.fromCharCode(num1[, num2, …])  Returns a text value created from the specified sequence of UTF16 code units.  text.fromCharCode(189, 43, 190, 61) => ½+¾= 
text.fromCodePoint(num1[, num2, …])  Returns a text value created from the specified sequence of Unicode code points.  text.fromCodePoint(9731, 9733, 9842, 0x2F804) => ☃★♲你 
Comparison operators (numbers and dates)
Operator  Description  Examples 
left == right  Determines whether any value is equal to another value. Special note: you must use two equals signs. In JavaScript, a single equals (=) is used to assign a value to a variable. Knackly does not support this syntax.  2 == 2 => true 
left != right  Determines whether any value is not equal to another value.  3 != 2 => true 
left < right  Determines whether one number value or date value is less than another.  3 < 5 => true date.today < date.new(2020,1,1) 
left <= right  Determines whether one number value or date value is less than or equal to another.  5 <= 5 => true 
left > right  Determines whether one number or date value is greater than another. 

left >= right  Determines whether one number or date value is greater than or equal to another 

Logical operators and functions
Logical operators
Operator  Description  Examples 
left && right  Logical AND: the && operator will return a "truthy" value only if both its operands are "truthy". If the lefthand operand is falsy, the result will be whatever the value of the lefthand operand is. If the lefthand operand is truthy, the result will be whatever the value of the righthand operand is.  true && true => true Client && Client.Name => John Smith (if Client is nonnull) "" && 5 => "" 
left  right  Logical OR: the  operator will return a "truthy" value if either of its operands are "truthy". If the lefthand operand is truthy, the result will be whatever the value of the lefthand operand is. If the lefthand operand is falsy, the result will be whatever the value of the righthand operand is.  false  true => true false  false => false 
! operand  Logical NOT: the ! operator will return true if its single operand is falsy, or false if its operand is truthy.  !true => false !false => true !Client => false (if Client is answered) => true (if Client is null / not answered) 
condition ? value1 : value2  Conditional operator: returns value1 if condition is truthy, otherwise it returns value2. Can be nested.  Simple example: Sales > 50 ? "Win" : "Lose" Nested and cleanly formatted: WaterTemp > 100 Testing for "answeredness": BirthDate 
Number operators, filters and functions
Number operators
Operator  Description  Examples 
+  Add together two numeric values  Size + 2 
  Subtract two numeric values  Price  3.00 
*  Multiply two numeric values  Price * Quantity 
/  Divide two numeric values  Price / NumPeople 
%  Returns the remainder after dividing the left operand by the right operand.  10 % 3 => 1 NumPeople % NumTables 
Number filters
Filter  Description  Examples 
format:general[:negative[:zero]]  Formats a numeric value into text. You can optionally supply separate format strings for positive numbers, negative numbers, and zero. The first (general) format given will be used if the zero and/or negative format is omitted. Format strings are fully specified in numeral.js's documentation: In addition to those supported by numeral.js, Knackly also supports format strings "a" and "A" to get spreadsheet columnstyle numbering.  10000format:"0,0.00" => 10,000.00 5.5  format: "0 %" => 550 % 25  format: "0000" => 0025 28  format: "A" => AB 
cardinal  Spells out a cardinal number in words.  123cardinal => one hundred twentythree 
ordinal  Spells out an ordinal number in words  123ordinal => one hundred twentythird 
ordsuffix  Provides the appropriate ordinal abbreviation suffix (without the number itself).  the {[Day]}^{{[Dayordsuffix]}} of the month => the 22^{nd} of the month 
else:text  Tests whether a number value is zero (falsy), and if so, supplies an alternative text value.  Child.Age  else:"not yet one" 
Mathematical "helper" functions
Function  Description  Examples 
math.abs(x)  Returns the absolute value of x.  math.abs(5) => 5 
math.cbrt(x)  Returns the cube root of x. 

math.ceil(x)  Returns the smallest integer greater than or equal to x.  math.ceil(1.01) => 2 math.ceil(1.01) => 1 
math.clz32(x)  Count leading zeros in 32bit binary representation 

math.exp(power)  Computes Euler's number (e) to the specified power.  math.exp(1) => 2.71828 math.exp(3) => 20.08554 
math.expm1(x)  Returns a number representing e^{x}  1 

math.floor(x)  Returns the nearest integer that is less than or equal to the value.  math.floor(1.99) => 1 
math.fround(x) 


math.hypot(value1[, value2, …])  The square root of the sum of squares of the given arguments. 

math.imul(a, b)  Clike 32bit multiplication of a and b 

math.log(x)  Natural logarithm (base e) of a given number 

math.log10(x)  Base 10 logarithm of a given number  math.log10(1000) => 3 
math.log1p(x)  Natural logarithm (base 3) of 1 plus the given number 

math.log2(x)  Base 2 logarithm of a given number  math.log2(1024) => 10 
math.max(value1[, value2, …])  Returns the largest of the given numbers  math.max(Amount, 1000) 
math.min(value1[, value2, …])  Returns the smallest of the given numbers  math.min(Amount, 0) 
math.pow(base, power)  Returns a n umber representing the given base raised to the given power (exponent).  math.pow(3, 3) => 27 math.pow(7, 0) => 1 
math.random()  A floatingpoint pseudorandom number between 0 (inclusive) and 1 (exclusive). 

math.round(x)  The value of the given number (x) rounded to the nearest integer. If the fractional portion of the argument is greater than 0.5, the argument is rounded to the integer with the next higher absolute value. If it is less than 0.5, the argument is rounded to the integer with the lower absolute value. If the fractional portion is exactly 0.5, the argument is rounded to the next integer in the direction of +∞.  math.round(3.5, 0) => 4 math.round(3.4, 0) => 3 
math.sign(x)  Returns either a positive or negative 1, depending on the sign of x. 

math.sqrt(x)  Square root of the given nonnegative number  math.sqrt(100) => 10 
math.trunc(x)  The integer part of the given number. Truncate towards zero. 

Mathematical constants (not super useful in document assembly)
Property  Description  Examples 
math.E  Euler's number  math.E => 2.71828 
math.LN10  Natural logarithm of 10 

math.LN2  Natural logarithm of 2 

math.LOG10E  Base 10 logarithm of e 

math.LOG2E  Base 2 logarithm of e 

math.PI  Pi, or the ratio of the circumference of a circle to its diameter 

math.SQRT1_2  The square root of ½ 

math.SQRT2  The square root of 2 

Trigonometry "helper" functions (not super useful in document assembly!)
Function  Description  Examples 
math.acos(x)  Arccosine (inverse cosine)  
math.acosh(x)  Hyperbolic arccosine (inverse hyperbolic cosine) 

math.asin(x)  Arcsine (inverse sine) 

math.asinh(x)  Hyperbolic arcsine (inverse hyperbolic sine) 

math.atan(x)  Arctangent (inverse tangent) 

math.atan2(y, x)  2agrument arctangent (2argument inverse tangent) the angle in the plane (in radians) between the positive xaxis and the ray from (0,0) to the point (x,y) 

math.atanh(x)  Hyperbolic arctangent (inverse hyperbolic tangent) 

math.cos(x)  Cosine 

math.cosh(x)  Hyperbolic cosine 

math.sin(x)  Sine 

math.sinh(x)  Hyperbolic sine 

math.tan(x)  Tangent 

math.tanh(x)  Hyperbolic tangent 

Financial "helper" functions
Function  Description  Examples 
finance.FV(rate, nper, pmt[, pv, type])  Future value of an investment with periodic constant payments and a constant interest rate. rate: interest rate per period nper: number of periods for the lifetime of the annuity pmt: payment amount per period pv: present value of the annuity (if omitted, defaults to 0) type: whether payments made at start or end of each period 0 = payments at end of period (default) 1 = payments at start of period  Future value of an investment of $1,000 per month for a period of 5 years. The present value is 0, interest rate is 5% per year and payments are made at the end of each month: finance.FV(0.05/12, 5*12, 1000) => 68,006.08 Future value of an investment of $2,000 per quarter for a period of 4 years. The interest is 10% annually and payment are made at the start of the quarter: finance.FV(0.1/4, 4*4, 2000, 0, 1) => 39,729.46 
finance.NPER(rate, pmt, pv[, fv, type])  Number of periods 

finance.PMT(rate, nper, pv[, fv, type])  Payment amount per period 

finance.PV(rate, nper, pmt[, fv, type])  Present value of a loan or an investment, based on a constant interest rate. rate: interest rate per period nper: number of periods for the lifetime of the annuity pmt: payment amount per period fv: future value of the annuity (if omitted, defaults to 0) type: whether payments made at start or end of each period 0 = payments at end of period (default) 1 = payments at start of period  Present value of an annuity that pays $1,000 per month for a period of 5 years. The interest is 5% annually and payments are made at the end of the month. finance.PV(0.05/12, 5*12, 1000) => 52,990.71 Present value of an annuity of $2,000 per quarter for a period of 4 years. The interest is 10% per year and payments are made at the start of the quarter. finance.PV(0.1/4, 4*4, 2000, 0, 1) => 26,762.76 
finance.RATE(nper, pmt, pv[, fv, type, guess])  Interest rate per payment period 

Date filters and functions
Date filters
Filter  Description  Examples 
format:string  Formats a date value into text. Format strings are fully specified in datefns' documentation:  => 
else:text 

=> 
Date "methods" (advanced)
Method  Description  Examples 
dateValue.getDate()  Extracts only the day (of the month) from dateValue. Equivalent to date.dayOf().  NewYearsEve.getDate() => 31 
dateValue.getDay()  Returns the day of the week for dateValue, where 0 represents Sunday and 6 represents Saturday. Equivalent to date.dayOfWeek().  MemorialDay.getDay() => 1 
dateValue.getFullYear()  Extracts only the year from dateValue. Equivalent to date.yearOf().  KnacklyOrigin.getFullYear() => 2019 
dateValue.getMonth()  Extracts only the month from dateValue. NOTE: This returns a zerobased month, where 0 is January, 1 is February, … and 11 is December. For 1based months, either add one to the result, or see the date.monthOf() helper function.  ValentinesDay.getMonth() => 1 
date1.isAfter(date2)  Tests whether date1 is after date2 chronologically. Equivalent to date1 > date2 (?) 

date1.isBefore(date2)  Tests whether date1 is before date2 chronologically. Equivalent to date1 < date2 (?) 

date1.isEqualTo(date2)  Tests whether date1 and date2 represent the same day. Equivalent to date1 == date2 (?) 

date1.isNotAfter(date2)  Tests whether date1 is NOT after date2 chronologically. In other words, date1 is no later than date2, or, date1 is before or on date2. Equivalent to date1 <= date2 (?) 

date1.isNotBefore(date2)  Tests whether date1 is NOT before date2 chronologically. In other words, date1 is no earlier than date2, or, date1 is on or after date2. Equivalent to date1 >= date2 (?) 

date1.isNotEqualTo(date2)  Tests whether date1 and date2 represent different days. Equivalent to date1 != date2 (?) 

dateValue.valueOf()  Returns an internal value representing the date, which is the number of milliseconds between 1 January 1970 and that date. 

Date "helper" functions
Function  Description  Examples 
date.addDays(dateValue, d)  Returns the date a specified number d days after dateValue.  date 10 days after openingDate: date.addDays(openingDate, 10) 
date.addMonths(dateValue, m)  Returns the date a specified number m months after dateValue.  date 3 months after startDate: date.addMonths(startDate, 3) 
date.addWeeks(dateValue, w)  Returns the date a specified number w weeks after dateValue.  date 8 weeks after startDate: date.addWeeks(startDate, 8) 
date.addYears(dateValue, y)  Returns the date a specified number y years after dateValue.  date 2 years after startDate: date.addYears(startDate, 2) 
date.age(dateValue)  Calculates the number of whole years between dateValue and today.  date.age(BirthDate) => 27 
date.dayOf(dateValue)  Returns the day portion (day of the month) of dateValue in the form of a number between 1 and 31. Equivalent to dateValue.getDate()  date.dayOf(Christmas) => 25 
date.dayOfWeek(dateValue)  Returns the day of the week for dateValue, where 0 represents Sunday and 6 represents Saturday. Equivalent to dateValue.getDay() 

date.daysBetween(date1, date2)  Returns the number of calendar days between date1 and date2. 

date.monthOf(dateValue)  Returns the month portion of dateValue as a number between 1 (January) and 12 (December). Note the difference in numbering with dateValue.getMonth() 

date.monthsBetween(date1, date2)  Returns the number of full months between date1 and date2. 

date.new(y, m, d)  Converts the given year, month (112) and day (131) numbers to a date value. 

date.parse(textValue)  Attempts to parse the given textValue as a date, returning the resulting date value. 

date.subDays(dateValue, d)  Returns the date a specified number d days before dateValue.  date 10 days before openingDate: date.subDays(openingDate, 10) 
date.subMonths(dateValue, m)  Returns the date a specified number m months before dateValue.  date 3 months before startDate: date.subMonths(startDate, 3) 
date.subWeeks(dateValue, w)  Returns the date a specified number w weeks before dateValue.  date 8 weeks before startDate: date.subWeeks(startDate, 8) 
date.subYears(dateValue, y)  Returns the date a specified number y years before dateValue.  date 2 years before startDate: date.subYears(startDate, 2) 
date.today()  Returns the current date in the local time zone. (Note that the results of this function changes only when the formula is recalculated. It does not update continuously.) 

date.yearOf(dateValue)  Returns the year portion of dateValue as a number between 1000 and 9999. 

date.yearsBetween(date1, date2)  Returns the number of full years between date1 and date2. 

True/false filters
Filter  Description  Examples 
format:iftrue:iffalse  "Format" a true/false value as one of the provided text arguments. Note: the conditional operator can do the same thing more concisely (coin ? "heads" : "tails"), so this is not very useful.  coinformat:"heads":"tails" => "heads" 
List properties, filters and functions
List properties
Property  Description  Examples 
length  The number of items in the list.  Children.length => 4 
List operators
Operator  Description  Examples 
[ ]  Extracts a single item from a list, where 0 retrieves the first item, 1 retrieves the second item, and so on.  Children[0] => the first child in the Children list 
List filters
List filters provide a way to filter, sort, and otherwise manipulate lists of data.
Filter  Description  Examples 
any:expr  Produces a true/false value indicating whether the given expression (predicate) is true when evaluated against any item in the input list. The filter stops evaluating as soon as it finds one item in the list where the expression evaluates to a truthy value. This filter can also be used under the alias of some.  Do any children have a name that starts with C? Childrenany:Name.startsWith("C") => true 
contains:value  Produces a true/false value indicating whether the given value exists in the input list. Equivalent to the includes function.  Does a list of text values contain a specific text value? TextListcontains:"this value" => false 
every:expr  Produces a true/false value indicating whether the given expression (predicate) is true when evaluated against EVERY item in the input list. The filter stops evaluating as soon as it finds one item in the list where the expression evaluates to a falsy value. This filter can also be used under the alias of all.  Are all the children married? Childrenevery:IsMarried => false 
filter:expr  Produces a filtered subset of the input list. The output list will contain every item from the input list where expr is true when evaluated against that item.  List all of the minor children: Childrenfilter: 
find:expr  Produces a single value of the same type as the items in the input list. The given expression is evaluated against each item in the input list (in order). The first item where expr is true (or truthy) gets returned as the result of the find.  Get the party designated as executor: Partiesfind:Role=="Executor" 
group:expr  Produces a list of groups or categories from a flat input list. The given expression (expr) is evaluated against each item in the input list. An output group is created for each unique result of that evaluation. Each item in the output list (that is, each output group) is an object with two properties: _key: the result of evaluating expr _values: a list of the same type as the input list  List parties by relationship to the client: {[list AllPartiesgroup: Client's {[_key]}s: {[list _values]} {[Name]} {[endlist]} {[endlist]}

map:expr  Produces a list of items where each item in the input list "maps" to exactly one item in the output list. The given expression (expr) is evaluated against each item in the input list, and the result of that evaluation is placed in the output list.  Produce a list of names (simple text values) from a list of children: Childrenmap:FullName

punc[:example]  Specifies a punctuation style for the list to which it is applied. Only has an effect when used in a {[list]} field in a template. Punctuation example strings consist of the digits (tokens) 1, 2, and optionally 3, separated by other characters as a way of indicating how items in this list should be joined together in text. If no example is provided, "1, 2, and 3" is assumed. Note: Unlike the rest of the list filters, this one outputs the same list that was passed into it.  {[list Childrenpunc]}{[Name]} {[endlist]} => John, Mary, Susan, and Edward {[list Boyspunc]}{[Name]} {[endlist]} => John and Edward {[list Childrenpunc:"1, 2."]}{[Name]} {[endlist]} => John, Mary, Susan, Edward. {[list Childrenpunc:"1, 2 and 3"]}{[Name]} {[endlist]} => John, Mary, Susan and Edward {[list Girlspunc:"1, 2, or 3?"]}{[Name]} {[endlist]} => Mary or Susan? 
reduce:reducer[:initial]  Produces a new value by evaluating the given reducer expression against each item in the input list. Typically follows one of two models: It can "reduce" the input list to a single value, such as when you want to calculate a value that requires some input from each item in the input list. Or it can "accumulate" a new list as it goes through each item in the input list. Items in this new list need not have a 1:1 correspondence with the input items. You can optionally specify an initial value for the output. For example, if the input list were empty, the output value would be whatever was specified as initial. If you do not specify an initial value, the first item in the input list becomes the initial value. Reducer expressions have access to a special local variable called _result., which is of the same type as either the initial value or the first item in the input list. _result is always set to the result of the previous item's evaluation. Think of _result as a kind of bridge between the evaluation of each item in the input.  Sum a list of numbers: NumberListreduce:_result + this Do the same thing as the map filter, mapping a list of Children to a list of their names: Childrenreduce:_result.concat( Do the same thing as the filter filter, conditionally adding items to the result only if the child's age is <18: Childrenreduce: Flatten a nested list. Each child has a list of toys, and each toy has a ToyName, but we need a flat list of ALL the toy names: Childrenreduce:

sort:key1[:key2…]  Changes the sort order of the list to which it is applied. Sort keys are expressions relative to each item in the list. Expressions will be evaluated for each item in the list, and the result is used to determine the order of the resulting list.  Specifying a sort with multiple keys: Partiessort:LastName:FirstName Descending (reversed) sort order uses a minus sign: Matterssort: StartDate Sorting a list of text values (instead of objects): TextListsort: this 
List "methods" (advanced)
Function  Description  Examples 
listValue.concat(item1[, item2…])  Merges two or more lists. The concat method creates a list consisting of the items in the list on which it is called, followed in order by, for each argument, the items of that argument (if the argument is a list) or the argument itself (if the argument is not a list).  [1, 2, 3].concat(4, 5, [6, 7, 8]) => [1, 2, 3, 4, 5, 6, 7, 8] 
listValue.includes(item[, start])  Determines whether a list includes a certain item among its entries, returning true or false as appropriate. If start is specified, it ignores any items in the list prior to that index. Equivalent to the contains filter. 

listValue.indexOf(item[, start])  Returns the first index at which a given item can be found in the list, or 1 if it is not present. 

listValue.join([separator])  Creates and returns a text value by concatenating all the items in a list of text values, separated by a specified separator value. If no separator is provided, an unspaced comma (",") will be used. If the list has only one text value, that value will be returned without using the separator. If the list contains items other than text values, they will be coerced to text and you'll probably get something ugly. 

listValue.lastIndexOf(item[, start])  Returns the last index at which a given item can be found in the list, or 1 if it is not present. 

listValue.slice([begin[, end]])  Extracts a portion of a list from begin (inclusive) to end (exclusive) where begin and end represent zerobased indices of items in the list. begin: Index at which to begin extraction. A negative index can be used, indicating an offset from the end of the list. If begin is omitted, slice begins from index 0. If begin is greater than the length of the list, an empty list is returned. end: Index before which to end extraction. A negative index can be used, indicating an offset from the end of the list. If end is omitted or is greater than the length of the list, slice extracts through the end of the list. 
