Template Functions
Veta registers template functions for Pongo templates and components.
Built-in functions are always available:
urlregex_replaceload_data
Custom functions live in functions/*.js and use the file stem as the template function name.
url
url returns a portable URL for an internal root-relative path from the current page.
<link rel="stylesheet" href="{{ url("/styles.css") }}">
<img src="{{ url("/images/logo.svg") }}" alt="Logo">
<a href="{{ url(page.permalink) }}">Current page</a>
From /docs/intro/, url("/styles.css") returns ../../styles.css. From /, it returns styles.css.
External URLs, fragment-only URLs, and already-relative URLs are returned unchanged.
regex_replace
regex_replace replaces text with a Go regular expression:
{{ regex_replace("World Hello", "(\\w+) (\\w+)", "$2 $1") }}
The result can be rendered directly or assigned with set:
{% set slug = regex_replace(page.title, "[^a-zA-Z0-9]+", "-") %}
<h1 id="{{ slug }}">{{ page.title }}</h1>
Invalid regular expressions fail the build.
load_data
load_data reads a local project file or a remote URL as text from a template, include, or component.
Use load_data inside native Pongo expressions. Assign values with Pongo's built-in set tag:
{% set navigation = load_data("data/navigation.yaml")|parse_yaml %}
{% for item in navigation.items %}
<a href="{{ item.href }}">{{ item.label }}</a>
{% endfor %}
Without a parse filter, load_data returns a string:
{% set readme = load_data("content/readme.md") %}
{{ readme|markdown }}
Local Files
Local paths are project-relative and can read files from the composed project and theme filesystem:
{% set badge = load_data("data/badge.toml")|parse_toml %}
{{ badge.label }}
Local paths must be relative. Absolute paths, Windows drive paths, empty paths, and paths containing .. are rejected.
Remote URLs
Remote URLs use HTTP GET:
{% set repo = load_data("https://api.github.com/repos/varavelio/veta")|parse_json %}
{{ repo.stargazers_count }}
Only http and https URLs are allowed. Non-2xx responses fail the build.
Parse Filters
Use parse filters to convert loaded text into structured values:
parse_jsonparse_yamlparse_tomlparse_markdown
{% set message = load_data("content/message.txt") %}
{% set site = load_data("data/site.json")|parse_json %}
{% set navigation = load_data("data/navigation.yaml")|parse_yaml %}
{% set theme = load_data("data/theme.toml")|parse_toml %}
Parsed values return normal template values:
{{ site.title }} {{ navigation.items.0.label }} {{ theme.colors.primary }}
Custom Functions
Custom functions are synchronous JavaScript files in functions/. Each file must export one default function:
// functions/excerpt.js
export default function({ page }, value, length) {
console.log("excerpt", page.permalink);
return String(value).slice(0, Number(length));
}
Use the file stem as the function name:
{{ excerpt(page.content, 120) }}
The first argument is the JavaScript runtime context. Template functions receive data, pages, page, props, files, httpClient, parse, and env. console is available as a JavaScript global, not as context.console.
If a template function calls parse.renderComponents(text), its context-bound data, page, and pages values can flow into component templates. Each component tag still supplies its own attributes and slot content through props. This differs from page-generator calls, where page and pages are not available because the generator is still creating the page list.
Function files are flat. Nested directories under functions/ are not supported. A custom function can override a built-in function by using the same file stem.