Diagrams in Templates
The diagram() template function renders a diagram inline from a
Jinja expression. Use it when the diagram source comes from
frontmatter, a layout context, or a shared template file
rather than the page body. Fenced code blocks handle the in-content
case; this function fills the gap for theme authors, and it is where
caption, alt text, and the other options live.
Both author paths route through the same renderer and cache, so the rendered SVG is byte-identical for the same source.
Quick reference
diagram(type, source, *, width=None, height=None, theme=None,
caption=None, alt=None, class=None, render=None) -> safe html
| Arg | Kind | Description |
|---|---|---|
type | positional | Renderer language: mermaid, svgbob, bob, or a plugin-registered language |
source | positional | Raw diagram source text (a string, not a path) |
width / height | keyword | SVG dimensions in pixels |
theme | keyword | Renderer theme name (defaults to config.diagrams.renderers.<type>.theme) |
caption | keyword | Rendered as <figcaption> inside a wrapping <figure> |
alt | keyword | Written as the wrapping <figure>’s aria-label for screen readers, in every render mode; empty alt text counts as none |
class | keyword | Extra CSS class appended to the wrapper |
render | keyword | Per-block render-mode override: server, client, or hybrid |
Setting any of caption, alt, or class flips the wrapper from a
bare <div class="diagram-wrapper"> to <figure>; otherwise the SVG
is wrapped in a div. A fenced block’s SVG is not wrapped, except in
development, where it sits in a div with the same classes for the dev
overlay.
Frontmatter-driven diagrams
The most common use: a page declares its diagram in frontmatter, the template renders it. This keeps the diagram source close to the page data without polluting the rendered markdown.
--- title: Architecture Overview architecture_diagram: | flowchart LR Browser --> Accent Accent --> Markdown architecture_alt: A request flow from browser through Accent to markdown ---
{% if page.custom.architecture_diagram %}
{{ diagram("mermaid", page.custom.architecture_diagram,
caption="Architecture",
alt=page.custom.architecture_alt) }}
{% endif %}
Note the use of page.custom.<field> (Accent’s frontmatter passthrough
namespace) rather than page.meta.<field>.
Hardcoded diagrams in templates
Sometimes a layout template wants its own diagram (e.g., a “how the build pipeline works” overview rendered on every docs index page). A literal string works fine:
{{ diagram("mermaid",
"flowchart LR\n Author --> Template\n Template --> SVG",
caption="Author path: template function") }}
\n in a double-quoted Jinja string is a real newline at runtime, so
the example above produces a three-line Mermaid program.
Error handling
diagram() honours diagrams.on_error from config.yaml:
| Mode | Behaviour |
|---|---|
warn (default) | Renders an inline warning-box SVG and keeps the page rendering |
fail | Raises a MiniJinja error so accent build exits non-zero |
silent | Emits an empty string |
Unknown renderer types (e.g., diagram("unknown-lang", "..."))
follow the same matrix.
Dev-overlay click-to-editor
The dev-mode source-provenance overlay routes clicks on diagrams
back to their source file. Fenced blocks get this treatment because
the renderer knows which markdown file they came from. The
diagram() template function receives a bare
source string – it could have come from frontmatter,
a literal, or a layout context – so there is no single source path
to attribute, and template-function diagrams are intentionally
skipped by the overlay. Cache correctness is unaffected because
cache keys hash the source content directly.
See also
- The Diagrams page in the Markdown Guide documents the full renderer surface (Mermaid dialects, Svgbob, plugin languages, configuration, render modes).
- A fenced
```mermaidblock is the in-content equivalent for prose pages; it takes no options beyondrender. templates/partials/diagram-fn-example.html.jinjain the default theme is a working demonstration of both hardcoded-source and frontmatter-driven calls.