Expression Language (EL) provides the way to refer to values of variables and do some light programming operations in the logic. It can be used in all command attributes, HTML logic element attributes and logic attributes that are marked as EL-evaluated, which most of them are. When an expression is evaluated, the result is always a single value.

The ${} notation marks EL expression. A dollar sign, followed by curly brackets. Whatever is between the curly brackets is treated as an EL expression. Note that in the content commands of HTML and Office templates, the dollar and curly brackets are not needed - everything is treated as an EL expression by default.

Constructing an expression

The contents of EL expressions can be variable references and simple values, and then the operators and methods that do something with the values. While the operators and methods are numerous, the ways in which values are expressed are relatively few. The basic rules of expression construction is that an expression has to consist of at least one value and an operator has to exist between each value if there is more than one value included.  

Values in expressions

Most of the values in expressions refer to the values of variables, as that is the main use case of EL in Dynamo. However, it is also possible to type in certain simple values into expressions directly. The following ways can be used to have values in expressions:

  • Variable values are referred to by simply having the variable's name in the expression. The expression ${weather} would refer to the value of the variable named "weather" and resolve into the value of that variable when evaluated.
  • Strings, or plain text, can be put into an expression by enclosing the text in single quotes. The expression ${'Dynamo'} would resolve into the String "Dynamo".    
  • Numbers can be just typed into the expression as is. The expression ${23} resolves into a Number with the value of 23.  
  • Booleans are represented by the keywords 'true and 'false'. The expression ${true} would resolve into the truthful Boolean value, while ${false} would resolve into the opposite.

In its simplest form, an expression consists of a single value like those above and nothing else.

Operators in expressions

Operators can appear between values in the expressions to have the expression resolve into something dependent on the values. A basic example of this concept is a mathematical expression, such as ${1 + 2}, which has the plus sign as the operator and would resolve into a Number with value of 3. Similarly, one of the values there could be a variable with a Number value, like ${someNumber + 2} - if the Number value of "someNumber" would be 5, the resolved value of this expression would be 7. While + and other mathematical operators might not be the most common ones, this is the basic idea of how operators interact with values. The actually common tasks are done with the operators dot, brackets and various different ones for conditional expressions, all introduced below.

The dot and brackets

An operator that is very common in most templates is the dot . which is used for several things, but primarily for accessing values contained within other values. Salesforce data retrieval commands typically bring the retrieved data into the logic as Data item values, which are values that then contain the values of each of the queried fields. For example, if the data of an Opportunity record would be in a variable named "opportunity", the value of the record's Amount field would be accessed with the expression ${opportunity.Amount}. It is also possible to go deeper with more dots, so getting the name of the Opportunity's associated Account could be done with ${opportunity.Account.Name}. The fact that this is very similar to the notation for specifying fields of related records in Saleforce Object Query Language (SOQL) is a pure coincidence, but certainly not a harmful association to make.  

This dot syntax is actually one for accessing the values of a Map's entries, but as Data items are essentially Maps, this syntax mostly appears used with these results of Salesforce data retrievals. But if you happen to have a Map, created with the setMap command for example, this same syntax can be used with it. If there would be a Map variable called "monthlyValues" containing an entry with the key "october", the expression ${monthlyValues.october} would resolve into the value of that entry. The expression ${param.id}, present in the logic of most templates, is also an example of this, accessing the value of the "id" entry of the "param" Map.

The dot is also used to make use of the methods intrinsic to values of different types. Methods are basically commands issued to the value itself that causes the value to produce a result of some kind. As this is a fairly significant feature, it has its own section Methods, but in short, a method is used with an expression of format ${value.methodName()}; this is identified as a method use by the () following the method name.

The brackets [] are an operator akin to the dot, allowing contents of a Map to be accessed. In this syntax the key is placed between the brackets, so the previous example expression with the Map variable "monthlyValues" could also be done like ${monthlyValues['october']}. Note that the key there is wrapped with single quotes - this is because whatever is between the brackets is evaluated like a value in the expression. Therefore while that expression gets the value of the entry with the key "october", ${monthlyValues[october]} would get the entry whose key is the value of the variable "october". If an expression with a variable key is what you need, the brackets are your tool.

