Documentation

Tag: tera

Writing and customizing templates

Writing and customizing templates Everlock uses [Tera](https://keats.github.io/tera/) as its template engine. Tera's syntax is similar to Jinja2 and Django templates. Templates live in the layouts/ directory of your site repository. This page explains the syntax, the context variables available in each template, and common customization patterns. Template syntax basics Output a variable <h1>{{ page.title }}</h1> Double braces output the value of a variable. Any HTML in the value is escaped by default. Output raw HTML safely <div class="content"> {{ page.content | safe }} </div> The | safe filter tells Tera the value is already trusted HTML and should not be escaped. Use this for rendered Markdown content. Conditionals {% if page.git_date %} <p class="meta">Updated {{ page.git_date }}</p> {% endif %} {% if page.tags %} <ul> {% for tag in page.tags %} <li><a href="/tags/{{ tag }}">{{ tag }}</a></li> {% endfor %} </ul> {% endif %} Loops {% for link in site.nav.links %} <a href="{{ link.url }}">{{ link.label }}</a> {% endfor %} Default values <time>{{ p.git_date | default(value=p.date) | default(value="") }}</time> Filters chain left to right. | default(value=x) substitutes x when the left side is empty or undefined. String filters {{ page.title | upper }} {{ tag | replace(from="-", to=" ") | title }} Common Tera filters: upper, lower, title, trim, replace, truncate, length, first, last. Date helpers Everlock adds a small date layer on top of Tera for Markdown sites: <p>Now: {{ now() }}</p> <p>Today: {{ today() }}</p> {% if page.date is before(date=now()) %} <p>This page date is in the past.</p> {% endif %} <time>{{ page.date | date_format(format="%Y-%m-%d") }}</time> Accepted input formats: - YYYY-MM-DD - RFC3339 timestamps such as 2026-06-11T08:30:00Z today() and date-only comparisons use the site timezone from site.toml. If no timezone is set, Everlock falls back to UTC. --- Template inheritance Every template in Everlock extends base.html. The pattern uses {% extends %} and {% block %}: layouts/base.html defines named blocks: <!doctype html> <html> <head> <title>{% block title %}{{ page.title }} | {{ site.title }}{% endblock %}</title> </head> <body> <nav> {% for link in site.nav.links %} <a href="{{ link.url }}">{{ link.label }}</a> {% endfor %} </nav> <main> {% block main %}{% endblock %} </main> </body> </html> layouts/single.html fills in the block: {% extends "base.html" %} {% block main %} <article> <h1>{{ page.title }}</h1> <div class="content">{{ page.content | safe }}</div> </article> {% endblock %} Any block not overridden in the child template renders from the parent. A child can call {{ super() }} to include the parent block's content and then add to it. --- Context variables reference Available in all templates | Variable | Type | Content | |---|---|---| | site.title | string | Site title from site.toml | | site.description | string | Site description from site.toml | | site.base_url | string | Base URL from site.toml | | site.timezone | string | Optional site timezone used by today() and date formatting | | site.nav.links | list | Navigation links, each with .label and .url | | data | map | All .toml files from the data/ directory | In single.html (content pages) | Variable | Type | Content | |---|---|---| | page.title | string | Title from frontmatter | | page.content | string | Rendered HTML of the page body | | page.summary | string | HTML of content before