Transform your data inline with the pipe syntax. Uppercase text, create URL slugs, format numbers, escape HTML, and more — all without writing JavaScript.
Add a pipe | after a variable name to transform its value:
{{ variableName | filterName }}
<script data>
({ title: "hello world" })
</script>
<h1>{{ title | uppercase }}</h1>
<!-- Output: <h1>HELLO WORLD</h1> -->
| Filter | Input | Output | What It Does |
|---|---|---|---|
uppercase |
"hello world" |
"HELLO WORLD" |
Converts all characters to uppercase |
lowercase |
"HELLO" |
"hello" |
Converts all characters to lowercase |
capitalize |
"hello world" |
"Hello world" |
Capitalizes the first letter |
trim |
" hello " |
"hello" |
Removes leading/trailing whitespace |
slugify |
"Hello World!" |
"hello-world" |
URL-safe slug (lowercase, hyphens) |
reverse |
"hello" |
"olleh" |
Reverses the string |
length |
"hello" |
5 |
Returns string/array length |
json |
{ a: 1 } |
'{"a":1}' |
JSON.stringify() |
escape |
"<div>" |
"<div>" |
HTML entity escaping |
truncate |
"A very long..." |
"A very lo..." |
Truncates to 100 chars with "..." |
number |
1234567 |
"1,234,567" |
Locale-formatted number |
encode |
"hello world" |
"hello%20world" |
URI-encodes the string |
<script data>
({ title: "OrbLayout Is Amazing" })
</script>
<h1>{{ title | uppercase }}</h1> <!-- ORBLAYOUT IS AMAZING -->
<p>{{ title | lowercase }}</p> <!-- orblayout is amazing -->
<a href="/posts/{{ title | slugify }}">Link</a> <!-- /posts/orblayout-is-amazing -->
<p>Length: {{ title | length }}</p> <!-- 20 -->
<script data>
({
price: 1299999,
searchQuery: "hello world & more",
userInput: "<script>alert('xss')</script>"
})
</script>
<p>Price: ${{ price | number }}</p> <!-- $1,299,999 -->
<a href="/search?q={{ searchQuery | encode }}">Search</a> <!-- URL-safe -->
<p>{{ userInput | escape }}</p> <!-- Safe from XSS -->
Chain multiple filters together with additional pipes. They execute left to right:
<!-- " Hello World " → "Hello World" → "HELLO WORLD" -->
{{ title | trim | uppercase }}
<!-- "My Blog Post Title" → "my-blog-post-title" -->
{{ title | slugify }}
<!-- "hello" → "Hello" → reverse → "olleH" -->
{{ name | capitalize | reverse }}
Think of pipes like a factory line: data enters from the left, gets transformed by each filter in sequence, and the final result is output.
<script data>
({
posts: [
{ title: "Getting Started with OrbLayout" },
{ title: "10 Tips for Better Static Sites" },
{ title: "Why Components Matter" }
]
})
</script>
{{#each posts}}
<a href="/blog/{{ title | slugify }}">
{{ title }}
</a>
{{/each}}
Result:
<!-- Always escape user input to prevent XSS -->
<div class="comment">
<p>{{ userComment | escape }}</p>
</div>
<!-- Format large numbers -->
<p>Downloads: {{ downloads | number }}</p>
<!-- 1500000 → "1,500,000" -->
<!-- Debug: see raw data -->
<pre>{{ config | json }}</pre>
<!-- {"pagesDir":"pages","minify":false} -->
<!-- Truncate long text -->
<p>{{ longDescription | truncate }}</p>
<!-- "Lorem ipsum dolor sit amet..." (max 100 chars) -->
Need a filter that doesn't exist? Register your own using the Node.js API:
const { loadConfig, OrbCompiler, OrbBuilder } = require("orblayout");
const config = loadConfig(process.cwd());
const compiler = new OrbCompiler(config);
// Register custom filters
compiler.registerFilter("shout", value => value + "!!!");
compiler.registerFilter("emoji", value => "🔥 " + value);
compiler.registerFilter("currency", value => "$" + Number(value).toFixed(2));
// Now use them in .orb files:
// {{ title | shout }} → "Hello!!!"
// {{ name | emoji }} → "🔥 Dan"
// {{ price | currency }} → "$9.99"
Custom filters are covered in depth in Lesson 9: CLI & Tooling. This is a preview!
You should now be able to:
{{ variable | filter }}{{ var | trim | uppercase }}escape, slugify, number, and encode