Template Syntax
Lumen templates are HTML with a small expression layer: variables, conditionals, loops, and component tags. No build step, no client runtime — what renders is what you wrote.
Variables
<h1>{{ title }}</h1>
<p>By {{ data.author.name }}</p>
Dotted paths traverse nested objects. Missing values render as empty strings — templates never throw on absent data.
Available variables
| Variable | Scope | Description |
|---|---|---|
{{ title }} | Page + Layout | The page title |
{{ content }} | Layout | The rendered page HTML |
{{ data.* }} | Page + Layout | Resolved data sources |
{{ params.* }} | Page + Layout | URL path parameters (e.g. /blog/:slug → params.slug) |
{{ query.* }} | Page + Layout | URL query string parameters |
{{ body.* }} | Page + Layout | Parsed POST body (when validation rules define body) |
{{ request.path }} | Page + Layout | Current URL pathname |
{{ request.origin }} | Page + Layout | Scheme + host |
{{ app.name }} / {{ app.url }} | Everywhere | App config from APP_NAME / APP_URL |
{{ this.* }} | Inside {{#each}} | Current item in a loop |
Conditionals
{{#if data.featured}}
<article>Featured: {{ data.featured.title }}</article>
{{else}}
<p>Nothing featured.</p>
{{/if}}
Supported operators: ==, !=, >, <, >=, <=, contains, startsWith, endsWith.
{{#if data.post.status == "published"}}Visible{{/if}}
{{#if data.tags contains "tech"}}Tech{{/if}}
Loops
<ul>
{{#each data.posts}}
<li><a href="/blog/{{this.slug}}">{{this.title}}</a></li>
{{/each}}
</ul>
Components
{{ component name:"hero" }}
{{ component name:"feature-card" props:this }}
Components receive the full context (data, params, query, request). Props merge in order: context → default_props → explicit props. See Components.
Active navigation links
Combine request.path with conditionals to highlight the current page:
<a href="/about" class="{{#if request.path == "/about"}}active{{/if}}">About</a>
<a href="/blog" class="{{#if request.path startsWith "/blog"}}active{{/if}}">Blog</a>
Raw HTML injection
Page and layout templates can inject raw HTML into the document shell via the head_html and body_html fields, exposed in templates as {{ head_html }} and {{ body_html }}. Page-specific CSS and JS fields are injected automatically before </head> and </body>.