Examples

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