Velocity component
The
velocitycomponent renders an Apache Velocity (VTL) template against the message and sets the rendered text as the new body.
Scheme: velocity: · Crate: cameleer-core · Cargo feature: templates · Consumer: no · Producer: yes ·
Apache Camel: Velocity
When to use it
- Render emails, notifications and reports from a message with loops and conditions.
- Build a few-shot prompt for a model: loop over example pairs and append the new input.
- Reuse Velocity templates from an existing Java Camel application.
URI format
velocity:templateResource[?options]templateResource is a file path relative to the working directory, file:path,
classpath:path (read as a relative path) or ref:beanName (a String in the registry).
Example
A few-shot classification prompt: the examples come from the request, the count from
$foreach.count, and the instruction changes with a header.
#set($n = $body.examples.size())
Classify the sentiment. $n examples follow.
#foreach($e in $body.examples)
$foreach.count. "$e.text" => $e.label
#end
Text: "$body.input"
#if($headers.strict == "true")
Answer with exactly one word.
#end- route:
id: velocity-few-shot
from:
uri: direct:velocity-few-shot
steps:
- unmarshal:
json: {}
- setHeader:
name: strict
constant: "true"
- to: velocity:templates/few-shot.vm{"examples":[{"text":"Great support, thanks!","label":"positive"},{"text":"Still broken after a week.","label":"negative"}],"input":"The update fixed it."}Classify the sentiment. 2 examples follow.
1. "Great support, thanks!" => positive
2. "Still broken after a week." => negative
Text: "The update fixed it."
Answer with exactly one word.Supplemental context
The CamelVelocitySupplementalContext header (a map) adds entries to the data model; the
CamelVelocityContext header replaces it entirely.
Hello $name from $team, quiet missing value: [$!missing]- route:
id: velocity-supplemental
from:
uri: direct:velocity-supplemental
steps:
- setHeader:
name: CamelVelocitySupplementalContext
simple: "${map('name','Ada','team','platform')}"
- to: velocity:templates/hello.vmignoredHello Ada from platform, quiet missing value: []Rust DSL
b.from("direct:velocity-rust")
.set_header("CamelVelocitySupplementalContext", simple("${map('name','Ada','team','ops')}"))
.to("velocity:templates/hello.vm");Options
| option | default | description |
|---|---|---|
allowTemplateFromHeader | false | Use the CamelVelocityTemplate / CamelVelocityResourceUri headers when present. |
contentCache | false | Read the template once; otherwise it is re-read for every message. |
allowContextMapAll | false | Add camelContext (with name) to the data model. |
encoding | UTF-8 | Accepted; templates are always read as UTF-8. |
loaderCache, propertiesFile | Accepted and ignored (Java Velocity settings). |
The data model: $body, $headers, $variables, $exchange ($exchange.properties,
$exchange.exchangeId, $exchange.getIn().getHeader("x")), $request / $in, and
$camelContext with allowContextMapAll=true.
Supported VTL
References $x, ${x}, quiet $!x, properties, method calls ($s.toUpperCase(),
$headers.get("x")), index access $list[0] and $map["k"]; #set, #if/#elseif/#else,
#foreach with $foreach.count/index/hasNext/first/last, #break, #stop, #macro and
calls, #include, #parse, #evaluate, #define, comments ## and #* *#, unparsed
blocks #[[ ]]#, escapes, arithmetic, comparisons and logical operators. Conditions follow
Velocity 2: null, false, empty strings, empty collections and zero are false.
Known difference: a #end line directly followed by another directive line (such as
#if(...)) can leave an empty line in the output where Velocity 2 removes both lines. Put a text line between the two directives, as the example does.
Message headers
| header | direction | description |
|---|---|---|
CamelVelocityTemplate | in | Template text used instead of the resource (needs allowTemplateFromHeader=true). |
CamelVelocityResourceUri | in | Template resource used instead of the endpoint's one (needs allowTemplateFromHeader=true). |
CamelVelocityContext | in | A map used as the whole data model. |
CamelVelocitySupplementalContext | in | A map merged into the data model. |
Run it with Docker
docker run --rm -v "$PWD:/routes:ro" pmsudhi/cameleer run /routes/few-shot.camel.yamlCommon questions
How do I print nothing for a missing value?
Use a quiet reference: $!name. A plain $name that is null renders as the literal text
$name, as in Velocity.
How do I get the loop index?
$foreach.count starts at 1, $foreach.index at 0; $foreach.hasNext helps with
separators.
Can I pass extra values without changing the body?
Yes: set CamelVelocitySupplementalContext to a map (for example with Simple's
${map(...)}), and its keys become top-level template variables.
Related
- Mustache, FreeMarker, StringTemplate, MVEL.
- Simple language for the
map(...)function. - Apache Camel Velocity component
Found a problem?
If something on this page doesn't match what Cameleer does, or you hit a bug while building
with it, please help fix it, whether you are a person or a coding agent:
open an issue that describes what you saw,
then fork the repository, fix it, add or update a test, run cargo test --workspace, and open
a pull request. CONTRIBUTING.md
explains the ground rules.