Templating
Quick Answer
Use this reference for Breyta Handlebars templating syntax, helpers, and practical template composition patterns.
Breyta Flows templates use Handlebars ({{...}}) via the Java implementation (handlebars-java).
Basics
| Pattern | Syntax | Use |
|---|---|---|
| Variables | {{id}}, {{user.name}} | Read scalar or nested fields from input data. |
| Conditionals | {{#if condition}}...{{/if}}, {{#unless condition}}...{{/unless}} | Branch rendered content based on truthy/falsey values. |
| Loops | {{#each items}}...{{/each}} | Render repeated blocks from arrays/lists. |
| Context switch | {{#with obj}}...{{/with}} | Temporarily scope lookup to a nested object. |
Custom helpers available
These helpers are available in the Flows runtime:
| Helper | Example | Behavior |
|---|---|---|
truncate | {{truncate text length=100 suffix="..."}} | Truncates text to a max length with optional suffix. |
json | {{json data}}, {{json data pretty=true}} | Serializes values to compact or pretty JSON. |
length | {{length items}} | Returns collection/string length. |
join | {{join items separator=", "}} | Joins list values with a separator. |
first | {{first items}} | Returns first element from a collection. |
last | {{last items}} | Returns last element from a collection. |
default | {{default value fallback}} | Returns fallback when value is missing/empty. |
Practical examples
LLM prompt template
{:id :findings
:type :llm-prompt
:system "Today is {{current-date}}."
:prompt "Analyze: {{text}}"}
Called as:
(flow/step :llm :findings {:connection :ai
:template :findings
:data {:current-date "2026-01-16"
:text "..."}})
Choosing between templates
When conditional logic gets messy, prefer two templates and select one in code:
(let [tpl ^{:label "Template variant"
:yes "Include timestamps"
:no "No timestamps"}
(if (:include-timestamps? ctx) :findings-with-ts :findings-no-ts)]
(flow/step :llm :findings {:connection :ai :template tpl :data ctx}))