Functions
Built-in functions for retrieving data and generating URLs in templates.
Data Retrieval
get_page()
Retrieve any page by path or URL:
{% set about = get_page(path="about.md") %}
{% if about %}
<a href="{{ about.url }}">{{ about.title }}</a>
{% endif %}
Parameters:
| Name | Type | Description |
|---|---|---|
| path | String | Relative source path (e.g. about.md) or URL path (e.g. /about/) |
Returns: Page? (nil if not found)
Returned Properties:
| Property | Type |
|---|---|
| title | String |
| description | String? |
| url | String |
| date | String? |
| section | String |
| draft | Bool |
| weight | Int |
| summary | String? |
| word_count | Int |
| reading_time | Int |
Examples:
{# Page in root #}
{% set contact = get_page(path="contact.md") %}
{# Page in section #}
{% set intro = get_page(path="docs/introduction.md") %}
{# Match by URL #}
{% set intro_by_url = get_page(path="/docs/introduction/") %}
get_section()
Retrieve a section by section name, source path, or URL:
{% set blog = get_section(path="blog") %}
{% if blog %}
<h2>{{ blog.title }}</h2>
<ul>
{% for p in blog.pages %}
<li><a href="{{ p.url }}">{{ p.title }}</a></li>
{% endfor %}
</ul>
{% endif %}
Parameters:
| Name | Type | Description |
|---|---|---|
| path | String | Section name (blog), path (blog/_index.md), or URL (/blog/) |
Returns: Section? (nil if not found)
Returned Properties:
| Property | Type |
|---|---|
| title | String |
| description | String? |
| url | String |
| path | String |
| name | String |
| pages | Array<Page> |
| pages_count | Int |
| assets | Array<String> |
Examples:
{# Top-level section #}
{% set docs = get_section(path="docs") %}
{# Nested section #}
{% set guides = get_section(path="docs/guides") %}
{# Match by URL #}
{% set blog = get_section(path="/blog/") %}
{# Display count #}
<p>{{ docs.pages_count }} articles</p>
get_taxonomy()
Access taxonomy terms and their pages:
{% set tags = get_taxonomy(kind="tags") %}
{% if tags %}
<ul class="tag-cloud">
{% for term in tags.items %}
<li>
<a href="/tags/{{ term.slug }}/">
{{ term.name }} ({{ term.count }})
</a>
</li>
{% endfor %}
</ul>
{% endif %}
Parameters:
| Name | Type | Description |
|---|---|---|
| kind | String | Taxonomy name (e.g., "tags", "categories") |
Returns: Taxonomy? (nil if not found)
Returned Properties:
| Property | Type |
|---|---|
| name | String |
| items | Array<Term> |
Term Properties:
| Property | Type |
|---|---|
| name | String |
| slug | String |
| pages | Array<Page> |
| count | Int |
get_taxonomy_url()
Generate URL for a taxonomy term:
<a href="{{ get_taxonomy_url(kind='tags', term='crystal') }}">
Crystal articles
</a>
Parameters:
| Name | Type | Description |
|---|---|---|
| kind | String | Taxonomy name |
| term | String | Term name |
Returns: String (absolute URL)
Data Loading
load_data()
Load external data files (JSON, TOML, YAML, CSV):
{% set menu = load_data(path="data/menu.json") %}
{% for item in menu %}
<a href="{{ item.url }}">{{ item.title }}</a>
{% endfor %}
Parameters:
| Name | Type | Description |
|---|---|---|
| path | String | Path to data file |
Returns: Parsed data or nil
Supported Formats:
| Extension | Format |
|---|---|
| .json | JSON |
| .toml | TOML |
| .yaml, .yml | YAML |
| .csv | CSV (array of arrays) |
Examples:
JSON (data/team.json):
[
{"name": "Alice", "role": "Developer"},
{"name": "Bob", "role": "Designer"}
]
{% set team = load_data(path="data/team.json") %}
<ul>
{% for member in team %}
<li>{{ member.name }} - {{ member.role }}</li>
{% endfor %}
</ul>
TOML (data/social.toml):
[[links]]
name = "Twitter"
url = "https://twitter.com/example"
{% set social = load_data(path="data/social.toml") %}
{% for link in social.links %}
<a href="{{ link.url }}">{{ link.name }}</a>
{% endfor %}
Environment
env()
Read environment variables in templates:
{{ env("ANALYTICS_ID") }}
{{ env("API_KEY", default="none") }}
Parameters:
| Name | Type | Description |
|---|---|---|
| name | String | Environment variable name |
| default | String? | Fallback value if variable is unset (optional) |
Returns: String (env var value, default, or empty string)
If the variable is not set and no default is provided, an empty string is returned and a build warning is logged.
Examples:
{# Google Analytics #}
{% if env("GA_ID") %}
<script async src="https://www.googletagmanager.com/gtag/js?id={{ env("GA_ID") }}"></script>
{% endif %}
{# API endpoint with fallback #}
<script>
const API = "{{ env("API_URL", default="https://api.example.com") }}";
</script>
URL Functions
url_for()
Generate URL with base_url:
<a href="{{ url_for(path='/about/') }}">About</a>
<img src="{{ url_for(path='/images/logo.png') }}">
Parameters:
| Name | Type | Description |
|---|---|---|
| path | String | Path to convert |
Returns: String (absolute URL)
get_url()
Alias for url_for(). You can use either name:
<a href="{{ get_url(path='/about/') }}">About</a>
now()
Get current datetime:
{# Default format #}
<p>Generated: {{ now() }}</p>
{# Custom format #}
<p>Year: {{ now(format="%Y") }}</p>
<p>Date: {{ now(format="%B %d, %Y") }}</p>
Parameters:
| Name | Type | Description |
|---|---|---|
| format | String? | Date format string (optional) |
Returns: String
Format Codes:
| Code | Description | Example |
|---|---|---|
| %Y | Year | 2025 |
| %m | Month (01-12) | 01 |
| %d | Day (01-31) | 15 |
| %B | Month name | January |
| %b | Month abbr | Jan |
| %H | Hour (00-23) | 14 |
| %M | Minute | 30 |
| %S | Second | 45 |
Media Functions
resize_image()
Returns a resized image variant. When image processing is enabled, this returns the URL to an automatically generated resized image. Otherwise, it returns the original URL.
{% set img = resize_image(path="/images/hero.jpg", width=640) %}
<img src="{{ img.url }}" width="{{ img.width }}">
Parameters:
| Name | Type | Description |
|---|---|---|
| path | String | Image path (e.g., /images/photo.jpg) |
| width | Int | Requested width in pixels (0 = original) |
| height | Int | Requested height in pixels (0 = original) |
Returns: Object with properties:
| Property | Type | Description |
|---|---|---|
| url | String | URL to the resized variant (or original if unavailable) |
| width | Int | Requested width |
| height | Int | Requested height |
| lqip | String | Base64 data URI of a tiny JPEG placeholder (empty if LQIP disabled) |
| dominant_color | String | Hex color string of the image's dominant color, e.g. #a3b2c1 (empty if LQIP disabled) |
The function selects the closest available width from the configured widths. If you request width=500 and the configured widths are [320, 640, 1024], it returns the 640px variant (smallest width >= requested). If nothing is large enough, it falls back to the largest available.
The lqip and dominant_color properties require [image_processing.lqip] to be enabled. When disabled, they return empty strings.
Examples:
{# Single resized image #}
{% set img = resize_image(path="/images/hero.jpg", width=800) %}
<img src="{{ img.url }}" alt="Hero">
{# Responsive srcset #}
{% set sm = resize_image(path="/images/hero.jpg", width=320) %}
{% set md = resize_image(path="/images/hero.jpg", width=640) %}
{% set lg = resize_image(path="/images/hero.jpg", width=1024) %}
<img
src="{{ md.url }}"
srcset="{{ sm.url }} 320w, {{ md.url }} 640w, {{ lg.url }} 1024w"
sizes="(max-width: 640px) 320px, (max-width: 1024px) 640px, 1024px"
>
{# With page image from front matter #}
{% if page.image %}
{% set thumb = resize_image(path=page.image, width=320) %}
<img src="{{ thumb.url }}" alt="{{ page_title }}">
{% endif %}
{# LQIP blur-up placeholder #}
{% set img = resize_image(path="/images/hero.jpg", width=1024) %}
<img
src="{{ img.url }}"
style="background-image: url({{ img.lqip }}); background-size: cover;"
loading="lazy"
alt="Hero"
>
{# Dominant color placeholder #}
{% set img = resize_image(path="/images/photo.jpg", width=640) %}
<img
src="{{ img.url }}"
style="background-color: {{ img.dominant_color }}"
loading="lazy"
alt="Photo"
>
Requires [image_processing] to be enabled in config.toml. See Image Processing for setup details.
Best Practices
Always Check for nil
{% set page = get_page(path="featured.md") %}
{% if page %}
{{ page.title }}
{% else %}
<p>Coming soon</p>
{% endif %}
Cache Function Results
{# Good: Single lookup #}
{% set blog = get_section(path="blog") %}
<h2>{{ blog.title }}</h2>
<p>{{ blog.pages_count }} posts</p>
{# Avoid: Multiple lookups #}
<h2>{{ get_section(path="blog").title }}</h2>
<p>{{ get_section(path="blog").pages_count }} posts</p>
Organize Data Files
data/
├── navigation/
│ ├── main.json
│ └── footer.json
├── team.yaml
└── products.toml
See Also
- Data Model — Site, Section, Page types
- Filters — Value transformation