CEL syntax reference
Contents
CEL syntax reference#
This guide is for implementers who need detailed syntax documentation.
Expression types#
Expressions in OpenSPP are categorized by type:
Type |
Output |
Use case |
|---|---|---|
Filter |
Boolean |
Select records (eligibility, search, compliance) |
Formula |
Number |
Calculate amounts (entitlements, benefits) |
Scoring |
Number |
Scoring indicator formulas |
Data Validation |
Boolean |
Data validation rules |
Other |
Any |
Library/utility expressions |
Basic syntax#
Literals#
Type |
Examples |
|---|---|
Boolean |
|
Number |
|
String |
|
Null |
|
Operators#
Comparison#
Operator |
Example |
Description |
|---|---|---|
|
|
Equal |
|
|
Not equal |
|
|
Less than |
|
|
Less than or equal |
|
|
Greater than |
|
|
Greater than or equal |
Logical#
Operator |
Alternative |
Example |
|---|---|---|
|
|
|
|
|
|
|
|
|
Arithmetic#
Operator |
Example |
Description |
|---|---|---|
|
|
Addition |
|
|
Subtraction |
|
|
Multiplication |
|
|
Division |
|
|
Modulo |
Safe field access#
Use has() to check if a field exists before accessing:
has(r.birthdate) and age_years(r.birthdate) >= 18
Built-in functions#
Date/time functions#
Function |
Example |
Description |
|---|---|---|
|
|
Years since date |
|
|
Date n days ago |
|
|
Date n months ago |
|
|
Date n years ago |
|
|
Current date |
|
|
Current datetime |
Math functions#
Function |
Example |
Description |
|---|---|---|
|
|
Minimum value |
|
|
Maximum value |
|
|
Absolute value |
String functions#
Function |
Example |
Description |
|---|---|---|
|
|
Check prefix |
|
|
Check substring |
|
|
Regex match |
|
|
String/collection length |
Utility functions#
Function |
Example |
Description |
|---|---|---|
|
|
Check if value is in range |
Collection functions#
Used with relations like members, enrollments, entitlements:
Function |
Example |
Description |
|---|---|---|
|
|
Any match |
|
|
All match |
|
|
Count matches |
|
|
Sum values |
|
|
Filter list |
|
|
Check if member is head of household |
Existence check#
Function |
Example |
Description |
|---|---|---|
|
|
Field exists and not null |
Collection predicates#
When using collection functions, predicates reference items with a loop variable:
members.count(m, age_years(m.birthdate) < 5)
members.exists(m, head(m) and m.gender == "female")
enrollments.exists(e, e.state == "enrolled")
The loop variable (m, e, etc.) represents each item in the collection.
Note
Newer syntax may omit the explicit loop variable:
members.count(age_years(m.birthdate) < 5)
Both forms are supported.
Profiles and symbols#
What are profiles?#
Profiles define what data is available in a given context:
The root model ("current record")
Related collections
Available functions
Default profiles#
Profile |
Root Model |
Available Relations |
|---|---|---|
|
|
|
|
|
|
|
|
- |
|
|
- |
|
|
- |
Root record symbol#
All profiles provide access to the current record via the r symbol:
Symbol |
Description |
|---|---|
|
Current record (registrant, ticket, entitlement, etc.) |
Example:
r.is_registrant == true and r.active == true
Note
The symbol r represents the current record in all contexts. Inside aggregate functions (like counting members), use m to reference each member.
CEL editor widget#
The Studio CEL editor provides:
Autocomplete#
Type
r.to see available fields on the current recordType a function name to see its signature
Press Ctrl+Space to trigger suggestions
See CEL quick start for a screenshot of the autocomplete feature.
Symbol browser#
Click the Symbols button to browse:
Available profiles
Symbols and fields
Variables
Functions
See CEL quick start for a screenshot of the symbol browser.
Validation#
Real-time validation shows:
Syntax errors (red underlines)
Unknown symbols
Type mismatches
Matching record count (for compile-to-domain expressions)
Validation API#
For developers, the widget calls these endpoints:
Endpoint |
Purpose |
|---|---|
|
List available profiles |
|
Get symbols for profile |
|
Validate expression |
CEL execution modes#
Compile-to-domain#
Used for record selection (eligibility, search):
Supports profile symbols and relations
Compiles to Odoo domain (SQL-optimized)
Shows matching count in editor
Runtime evaluation#
Used for value computation (amounts, routing):
Works with provided context dictionary
Supports arithmetic and comparisons
No ORM access
Feature |
Compile-to-Domain |
Runtime |
|---|---|---|
Profile symbols |
✓ |
Limited |
Relations (members) |
✓ |
✗ |
Matching count |
✓ |
✗ |
Arithmetic |
✓ |
✓ |
Context variables |
✓ |
✓ |
Are you stuck?#
"Unknown symbol" error?
Check the profile matches your context (individual vs group)
Use autocomplete to find the correct field name
Verify variables are active
Expression validates but matches 0 records?
Verify the base population (individuals vs groups)
Check member relations exclude ended memberships
Ensure event data exists if using event functions
Need more help?
See CEL troubleshooting for common issues
See Variables for variable configuration
openspp.org