Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Template Syntax Reference

All mdt tags are HTML comments. They are invisible when markdown is rendered.

Tag types

Source tag

Defines a named block of content in a template file (*.t.md).

<!-- {@blockName} -->
  • Sigil: @
  • Only recognized in *.t.md files.
  • The content between the opening and closing tags becomes the source’s content.

Target tag

Marks where source content should be injected.

<!-- {=blockName} -->
<!-- {=blockName|transformer1|transformer2:"arg"} -->
  • Sigil: =
  • Recognized in any scanned file (markdown or source code).
  • Optionally includes transformers after the block name.

Inline tag

Inline blocks are useful when you need dynamic content in-place without creating a separate source. Typical examples include versions, toolchain values, environment metadata, and short computed strings.

Inline blocks render minijinja template content from the block’s first argument:

<!-- {~version:"{{ pkg.version }}"} -->0.0.0<!-- {/version} -->

During mdt update, mdt evaluates the template argument with your configured [data] context, then replaces the content between the opening and closing tags.

Because inline blocks are source-free, they are ideal for one-off values that still need to stay synchronized.

Current limits

  • Inline blocks must include a first argument that is the template string to render.
  • Inline blocks do not resolve source content; everything comes from the inline template argument and current data context.
  • Inline rendering still supports transformers (|trim, |code, etc.) after template evaluation.
  • In markdown, inline blocks work in normal content (paragraphs, lists, headings, tables) where HTML comments are parsed.
  • Tags shown inside fenced markdown code blocks are treated as examples and are not interpreted as live blocks.
  • In source files, inline tags follow source scanning rules and respect [exclude] markdown_codeblocks filtering.

Practical examples

Inline value in prose

Install version <!-- {~releaseVersion:"{{ pkg.version }}"} -->0.0.0<!-- {/releaseVersion} --> today.

Inline value in a table cell

| Package | Version                                                               |
| ------- | --------------------------------------------------------------------- |
| mdt     | <!-- {~mdtVersion:"{{ pkg.version }}"} -->0.0.0<!-- {/mdtVersion} --> |

Inline value with a transformer

CLI version: <!-- {~cliVersionCode:"{{ pkg.version }}"|code} -->`0.0.0`<!-- {/cliVersionCode} -->

Inline value from a script-backed data source

[data]
release = { command = "cat VERSION", format = "text", watch = ["VERSION"] }
Release: <!-- {~releaseValue:"{{ release }}"} -->0.0.0<!-- {/releaseValue} -->

When VERSION is unchanged, mdt reuses cached script output from .mdt/cache/data-v1.json.

Close tag

Closes source, target, and inline blocks.

<!-- {/blockName} -->
  • Sigil: /
  • The name must match the opening tag.

Block names

Block names follow identifier rules:

  • Start with a letter or underscore
  • Followed by letters, digits, or underscores
  • Case-sensitive

Valid names: install, apiDocs, my_block, block123, _private

Transformer syntax

Transformers are pipe-delimited and follow the block name:

{=name|transformer1|transformer2:"arg1":"arg2"}
{~name:"{{ value }}"|transformer1|transformer2:"arg1":"arg2"}

Structure

|transformerName           — no arguments
|transformerName:"arg"     — one string argument
|transformerName:4         — one numeric argument
|transformerName:"a":"b"   — two arguments

Argument types

TypeSyntaxExample
StringDouble-quoted"hello", "/// ", "\n"
NumberUnquoted integer or float4, 2.5
Booleantrue or falsetrue

String arguments support escape sequences: \", \\, \n, \t.

Whitespace handling

Whitespace between the comment delimiters and the tag braces is allowed:

<!--  { @blockName }  -->

Newlines within the comment are also allowed:

<!--
{/blockName}
-->

Content boundaries

The content of a block is everything between the end of the opening tag and the start of the closing tag. This includes surrounding whitespace and newlines:

<!-- {@block} -->

This content includes the newlines above and below.

<!-- {/block} -->

The source content here is \nThis content includes the newlines above and below.\n\n — note the leading newline after the opening tag and the trailing newline before the closing tag. Use the trim transformer on consumers if you want to strip this whitespace.

Template variables

Inside source blocks, minijinja template syntax is available when data files are configured:

Variable output

{{ namespace.key }}
{{ namespace.nested.value }}

Control flow

{% if condition %}...{% endif %}
{% if condition %}...{% else %}...{% endif %}
{% for item in list %}...{% endfor %}

Comments

{# This is a template comment and won't appear in output #}

Template variables are rendered before transformers are applied.

Examples

Minimal

<!-- {@greeting} -->

Hello!

<!-- {/greeting} -->

With transformers

<!-- {=docs|trim|linePrefix:"/// "} -->

Old content.

<!-- {/docs} -->

With template variables

<!-- {@version} -->

Current version: {{ package.version }}

<!-- {/version} -->

Complex chain

<!-- {=apiDocs|trim|replace:"Example":"Usage"|codeBlock:"typescript"} -->
<!-- {/apiDocs} -->