Skip to content

Template syntax

The dialect is Jinja2's, plus a scope prefix that says which part of the document a control tag applies to.

Values

{{ expression }} is replaced in place, inside the run that contains it, so it keeps the formatting you gave the tag in Word.

Values are XML-escaped by default. A value containing & or < is safe.

Scope prefixes

A control tag placed in a paragraph would, without help, emit its literal text into that paragraph. The prefix re-anchors it onto the element it names — and, the part worth remembering:

A prefixed tag removes the element it names

{%p if … %} takes its whole paragraph with it, {%tr for … %} its whole row, {%r … %} its whole run. Anything else in that element goes too.

So the tag goes in an element of its own: loop tags in rows above and below the rows that repeat, not in the repeating row. This is docxtpl's rule, reproduced exactly, and it is what makes the loop repeat markup rather than emitting its own text.

Tag Applies to Use for
{% … %} the text in place inline expressions
{%r … %} the containing run repeating or omitting formatted text
{%p … %} the containing paragraph repeating or omitting a paragraph
{%tr … %} the containing table row repeating or omitting a row
{%tc … %} the containing table cell repeating or omitting a cell

Comments take the same prefixes: {#p … #}, {#tr … #}.

To write a literal delimiter, escape it: {_{, }_}, {_%, %_}.

Table directives

Resolved against the finished table, after the loops have run:

Directive Effect
{% colspan n %} the containing cell spans n grid columns
{% hm %} merge horizontally with the cell to the left
{% vm %} merge vertically with the cell above
{% cellbg rrggbb %} shade the containing cell
{% colwidth w %} set the width of the column the cell starts in

Values that are not strings

Tag Value Page
{{r note }} a Text — formatted runs Rich text
{{p findings }} a Fragment — whole paragraphs and tables Fragments
{{ logo }} an Image Images
{{ excerpt }} a Preformatted Preformatted text

The first two carry a prefix because they replace an element: a Text produces runs, which cannot live inside a w:t, and a Fragment produces paragraphs, which cannot live inside a w:p. The other two need none — they are placed where you typed them.

Control characters

In a rendered value, \n becomes a line break, \t a tab, \f a page break and \a a new paragraph. The new paragraph inherits the properties of the one it was split from, so a value carrying \a in a styled paragraph produces more of the same style.

For multi-line text whose indentation matters as well, use Preformatted.

Where tags are looked for

Everywhere text can be authored: the body, every header and footer, the footnotes, the endnotes, the comments and the document properties. Hyperlink addresses too, which are not in the document at all.

A key whose name is a method's

{{ order.reference }} reads the key reference — unless the object has an attribute by that name, because Jinja2 tries the attribute first. For a plain dict that means these names do not do what you expect:

pop, items, keys, values, get, update, copy, clear, setdefault

{{ census.pop }} renders dict.pop — the method — rather than the population. Its repr contains a <, so with escaping off the document then fails to parse, and the failure looks nothing like its cause.

Write the subscript, which tries the key first:

{{ census['pop'] }}

The error message says so when this happens, and names the key.