Expressions
Output variables, access nested values, and control HTML escaping in your templates.
Variable output
Use double curly braces to output a variable. HTML is escaped by default to prevent XSS:
{{ site.name }}
{{ page.title }}If a variable contains <script>alert('xss')</script>, the output will be safely escaped as &lt;script&gt;alert('xss')&lt;/script&gt;.
Raw output
When you need to output unescaped HTML, use the raw syntax:
{!! raw_html !!}HTML escaping
By default, all expressions escape these characters:
&becomes&amp;<becomes&lt;>becomes&gt;"becomes&quot;'becomes&#x27;
This makes {{ }} safe for use in HTML attributes and text content alike:
<a href="{{ link_url }}" title="{{ link_title }}">
{{ link_text }}
</a>Dot notation
Access nested values using dot notation. This works with site configuration, page frontmatter, and any structured data:
{{ site.name }}
{{ site.base_url }}
{{ site.description }}
{{ page.title }}
{{ page.date }}
{{ author.name }}Available variables
Site variables
Every field in the [site] section of tulip.toml is available via the site prefix. The built-in fields are:
{{ site.name }}— the site name{{ site.base_url }}— the base URL{{ site.description }}— the site description
You can add any custom fields and they become available as variables:
[site]
name = "My Blog"
base_url = "https://example.com"
author = "Eduardo"
github = "https://github.com/eduardostuart"Then use them in templates:
<footer>{{ site.author }} — <a href="{{ site.github }}">GitHub</a></footer>Page variables
Frontmatter fields defined at the top of a page or markdown file are available as template variables:
---
title: My Page
date: 2025-01-15
author: Jane
---These become:
{{ title }} <!-- "My Page" -->
{{ date }} <!-- "2025-01-15" -->
{{ author }} <!-- "Jane" -->Expressions in attributes
Expressions work inside HTML attributes just like in text content:
<meta name="description" content="{{ site.description }}">
<body class="{{ page.body_class }}">
<img src="{{ page.image }}" alt="{{ page.title }}">