Syntax
Expression Language uses JavaScript-like syntax designed to be intuitive for both designers and developers. Optimized for visual development workflows. Understanding these syntax rules is essential for writing valid expressions that transform and process your WordPress data effectively across all Builderius contexts.
Basic Expression Structure
All expressions follow consistent syntax patterns:
Context-Specific Wrappers
- Element Content, Attributes & Component Properties:
[[expression]]- Same like dynamic data access - Loop Content:
{{expression}}- Current loop item data - GraphQL Queries:
expression_result(expression: "...")- No wrapper needed - Condition Builder: Raw expression - No wrapper needed
Single-Line Requirement
# Correct - single line
[[upper(limit_characters(post_title, 50, '...')]]
# Error - multiple lines not allowed
[[upper(
limit_characters(post_title, 50, '...')
)]]
Data Access Syntax
Expressions use "dot notation" to access dynamic data. If the field is a sibling to the expression, then a simple field_name is used, if the sibling sub-field should be selected field_name.sub_fieldname is used, and if the field is in another scope full path should be used, for eg. wp.post.title.
| Access Type | Syntax | Example | Description |
|---|---|---|---|
| Field Access | field_name | post_title | Direct field reference |
object.property | current_user.display_name | Object property access | |
wp.scope.field | wp.post.post_title | WordPress context data | |
| Array Access | array[index] | posts[0] | First array item |
array[index].field | categories[1].name | Array item property | |
wp.query.array[0].field | wp.posts_query.posts[0].post_title | WordPress array data | |
| Object Properties | parent.child.grandchild | post_author.display_name | Nested property access |
complex.nested.path | featured_image.alt_text | Deep object nesting | |
wp.context.nested.data | wp.archive.term.parent.name | WordPress nested data |
Function Call Syntax
Functions transform and process data using parentheses syntax function_name(arguments). Functions can be nested inside other functions, and arguments can be literal values, variables, or other function results.
| Function Type | Syntax | Example | Description |
|---|---|---|---|
| Simple Functions | function() | time() | No arguments needed |
function(value) | upper('hello world') | Single argument | |
function(variable) | count(posts) | Variable as argument | |
| Multiple Arguments | function(arg1, arg2) | limit_words(post_content, 25) | Two arguments |
function(arg1, arg2, arg3) | limit_words(text, 25, '...') | Three arguments | |
function(string, number, boolean) | has_term('featured', 'category', post_id) | Mixed argument types | |
| Nested Functions | outer(inner(value)) | upper(limit_words(post_title, 5)) | Function as argument |
function(nested(args), value) | sprintf('$%.2f', round(price, 2)) | Mixed nested and direct | |
complex(nested(chain())) | join(sort(split(tags_string, ',')), ' • ') | Multiple nesting levels |
Data Types and Values
Expressions work with different data types that represent various kinds of information. String values must be quoted, numbers are written directly, and arrays use square brackets. Understanding data types ensures your expressions process values correctly.
| Data Type | Syntax | Example | Usage |
|---|---|---|---|
| Strings | 'text' or "text" | 'Hello World' | Text values, must be quoted |
'escaped\'quote' | 'It\'s working' | Escape quotes inside strings | |
variable ~ ' text' | first_name ~ ' ' ~ last_name | String concatenation | |
| Numbers | 123 | 45.67 | Integers and decimals |
-10 | 0 | Negative and zero values | |
price + tax | quantity * unit_price | Mathematical operations | |
| Booleans | true or false | is_logged_in | True/false values |
expression > value | count(posts) > 0 | Boolean expressions | |
function() | is_user_logged_in() | Boolean-returning functions | |
| Arrays | [item1, item2] | [1, 2, 3, 4, 5] | Lists of values |
['text', 'values'] | ['apple', 'banana', 'orange'] | String arrays | |
variable[index] | posts[0] | Array item access |
Operators
Operators combine and compare values to create logical expressions. Use comparison operators to test conditions, logical operators to combine multiple conditions, and arithmetic operators for calculations. String concatenation joins text values together.
| Operator Category | Usage Pattern | Example | Purpose |
|---|---|---|---|
| Comparison | value operator value | price == 100 | Test equality |
variable != value | post_status != 'draft' | Test inequality | |
number > threshold | quantity > 5 | Numeric comparisons | |
| Logical | condition and condition | is_logged_in and has_permission | Combine conditions with AND |
condition or condition | is_admin or is_editor | Combine conditions with OR | |
not condition | not is_guest | Negate condition | |
| Arithmetic | number + number | base_price + shipping | Mathematical operations |
(expression) operator value | (price * quantity) + tax | Use parentheses for order | |
variable ** power | base_amount ** growth_rate | Exponentiation | |
| String | text ~ text | first_name ~ ' ' ~ last_name | Join strings together |
prefix ~ variable ~ suffix | 'Hello, ' ~ user_name ~ '!' | Build dynamic text | |
expression ~ string | count(items) ~ ' items found' | Combine values and text |
Conditional Logic
Conditional logic enables decision-making in expressions using ternary operators for if/then/else logic and null coalescing for fallback values. These patterns let expressions adapt their output based on data conditions.
- Ternary Operator
- Null Coalescing
The condition ? true_value : false_value pattern provides if/then/else logic:
# Check user login status and display appropriate greeting
is_logged_in ? 'Welcome back!' : 'Please log in'
# Compare price value and assign category label
price > 100 ? 'Premium' : 'Standard'
# Nested conditional logic to determine user role display text
user_role == 'admin' ? 'Administrator' : (user_role == 'editor' ? 'Editor' : 'User')
# Multiple conditions with string concatenation for product availability
(inventory > 0) and (price > 0) ? 'Available - $' ~ price : 'Out of Stock'
The ?? operator provides fallback values for null/undefined data:
# Use custom_title if it exists, otherwise fall back to post_title
custom_title ?? post_title
# Check alt_text first, then post_title, finally use 'Image' as last resort
featured_image.alt_text ?? post_title ?? 'Image'
# Get user bio from meta or show default message if empty
get_user_meta('bio') ?? 'No bio available'
# Priority chain: custom excerpt, then post excerpt, then truncated content
acf_value('custom_excerpt') ?? post_excerpt ?? limit_words(post_content, 25)
Advanced Syntax Patterns
Arrow Functions
- Syntax
- Example
- JSON Output
Arrow functions use the pattern (parameter) -> expression for array processing functions:
# Filter posts array to only include items with 'publish' status
filter(posts, (post) -> post.post_status == 'publish')
# Extract only the name property from each category object into a new array
foreach(categories, (cat) -> cat.name)
# Filter products that meet both price and inventory requirements
filter(products, (item) -> item.price > 50 and item.inventory > 0)
Arrow functions transforming related posts data:
{
post {
ID
post_title
# Get related posts (raw data)
related_posts: posts_query(
arguments: {
post_type: "post"
posts_per_page: 10
post__not_in: "{{ID}}"
}
) {
posts @private { # hide the original loop
post_title
post_status
comment_count
post_author {
display_name
}
categories {
name
}
}
}
# Transform related posts with arrow functions
published_related: expression_result(
expression: "filter(related_posts.posts, (post) -> post.post_status == 'publish')"
)
# Extract category names from each post into flat array
all_category_names: expression_result(
expression: "foreach(related_posts.posts, (post) -> foreach(post.categories, (cat) -> cat.name))"
)
# Filter posts that have comments and are published
popular_posts: expression_result(
expression: "filter(related_posts.posts, (post) -> post.comment_count > 0 and post.post_status == 'publish')"
)
}
}
JSON result showing arrow function transformations:
{
"post": {
"ID": 123,
"post_title": "Current Blog Post",
"published_related": [
{
"post_title": "Published Article",
"post_status": "publish",
"comment_count": 5,
"categories": [{"name": "Technology"}, {"name": "WordPress"}]
},
{
"post_title": "Popular Post",
"post_status": "publish",
"comment_count": 12,
"categories": [{"name": "Technology"}, {"name": "Tips"}]
}
],
"all_category_names": [
["Technology", "WordPress"],
["Design"],
["Technology", "Tips"]
],
"popular_posts": [
{
"post_title": "Published Article",
"post_status": "publish",
"comment_count": 5,
"categories": [{"name": "Technology"}, {"name": "WordPress"}]
},
{
"post_title": "Popular Post",
"post_status": "publish",
"comment_count": 12,
"categories": [{"name": "Technology"}, {"name": "Tips"}]
}
]
}
}
WordPress Data Integration
Access WordPress data through the wp context:
# Template context data
wp.post.post_title # Current post data
wp.current_user.display_name # Current user data
wp.archive.title # Archive context
wp.option_value__site_name # WordPress options
# Conditional WordPress data
wp.post ? wp.post.post_title : wp.archive.title
wp.current_user.ID ? 'Logged in' : 'Guest user'
Common Syntax Errors
- Missing Quotes
- Wrong Operators
- Context Wrappers
- Function Arguments
String values must be quoted:
# Error - missing quotes
upper(hello world)
post_status == publish
# Correct - with quotes
upper('hello world')
post_status == 'publish'
Variable references don't use quotes:
# Error - quoted variable names
upper('post_title') # Treats as literal string "post_title"
count('posts') # Treats as literal string "posts"
# Correct - unquoted variables
upper(post_title) # Uses actual post_title value
count(posts) # Uses actual posts array
Assignment vs comparison operators:
# Error - assignment operator
post_status = 'publish' # Tries to assign, not compare
# Correct - comparison operator
post_status == 'publish' # Compares values
# Error - wrong logical operators
is_admin & is_active # Bitwise operator, not logical
is_admin | is_editor # Bitwise operator, not logical
# Correct - logical operators
is_admin and is_active # Logical AND
is_admin or is_editor # Logical OR
Context-appropriate wrappers:
<!-- Element Content -->
<!-- Error - wrong wrapper for element content -->
{{post_title}}
<!-- Correct - global data wrapper -->
[[post_title]]
<!-- Loop Content (inside Collection element) -->
<!-- Error - wrong wrapper for loop content -->
[[post_title]]
<!-- Correct - loop item wrapper -->
{{post_title}}
GraphQL expressions:
# Error - wrapper in GraphQL context
expression_result(expression: "[[upper(post_title)]]")
# Correct - no wrapper needed
expression_result(expression: "upper(post_title)")
Function argument requirements:
# Error - missing required arguments
limit_words(post_content) # Missing word count argument
sprintf(price) # Missing format string
# Correct - all required arguments
limit_words(post_content, 25) # Text and word count
sprintf('$%.2f', price) # Format string and value
# Error - wrong argument types
count('not an array') # String instead of array
upper(123) # Number instead of string
# Correct - proper argument types
count(posts) # Array argument
upper(post_title) # String argument
Syntax Best Practices
Readability
# Good - clear and readable
user_role == 'admin' ? 'Administrator Panel' : 'User Dashboard'
# Harder to read - no spaces
user_role=='admin'?'Administrator Panel':'User Dashboard'
Function Organization
# Good - logical grouping
upper(limit_words(post_title, 5))
# Confusing - unclear order
limit_words(upper(post_title), 5) # Uppercases first, then truncates
Variable Naming
# Good - descriptive field names
is_user_logged_in()
post_author.display_name
# Less clear - abbreviated names
is_logged()
author.name
For detailed information about all available functions, see: Built-in Functions → - Complete function library with examples and usage patterns
For comprehensive operator documentation, see: Operators → - All comparison, logical, and mathematical operators
These syntax rules provide the foundation for writing valid Expression Language code across all Builderius contexts. Master these patterns, and you'll be able to create sophisticated data transformations and conditional logic throughout your templates.