Template Functions

Veta registers template functions for Pongo templates and components.

Built-in functions are always available:

  • url
  • regex_replace
  • load_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_json
  • parse_yaml
  • parse_toml
  • parse_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.