It is also possible to use the brackets to access specific items of a Collection. This is done by putting the index of an item between the brackets, so for example to access the second item of a Collection in variable "products", the expression would be ${products[1]}. The index of the second item is 1, as the indexes start from 0. This use of brackets doesn't generally see too much use as rather than accessing individual items in this way, a loop is typically used to iterate through all the items of a Collection in order. Also, doing this can be considered a bit dangerous as specifying an index that the Collection doesn't have an item for, such as index 7 if the Collection has but 2 items, causes the expression to fail.  

Both the dot and the brackets may be "chained", like in ${opportunity.Account.Name}. This is technically a two-part expression that first gets the value of the "Account" entry of the "opportunity" Map. The "Account" value is a Map, so the next part gets the value of the "Name" entry of that Map. This works similarly with brackets, like ${opportunity['Account']['Name']}, and these two operators can also be mixed, so ${opportunity.Account['Name']} and ${opportunity['Account'].Name} are also valid. This also applies to the dot's use with methods. For example, the expression ${company.Name.toUpperCase()} would get the "Name" value of the "company" Map, and then use the toUpperCase() method. This, of course, requires that you are sure to know what kind of value the part preceding the method expression resolves into - the example expression only works if the value of "Name" is a String, as toUpperCase() is a method of String type values. As might be expected, method uses can be chained as well, so for example with the variable "representedCountries" having a Multipicklist value, the expression ${representedCountries.asList().size()} would first use the asList() method of the Multipicklist type, and then use the size() method of the List that was the result of the first method.  

Operators for conditions

Other common operators are the various logical and relational ones that create conditional expressions, that is, ones that resolve into Boolean values. These are most commonly used with the if logic command and the if content command. There's a large variety of these operators, but let's first take a look at a common one checking equality, the == operator. It checks if the two values it is in between of are equal, resolving into a Boolean "true" if they are equal and "false" if not. An expression like ${type == 'Special'} would resolve into "true" if the value of the variable "type" is the String "Special", while ${type == requestedType} would check if the variables "type" and "requestedType" have equal values. The opposite operator is != that resolves into a Boolean "true" only if the values are not equal.

Note that if you have a variable that already has a Boolean as its value, such as the value of a checkbox-type Salesforce field, just using that variable's value alone is a conditional expression, eg. ${Opportunity.IsClosed}. If you'd like to invert this check, that is, to have it resolve into "true" when the variable's value is actually "false", add the exclamation mark in front of the variable name, or precede it with not, eg. ${!Opportunity.IsClosed} or ${not Opportunity.IsClosed}. These expressions could also be done by checking equality with the Boolean keywords "true" and "false": ${Opportunity.IsClosed == true} and ${Opportunity.IsClosed == false}.

Another useful operator for creating conditional expressions is the operator empty. It checks if the variable value after the operator is null (an undefined value) or a String with zero characters in it, resolving into "true" if either of these is the case. For example, the expression ${empty opportunity.Description} resolves into "true" if the "Description" field of the queried Opportunity record has no value. This operator also checks actual emptiness, in that if the variable value is a Map or a Collection, it resolves into "true" if the Map or Collection has no entries or items in it. For example, if "queryResults" was a variable produced by the SOQL query command, the expression ${not empty queryResults} would resolve into "true" only if the query retrieved data of one or more records.

Multiple conditional expressions can be combined together to form a single expression using the operators && and ||, or and and or. The && or and combines the two expressions is in between of so that the combined expression resolves into "true" only if both of the individual expressions resolve into "true". For example, the expression ${status == 'Testing' and user.isTester} would resolve into "true" only if the "status" variable's value is "Testing" and the "user" is supposedly a tester. The || or or combines the expressions it is in between of so that the result is "true" if either of the individual expressions resolves into "true". For example, the expression ${season == 'Winter' or season == 'Spring'} would resolve into "true" if the "season" variable's value is either "Winter" or "Spring". These could be further combined with each other, like  ${(status == 'Testing' and user.isTester) and (season == 'Winter' or season == 'Spring')} - note the use of parenthesis here to define operator priority in a way similar to how it works in mathematics.

