Summary
The following page outlines complex functions and advanced usage examples.
For a list of all Context Variables available, see the full Expression Language Index.
Search & Expression Example (#expr)
General-purpose helper functions for:
- Searching (e.g., Solr queries)
- Finding items (e.g., by path)
- User/group lookups
Examples of #expr for Searching & Filtering
| Expression | Description | Notes |
#expr.find(#item.id) | Find item by ID | Returns object or null |
#expr.find(#item.ancestors?.get(0).id) | Return parent folder object when item is a FILE | Returns object or null |
#expr.find(#item.ancestors?.get(1).id) | Return parent folder object when item is a FOLDER, FORM, or ISSUE | Returns object or null |
#expr.findByPath('path') | Find by path "/home/folder1/" | Exact match required |
| #expr.findByPath( ‘path’, true ) | Try to find item by path in BR and/or create item and path if non-existent | |
| #expr.entitySearch( #item.createdBy, '#entities')[0] | Find item creator by Entity ID | Returns entity object (team, user, company) |
| #expr.isMemberOf('Developers') | Returns true if the current user logged in is a member of the listed Teams, in this case the team “Developers”. False otherwise. | |
| #expr.dateFormat( new java.util.Date(), 'yyyy-MM-dd HH:mm:ssZ' ) | Evaluate to current date | |
#expr.search(term, field) | Programmatic solr query search | Not always real-time |
#expr.count(list, condition) | Check if a list of items satisfy a condition. Returns a Count of matches. | Safe for empty list |
#expr.any(list, condition) | Check if a list of items satisfy a condition. Returns boolean TRUE if any match. | False if empty |
#expr.all(list, condition) | Check if a list of items satisfy a condition. Returns boolean TRUE if all match. | True if empty |
#expr.none(list, condition) | Returns boolean TRUE if none match. | Opposite of any |
| (( #expr.dataSetSearch( <DATASET_ID>, "#dataSet.data.?[( #this.cells['Col1Title'] == 'ABC' || #this.cells['Col2Title'] == 'Chapter 2' || #this.cells['Col3Title'] == 'Author') && #this.cells[#Col4] == 'Yes' ].![cells['Col5']]") )) | Using a dataset ID, lookup multiple column values in a dataset (Can use AND '&&' or OR '||' symbols) (ie (Col1 || Col2 || Col3) && Col4), and return the corresponding values found in Col5. | May return multiples if multiple rows are matched |
Collections & List Example (#list)
ListUtil is used for working with collections (lists of objects).
General-purpose helper functions for:
- Finding items (e.g., by path)
- Converting or transforming values
| Expression | Description | Notes |
|---|---|---|
#list.explode(string, delimiter)eg. (( list.explode('a|b|c', '|') )) | Takes a string and returns a list, split by the delimiter. | eg Returns a list with items "a","b","c" |
#list.explodeProperty(collection, property)eg. #list.explodeProperty(#folder.items, 'title') | Collection -> List of a specific property. | eg Return a list of item titles from all items in a folder |
#list.implode(list, ',')eg. (( #list.implode(#item.ancestors.![title], ',') )) | List → string | Safe on empty list |
#list.findBy(list, field, value)eg. (( #list.findBy( #item.items, ‘status’, ‘New’ ) )) | Filter list. eg Finds all the child items that have a status of New | Returns list. To pick a file/folder for the user to process based on status. |
#list.findUniqueBy(...)eg. (( #list.findUniqueBy( #item.items, ‘status’, ‘New’ ) )) | Unique match. eg Finds one child item that have a status of New | Fails if multiple |
| ((#list.implode(#list.explodeProperty( #list.reverseList(#item.ancestors), 'title' ), '/'))) Save above to Context Variable then use the below to remove “Home/” and filename from path: ((#path_long.substring(5, #path_long.length()-#filename.length()))) |
MapUtil (#map)
Used for working with key-value structures.
Less commonly used, but useful when dealing with structured or nested data such as attributes
Key Tips
- Always wrap expressions with
(( )) - Use
#to reference objects - Use dot notation for properties
- Use helper functions for complex logic
- Check context to know what data is available
- Full Appendix of Context Variables are listed here: https://support.bluerelay.com/en/support/solutions/articles/22000295803-spel-expression-language-full-appendix
Basic Example
Get File Title
((#file.title))
Get Current User Name
((#user.name))
Advanced Examples
1. Property Access & Chaining
Access Nested Properties
#item.ancestors[0].idRetrieves a nested value by chaining object properties.
Safe Access Pattern (Check Before Use)
#item.ancestors != null ? #item.ancestors[0].id : ''
Prevents errors when a property might not exist. This allows an event to move forward and not exit if a step fails.
2. Conditional Logic
Simple Condition
Return true if item.status = Active
#item.status == 'Active'Check if a Value Exists
((#form.questionsMap['approval'].answers[0].content != null))
Conditional (Ternary)
If item.status = Active, then return "Open", otherwise "Closed"
#item.status == 'Active' ? 'Open' : 'Closed'
Multiple Conditions
#item.status == 'Active' && #item.priority == 'High'
Null Checks
#item.attributes != null
3. Working with Forms
Get Answer Value
This examples references the question using it's alias 'q1'.
To assign an alias, go to the form question configuration -> see Advanced to assign the Alias
#form.questionsMap['q1'].answers[0].content
Conditional Form Logic
#form.questionsMap['q1'].answers[0].content == 'Yes'
Used for:
- Showing/hiding questions
- Validation rules
Check if Answer Exists
#form.questionsMap['q1'].answers.size() > 0
4. List Operations (#list)
Extract Property from List
#list.explodeProperty(#folder.items, 'title')
Returns a list of file titles under a folder.
Extract Nested Property
#list.explodeProperty(#folder.items, 'owner.name')
Filter-Like Pattern (via condition)
#folder.items.?[#this.status == 'Active']
Returns only matching items.
Get First Item
#folder.items[0]
5. Search & Data Retrieval (#expr)
Basic Search
Return the parent folder when item is a FILE
#expr.find( #item.ancestors[1].id )Return the parent folder when item is a FOLDER, FORM, or ISSUE
#expr.find( #item.ancestors[0].id )Find by Path
#expr.findByPath('/Projects/Example/File.txt')
Entity Search (Users / Groups)
#expr.entitySearch( #item.createdBy, '#entities')[0].username
6. Working with Dates & Time
Convert String to Time
#expr.stringToTime('2024-01-01')
Compare Dates
#item.dueDate > #expr.stringToTime('2024-01-01')
7. Combining Data
Build Dynamic Values
#file.title + ' - ' + #user.name
8. Map Operations (#map)
Access Value by Key
Return a mapping of all file names under a folder. Assuming the item in context is a folder.
#map.get(#item.ancestors, 'title')
Check Key Exists
#map.containsKey(#item, 'activeTasks')
9. Common Patterns
Default Value Fallback
#item.description != null ? #item.description : 'N/A'
Boolean from Text
#form.questionsMap['q2'].answers[0].content == 'Yes'
10. Quick Copy Examples
| Expression / Variable | Description |
|---|---|
| #item != null and #item.status == "Approved" | Basic item status check |
| #item.attributes["DocumentType"] != null and #item.attributes["DocumentType"].value == "Contract" | Attribute value check |
| #item.activeTasks.size() > 0 and #item.activeTasks[0].subject == "Review" | Active task check |
| #item.activeForms.size() > 0 and #item.activeForms[0].questionsMap["risk_level"] != null | Active form question check |
| #question.label == "Priority" and #answer.display == "High" | Question/answer check |
| #statusCode == 200 and #response != null | Web service output check |
| #rowsCreated > 0 or #rowsModified > 0 | Dataset upload result check |
| #result.status == "SUCCESS" | Previous action outcome check |
Key Takeaways
- Use dot notation for object navigation
- Use ternary conditions for safe fallbacks
- Use
#listfor collections - Use
#exprfor search and dynamic data - Always consider null safety in advanced expressions