Themes

A theme is a directory containing HTML templates and optional static files. Point aphid.toml at it with theme_dir:

theme_dir = "mytheme"

All paths are relative to the working directory where aphid is invoked. If theme_dir is omitted, the embedded default theme is used.

Directory layout

mytheme/
  theme.toml          ← required metadata
  templates/          ← required; all .html templates go here
    base.html
    home.html
    blog_post.html
    blog_index.html
    wiki_page.html
    wiki_index.html
    page.html
    tag.html
    tags_index.html
    404.html
  static/             ← optional; copied to output static/
    css/
    js/

theme.toml

name = "mytheme"
version = "0.1.0"
description = "Optional description."

name and version are required; description is optional.

Templates

Templates use Tera syntax — a Jinja2-style engine. The typical pattern is a base.html layout that other templates extend:

{# base.html #}
<!DOCTYPE html>
<html>
<head><title>{% block page_title %}{{ site_title }}{% endblock %}</title></head>
<body>
  {% block content %}{% endblock %}
</body>
</html>
{# blog_post.html #}
{% extends "base.html" %}
{% block content %}
  <h1>{{ title }}</h1>
  {{ content | safe }}
{% endblock %}

The content variable holds rendered HTML — always use the | safe filter to prevent double-escaping.

Variables available in every template

These come from base.html and are available in all templates via inheritance:

VariableTypeDescription
site_titlestringFrom title in aphid.toml
base_urlstringFrom base_url in aphid.toml
versionstringThe aphid binary version
nav_pageslistStandalone pages sorted by order; each has title and url
socialslistSocial links from aphid.toml; each has platform and url

blog_post.html

VariableTypeDescription
titlestringPost title from frontmatter
urlstringClean URL, e.g. /blog/my-post/
contentstringRendered HTML body
toclistHeading entries; each has level, text, and id
backlinkslistPages that link here; each has title and url
authorstring?From frontmatter
imagestring?Hero/headline image path or URL, from frontmatter
createdstring?Publication date, formatted YYYY-MM-DD
updatedstring?Last-edited date
tagslistEach tag has name and slug

wiki_page.html

Same variables as blog_post.html. author and image are always absent; created, updated, and tags are present only if set in frontmatter. In addition:

VariableTypeDescription
categorystring?Category for this page, from frontmatter
wiki_categorieslistAll wiki pages grouped by category — for rendering a sidebar with the current page highlighted (compare page.url == url). Each entry has name (string?) and pages (list of {title, url}). Named categories come first alphabetically; uncategorised pages are grouped under name = null at the end.

page.html

Same variables as blog_post.html. author, image, created, updated, and tags are always absent.

home.html

Renders the site root (/index.html). Receives the post list plus an optional rendered home block from content/home.md (see Configuration).

VariableTypeDescription
postslistAll blog posts — see the post entry shape below
homeobject?Present when content/home.md exists. Has content (string, the rendered HTML — pass through | safe).

blog_index.html

Renders the blog listing at /blog/.

VariableTypeDescription
postslistAll blog posts — see the post entry shape below

Post entry shape

Each entry in posts (and on tag.html) has:

FieldTypeDescription
titlestringPost title
urlstringClean URL, e.g. /blog/my-post/
createdstring?Publication date, formatted YYYY-MM-DD
imagestring?Path or URL of the hero image, from frontmatter
descriptionstring?Short summary, from frontmatter
tagslistEach tag has name and slug

wiki_index.html

VariableTypeDescription
categorieslistAll wiki pages grouped by category. Each entry has name (string?) and pages (list of {title, url}). Named categories come first alphabetically; uncategorised pages are grouped under name = null at the end.

tag.html

VariableTypeDescription
tagstringTag display name
tag_slugstringURL-safe slug
postslistTagged posts; each has title, url, and created?

tags_index.html

VariableTypeDescription
tagslistAll tags; each has name, slug, and count

404.html

No additional variables beyond the site-level ones.

Static files

Files under mytheme/static/ are copied to the output's static/ directory before any user static files. If a file exists in both the theme and the user's static_dir, the user's file wins.

Reference theme assets with an absolute path in templates:

<link rel="stylesheet" href="/static/css/theme.css">

Syntax highlighting

Code blocks are highlighted with CSS classes prefixed hl- (e.g. hl-keyword, hl-string, hl-comment). Your theme stylesheet must provide rules for these classes — otherwise code blocks will render in a single color. The default theme ships with Catppuccin Mocha colors as a reference.