Variables#
Document variables let you define values once and reuse them — as text interpolated into your content, or as data passed into blocks.
Defining variables — _vars#
Add a _vars mapping to the root of your report. Values can be any native YAML type:
string, integer, float, null, boolean, list, or mapping.
_vars:
a: "hello"
b: true
c: 23
d: -0.013
e: {'key': 'value', 'key2': 'val2'}
f: ['val1', 'val2']
There are two distinct ways to use a variable: Jinja interpolation for display text,
and the $var syntax for passing objects into blocks.
Interpolating into text with Jinja#
Inside any displayed string, reference a variable with double braces. Values are rendered
with Jinja and stringified — you see str(value).
Document Variables:
- >
This document defines a, b, c, d, e, and f.
- - a = {{a}}
- b = {{b}}
- c = {{c}}
- d = {{d}}
- e = {{e.key2}} # index into a mapping
- f = {{f}}
Use dotted access ({{e.key2}}) to reach into nested mappings.
Tip
A paragraph immediately followed by a list can sometimes be misread as a bullet. A common fix is a zero-height spacer between them:
- _spacer: 0 # prevents the paragraph above being read as a bullet
Passing Python objects into blocks — $var#
Some blocks need real objects, not stringified text — for example a matplotlib figure.
For those, reference a variable with the bash-style $name syntax. This passes the actual
Python object through to the block’s parameter.
_vars:
small_space: 5
Report:
- Some text.
- _spacer: $small_space # reuse a consistent spacer everywhere
- More text.
Important
$var is for block parameters and for tables. As content on its own, $name must
hold tabular data (a list of mappings), which renders as a table; see
Tables from data. Any other value raises an error. For display text, use
Jinja ({{name}}) instead.
Computing variables in Python — _py#
The _py block executes Python with the
_vars dictionary as its scope. Variables you create in Python become available to the
rest of the document, and vice versa.
Report:
- _py:
namespace: py1
source: |
import math
a = 3
b = 4
c = math.sin(a / b)
- - a = {{py1.a}}
- b = {{py1.b}}
- c = {{py1.c}}
This is how you construct objects that don’t exist in YAML — such as a matplotlib figure —
and hand them to a block via $var:
Report:
- _py:
echo: false
source: |
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.plot([0, 1, 2], [0, 1, 4])
- _matplotfig:
fig: $fig
caption: "Figure 1: A computed plot"
See Namespaces for what namespace: py1 does.
Tip
Data that several documents share (a design schedule, section tables, analysis results)
belongs in the project config’s _data, where it is named once and
used by name in every document.
Loading variables from JSON — _loadjson#
The _loadjson block reads a JSON
file into your variables at render time, optionally under a namespace.
Report:
- _loadjson:
path: extra_vars.json
namespace: extra_vars
- - bn = {{extra_vars.bn}}
- dx = {{extra_vars.dx}}
Writing variables to JSON — _dumpjson#
The _dumpjson block writes variables defined so far in the document
to a JSON file. A dotted name writes a nested value:
Report:
- _dumpjson:
path: out/values.json
vars: [beam.span, phi] # {"beam": {"span": 6.0}, "phi": 0.9}
Namespaces#
_py and _loadjson accept an optional namespace. When you provide one, the
variables they create are nested under that name in the variable dictionary, so you access
them as {{namespace.variable}}. Without a namespace, the variables land at the top level
and are accessed directly as {{variable}}.
This keeps computed or loaded values from colliding with the variables you defined in
_vars.
_dumpjson accepts a namespace too, the other way round: it writes the names inside
that mapping at the top level of the file, so _loadjson with the same namespace puts
them back where they were.
Auto-filling PDF form fields#
When you overlay your document onto a PDF background, any variable whose name exactly matches a form-field name in the background PDF automatically fills that field. See PDF backgrounds for details and how to avoid accidental clashes.