Mixing up text and expressions

The value defined for an EL-evaluated attribute value doesn't have to be a single expression, it is possible to have both static text and expressions mixed up. So, for an attribute one could define a value like The price of ${product.name} is ${product.unitPrice}${currencySymbol}., which could evaluate into the String "The price of EL-Resolver is 75,45€.". Inclusion of static text or multiple expressions in the attribute value will always make the attribute's resolved value a String, regardless of the types of values the expressions within produce - if an attribute requires any other type of value, be sure to just specify a single expression resolving into a value of that type with no extra characters around the expression.  

Matching value types

When using certain kinds of operators involving two values in expressions, such as the ones for mathematical operations, it can be important to have the involved values be of a certain, and perhaps matching, type. Most notably, all of the operators of the "Arithmetic" category in the operator table only work if the values are Numbers - trying to, for example, subtract a Data Item from a String isn't a valid operation. Similarly, checking the equality of a Collection and a File wouldn't serve much purpose. The operator table lists these rules in its "Restrictions" column.

Expression errors

EL expressions generally are not very tolerant to problems of any kind - they either work perfectly or not at all. There are generally two reasons why expressions fail:

  • Incorrect syntax, such as not getting the curly brackets right or missing operators between values in the expression. In this case the expression cannot be parsed at all and the command, in whose attribute this error occurs, will itself fail.
  • Referring to nonexistent variables. If an expression refers to the value of a variable that does not exist, the attribute in which this expression is will resolve into null and the attribute's command will report this error. However, if null is a valid resolved value for the attribute, the command will keep doing its work as if the attribute was undefined. Unless there's a typo in the referred variable's name, this error is likely to not be a problem in the expression itself - to solve this, try to find out why the variable does not exist. Maybe the command creating it is in a conditional section that was skipped, or maybe the command was evaluated but still failed to create its variable.    

Regardless of the kind of problem an expression has, they can all be fixed, either by correcting the expression itself or altering the logic around the command the expression is in.

Operators

Below is a complete list of the operators available for use in EL expressions. Note that the operators are case-sensitive and lowercase, so "AND" or "Not" for instance are not valid representations of those operators.




Category Symbol(s) Operator Restrictions Example expression Value of the example
Dot . Access value of a Map's entry Value has to be a Map or a Data Item ${Opportunity.Account.Name}
Name value of the Account related to the Opportunity.
Use method

${exampleCollection.size()}
Number of items in the Collection
Brackets [] Access value of a Map's entry
Value has to be a Map or a Data Item
${Opportunity['Account']['Name']}
Name value of the Account related to the Opportunity
Access item of a Collection Value has to be a Collection
${exampleCollection[2]}
The third item in the Collection
Arithmetic + Addition
Both values have to be Numbers
${1 + 2}
3 (Number)
- (binary) Subtraction ${1 - 2}
-1 (Number)
* Multiplication ${1 * 2}
2 (Number)
/, div Division ${1 div 2}
0.5 (Number)
%, mod Modulus/ remainder ${11 % 9}
2 (Number)
- (unary) Negation ${-(1+2)}
-3 (Number)
Logical and, && Logical AND
${(2 < 4) and (1 > 3)}
${(2 < 4) && (1 > 3)}
False (Boolean)
or, || Logical OR
${(2 > 4) or (1 > 3)}
${(2 > 4) || (1 > 3)}
True (Boolean)
not, ! Logical negation (NOT)
${!opportunityContact.IsPrimary}
True (Boolean), if the Contact is not the primary contact for the Opportunity
False (Boolean), if it is the primary contact
Relational ==, eq Equal to Both values have to be of the same type ${Account.Name eq ‘Tom’}
${Account.Name == ‘Tom’}
True (Boolean), if the Account's name is ‘Tom’
False (Boolean), if the name is anything else
!=, ne Not equal to ${Opportunity.Amount != 2}
${Opportunity.Amount ne 2}
True (Boolean), if the Opportunity's Amount is not 2
False (Boolean) if the Opportunity's Amount is 2
<, lt Less than Both values have to be either Numbers or Date(Time)s
${Opportunity.Amount < 1000}
True (Boolean), if the Opportunity's Amount is less than 1000
False (Boolean), if the Opportunity's Amount is greater than or equal to 1000
>, gt Greater than ${Opportunity.Amount > 5000}
True (Boolean), if the Opportunity's Amount is greater than 5000
False (Boolean), if the Opportunity's Amount is less than or equal to 5000
<=, le Less than or equal to ${12 <= 3}
False (Boolean)
>=, ge Greater than or equal to ${Opportunity.Amount >= 500}
True (Boolean), if Opportunity’s Amount is at least 500.
Empty empty Checks whether a value is null, an empty string
or has no items (Collection) or entries (Map)

