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 and the [diagram] shortcode handle the in-content cases; this function fills the gap for theme authors.

All three 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
ArgKindDescription
typepositionalRenderer language: mermaid, svgbob, bob, or a plugin-registered language
sourcepositionalRaw diagram source text (a string, not a path)
width / heightkeywordSVG dimensions in pixels
themekeywordRenderer theme name (defaults to config.diagrams.renderers.<type>.theme)
captionkeywordRendered as <figcaption> inside a wrapping <figure>
altkeywordForwarded as the SVG’s <title> for screen readers
classkeywordExtra CSS class appended to the wrapper
renderkeywordPer-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 so it survives pulldown-cmark in the shortcode path (this matches the [diagram] shortcode wrapping verbatim).

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:

ModeBehaviour
warn (default)Renders an inline warning-box SVG and keeps the page rendering
failRaises a MiniJinja error so accent build exits non-zero
silentEmits 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 and [diagram] shortcodes 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).
  • The [diagram] shortcode is the in-content equivalent for prose pages.
  • templates/partials/diagram-fn-example.html.jinja in the default theme is a working demonstration of both hardcoded-source and frontmatter-driven calls.