Skip to main content
A Reporter template is a plain-text .tpl file. Reporter renders it with a Pongo2 engine, which reads Django-style tags and pipe filters. Template reference lists every tag and filter. Template formats shows a worked file per output format. This page covers what the engine does around that syntax: what it reads out of your file, what data it puts in front of it, and which limits it applies.

The field map


When you upload a template, Reporter analyses the text and derives a field map: every data source, every table, and every field the template names.
The map is stored with the template metadata and travels with each report request. Extraction reads only what the map lists. A field your template never names is never queried, so a template stays cheap as the underlying tables grow. Two consequences follow. First, Reporter derives the map when you upload or replace the file, never at render time. A new field reference reaches a report only after you upload the changed template. Second, Reporter checks the map against the live schema of each data source at upload time. A wrong table name or a wrong field name surfaces there, before any report runs. When a data source cannot answer, Reporter returns warnings and still accepts the template. One unreachable database does not block your work.

The data context


Extraction builds one context for the render. The first level is the data source config name. The second level is the table. Each value is a list of rows.
Your template addresses that context by the same names it used to declare them:
Rows come back under the key your template wrote. A bare table name stays bare. A schema-qualified reference becomes schema__table, with a double underscore, in both the field map and the render context. Row filters are looser and accept either schema.table or schema__table.

Variables

A template reads the context through variables. A loop alias binds one row at a time, and {% with %} names part of the context for the block below it. Both aliases are local to the block that declares them. The analyser follows an alias back to the table behind it. A field you read as order.total inside a loop over external_db.orders lands in the field map as total under that table, so extraction returns it.

Multi-schema data sources


An operator declares each data source through environment variables. CONFIG_NAME sets the name your templates use, and SCHEMAS lists the schemas Reporter discovers on it. Keep the environment-name segment and the CONFIG_NAME value identical, as in the block below:
Without SCHEMAS, Reporter discovers the public schema alone. See Environment variables for the full block. The engine resolves a bare table name against every discovered schema: Qualify the reference to remove the ambiguity. The qualified form names the source, the schema, and the table:
A qualified reference must match the discovered schema exactly. The engine does not search other schemas for it.

Blocks


A block is the unit the visual template builder works in. Thirteen types exist, in six categories: The value in brackets is the category string the block catalogue returns, so a client matching on the API response keys on it rather than on the label. Four of them hold children: loop, conditional, section, and with. A conditional also carries alternative branches. Blocks nest up to fifty levels deep. Blocks are never stored. The builder sends them to Reporter, and Reporter returns Pongo2 source plus the field map that source implies. The template you upload is always the text. Three operations support that flow:

Two kinds of filter


Reporter uses the word filter for two different things, and they run at different times. Row filters run during extraction. They live in the report request, not in the template, and they narrow the rows the database returns. The payload nests them three levels deep: data source, then table, then field.
Eight operators exist: Every operator takes an array. Several operators on one field combine, as the date range above shows. Template filters run during the render, after the rows arrive. They shape a value inside the document, and they use pipe syntax: {{ value|percent_of:total }}. List filter definitions returns the catalogue with an example per filter.

The render step


The engine parses the prepared template once per report and executes it against the context. Two behaviours of that step change how you design a document. Numeric output loses its trailing zeros, so 1200.00 renders as 1200. Use floatformat when a column needs fixed decimals. Values that carry several dots stay intact, which keeps an accounting code such as 1.1.2.00.000 unchanged. An XML template can declare the encoding of the stored file. Put the marker on the same line as the XML declaration:
Reporter then writes the file in UTF-16BE with no byte order mark. PDF output ignores the marker.

Limits the engine applies


Reporter blocks the Pongo2 tags that load or extend another file: include, extends, import, block, and ssi. A template is a self-contained document.
Block nesting stops at fifty levels, on validation and on code generation alike. Free-form block fields reject template delimiters, so builder input cannot inject a tag. Uploaded templates reject script tags.

Next steps


How report generation works

The path from a report request to a file you can download.

Template reference

Every tag, filter, and operator the syntax accepts.

Template formats

A worked template per output format.

Reporter core concepts

Templates, data sources, reports, and deadlines in one place.