${empty Opportunity.Amount}
True (Boolean), if Opportunity’s Amount is not defined.
Conditional A ? B : C If A resolves to Boolean 'true', the resolved value is B, otherwise the
resolved value is C

${(12 < 1) ? ‘Bear’ : ‘Duck’}
"Duck" (String)

Methods

To use a method in an expression, place a dot after a value - typically a variable - and then the name of the method followed by parenthesis, eg. ${sampleCollection.size()}. If the method requires parameters, place the variables or values to act as parameters separated by commas inside the parenthesis, eg. ${nameString.substring(0,5)} or ${nameString.substring(start,end)}. Many of these methods can also be written in a shorthand form; typically methods starting with "get" or "is" without parameters can be written without that word and the parenthesis, so ${loopStatus.getCount()} for example is equivalent to ${loopStatus.count}. The methods that can be written in this compact form have it mentioned in their documentation along with an example.

However, do note that an expression using a variable's method is guaranteed to fail should the value of that variable be null. As null represents an undefined value, it cannot execute a method and therefore causes an expression error. Try to only use methods with variables that are certain to not be null, or use them inside conditional blocks that specifically check that the method-performing variables are not null.  

The table below highlights some of the more common methods, find the rest along with examples in the value types' own articles. Like operators, method names are also case-sensitive but instead of being entirely in lowercase, names with multiple words have the starting letter of the words aside from the first capitalized ie. they're in camel case.

Value Type Method Example use case Example expression Example result
Collection contains() Test whether a Collection in the variable "countries" has the value of the Account record's Billing Country field as one of its items. ${countries.contains(Account.BillingCountry)} If Billing Country field's value is for example "Denmark", the expression returns true if 'Denmark' is in the Collection, otherwise false.
Date
plusDays()
You need a Date value that is 30 days in the future.
${today.plusDays(30)}
If the value of "today" was 1.10.2018, the resolved value would be 31.10.2018.
String replace() You have the name of a company branch, consisting of the company name and the region the branch is in. You'd like to just have region name without the company name.  ${branch.Name.replace('Dynamo ','')} If the name is "Dynamo Dynapolis", the "Dynamo " is replaced with nothing, so the resolved value will be "Dynapolis".
startsWith()
Test whether the value of the variable "businessType" begins with the characters "B2B".
${businessType.startsWith('B2B')}
If the value of "businessType" variable starts with "B2B", the resolved value is true, otherwise false.
toUpperCase() / toLowerCase() The name of a product in the variable "productName" is needed entirely in uppercase or lowercase. ${productName.toUpperCase()}
${productName.toLowerCase()}
If the name is "EL-Resolver", the resolved values would be "EL-RESOLVER" and "el-resolver".
UserInfo getUserId() You'd like to query fields of the template-running user's User record, which requires the Id of the record. ${UserInfo.getUserId()} The Id of an User record, such as "00533000000X78wha7".