> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lerian.studio/llms.txt
> Use this file to discover all available pages before exploring further.

# Motor de templates do Reporter

> Como o Reporter avalia um template: o mapa de campos que ele deriva, o contexto de dados que ele monta, os blocos, os filtros de template, os filtros de linha e o modelo de fontes de dados com múltiplos esquemas.

Um template do Reporter é um arquivo `.tpl` de texto puro. O Reporter o renderiza com um motor Pongo2, que lê tags no estilo Django e filtros com sintaxe de pipe.

[Referência de templates](/pt/reporter/template-reference) lista cada tag e cada filtro. [Formatos de template](/pt/reporter/template-examples) mostra um arquivo trabalhado por formato de saída. Esta página cobre o que o motor faz em volta dessa sintaxe: o que ele lê do seu arquivo, quais dados ele coloca na frente dele e quais limites ele aplica.

## O mapa de campos

***

Quando você envia um template, o Reporter analisa o texto e deriva um **mapa de campos**: cada fonte de dados, cada tabela e cada campo que o template nomeia.

```json theme={null}
{
  "external_db": {
    "sales__orders": ["id", "total", "created_at"]
  }
}
```

O mapa é guardado junto com os metadados do template e viaja com cada requisição de relatório. A extração lê apenas o que o mapa lista. Um campo que o seu template nunca nomeia nunca é consultado, então um template continua barato conforme as tabelas por trás dele crescem.

Duas consequências vêm daí. Primeiro, o Reporter deriva o mapa quando você envia ou substitui o arquivo, nunca na hora do render. Uma referência a um campo novo chega a um relatório apenas depois que você envia o template alterado.

Segundo, o Reporter confere o mapa contra o esquema ao vivo de cada fonte de dados no momento do envio. Um nome de tabela errado ou um nome de campo errado aparece ali, antes de qualquer relatório rodar. Quando uma fonte de dados não consegue responder, o Reporter devolve avisos e aceita o template mesmo assim. Um banco de dados inalcançável não trava o seu trabalho.

## O contexto de dados

***

A extração monta um contexto para o render. O primeiro nível é o nome de configuração da fonte de dados. O segundo nível é a tabela. Cada valor é uma lista de linhas.

```json theme={null}
{
  "external_db": {
    "orders": [
      { "id": "018f...", "total": "1200.00", "created_at": "2026-07-01" }
    ]
  }
}
```

O seu template endereça esse contexto com os mesmos nomes com que o declarou:

```django theme={null}
{% for order in external_db.orders %}
  {{ order.id }} — {{ order.total|floatformat:2 }}
{% endfor %}
```

As linhas voltam sob a chave que o seu template escreveu. Um nome de tabela simples permanece simples. Uma referência qualificada por esquema vira `schema__table`, com underscore duplo, tanto no mapa de campos quanto no contexto de renderização. Os filtros de linha são mais flexíveis e aceitam `schema.table` ou `schema__table`.

### Variáveis

Um template lê o contexto por meio de variáveis. Um apelido de laço liga uma linha por vez, e `{% with %}` nomeia parte do contexto para o bloco abaixo dele. Os dois apelidos são locais ao bloco que os declara.

O analisador segue um apelido até a tabela por trás dele. Um campo que você lê como `order.total` dentro de um laço sobre `external_db.orders` cai no mapa de campos como `total` sob aquela tabela, então a extração o devolve.

## Fontes de dados com múltiplos esquemas

***

Um operador declara cada fonte de dados por variáveis de ambiente. `CONFIG_NAME` define o nome que os seus templates usam, e `SCHEMAS` lista os esquemas que o Reporter descobre nela. Mantenha o segmento do nome de ambiente e o valor de `CONFIG_NAME` idênticos, como no bloco abaixo:

```bash theme={null}
DATASOURCE_EXTERNAL_DB_CONFIG_NAME=external_db
DATASOURCE_EXTERNAL_DB_HOST=external-postgres
DATASOURCE_EXTERNAL_DB_PORT=5432
DATASOURCE_EXTERNAL_DB_USER=db_user
DATASOURCE_EXTERNAL_DB_DATABASE=external_database
DATASOURCE_EXTERNAL_DB_TYPE=postgresql
DATASOURCE_EXTERNAL_DB_SCHEMAS=sales,inventory,reporting
```

Sem `SCHEMAS`, o Reporter descobre apenas o esquema `public`. Veja [Variáveis de ambiente](/pt/reporter/reporter-environment-variables) para o bloco completo.

O motor resolve um nome de tabela simples contra todos os esquemas descobertos:

| Donos do nome de tabela                | Resultado                                                     |
| -------------------------------------- | ------------------------------------------------------------- |
| Exatamente um esquema                  | O motor lê aquela tabela.                                     |
| Vários esquemas, um deles `public`     | O motor lê a tabela de `public`.                              |
| Vários esquemas, nenhum deles `public` | O motor reporta a tabela como ambígua e nomeia as candidatas. |
| Nenhum esquema                         | O motor reporta a tabela como não encontrada.                 |

Qualifique a referência para remover a ambiguidade. A forma qualificada nomeia a fonte, o esquema e a tabela:

```django theme={null}
{% for order in external_db:sales.orders %}
  {{ order.id }}
{% endfor %}
```

Uma referência qualificada precisa casar exatamente com o esquema descoberto. O motor não procura essa tabela em outros esquemas.

## Blocos

***

Um bloco é a unidade com que o editor visual de templates trabalha. Existem treze tipos, em seis categorias:

| Categoria             | Tipos de bloco                                          |
| --------------------- | ------------------------------------------------------- |
| Básico (`basic`)      | `text`, `variable`, `comment`                           |
| Controle (`control`)  | `loop`, `conditional`, `with`                           |
| Dados (`data`)        | `aggregation`, `calculation`, `date_time`, `expression` |
| Layout (`layout`)     | `section`                                               |
| Numeração (`dimp`)    | `counter`                                               |
| Avançado (`advanced`) | `custom_tag`                                            |

O valor entre parênteses é a string de categoria que o catálogo de blocos devolve, então um cliente que compara contra a resposta da API usa essa string, e não o rótulo.

Quatro deles contêm filhos: `loop`, `conditional`, `section` e `with`. Um condicional carrega ainda ramos alternativos. Os blocos aninham até cinquenta níveis de profundidade.

Os blocos nunca são armazenados. O editor os envia ao Reporter, e o Reporter devolve código-fonte Pongo2 mais o mapa de campos que esse código implica. O template que você envia é sempre o texto.

Três operações sustentam esse fluxo:

* [Validar blocos de template](/pt/reference/reporter/validate-template-blocks) confere a estrutura, faz o parse do código gerado e reporta cada problema contra o bloco que o causou.
* [Gerar código de template](/pt/reference/reporter/generate-template-code) devolve o código pronto para um formato de saída.
* [Listar definições de bloco](/pt/reference/reporter/list-block-definitions) devolve o catálogo, para que um cliente fique em dia com o motor.

## Duas espécies de filtro

***

O Reporter usa a palavra filtro para duas coisas diferentes, e elas rodam em momentos diferentes.

**Os filtros de linha** rodam durante a extração. Eles vivem na requisição do relatório, não no template, e restringem as linhas que o banco de dados devolve. O payload os aninha em três níveis: fonte de dados, depois tabela, depois campo.

```json theme={null}
{
  "templateId": "018f2a6c-1c2f-7a10-9f1e-2b8c4d5e6f70",
  "filters": {
    "external_db": {
      "orders": {
        "status": { "nin": ["cancelled", "draft"] },
        "created_at": { "gte": ["2026-07-01"], "lte": ["2026-07-31"] }
      }
    }
  }
}
```

Existem oito operadores:

| Operador  | Significado                      | Valores         |
| --------- | -------------------------------- | --------------- |
| `eq`      | Casa com qualquer valor listado  | Um ou mais      |
| `gt`      | Acima do valor                   | Um              |
| `gte`     | No valor ou acima                | Um              |
| `lt`      | Abaixo do valor                  | Um              |
| `lte`     | No valor ou abaixo               | Um              |
| `between` | Dentro de um intervalo inclusivo | Exatamente dois |
| `in`      | Casa com qualquer valor listado  | Um ou mais      |
| `nin`     | Exclui todos os valores listados | Um ou mais      |

Todo operador recebe um array. Vários operadores sobre um mesmo campo se combinam, como mostra o intervalo de datas acima.

**Os filtros de template** rodam durante o render, depois que as linhas chegam. Eles dão forma a um valor dentro do documento e usam sintaxe de pipe: `{{ value|percent_of:total }}`. [Listar definições de filtro](/pt/reference/reporter/list-filter-definitions) devolve o catálogo com um exemplo por filtro.

## O passo de render

***

O motor faz o parse do template preparado uma vez por relatório e o executa contra o contexto. Dois comportamentos desse passo mudam como você desenha um documento.

A saída numérica perde os zeros à direita, então `1200.00` renderiza como `1200`. Use `floatformat` quando uma coluna precisar de casas decimais fixas. Valores que carregam vários pontos ficam intactos, o que mantém um código contábil como `1.1.2.00.000` inalterado.

Um template XML pode declarar a codificação do arquivo armazenado. Coloque o marcador na mesma linha da declaração XML:

```django theme={null}
{# reporter:output-encoding=utf-16be #}<?xml version="1.0" encoding="UTF-16"?>
```

O Reporter então grava o arquivo em UTF-16BE sem marca de ordem de bytes. A saída em PDF ignora o marcador.

## Limites que o motor aplica

***

<Note>
  O Reporter bloqueia as tags do Pongo2 que carregam ou estendem outro arquivo: `include`, `extends`, `import`, `block` e `ssi`. Um template é um documento autocontido.
</Note>

O aninhamento de blocos para em cinquenta níveis, tanto na validação quanto na geração de código. Campos de bloco de formato livre recusam delimitadores de template, então a entrada do editor não consegue injetar uma tag. Templates enviados recusam tags de script.

## Próximos passos

***

<CardGroup cols={2}>
  <Card title="Como funciona a geração de relatórios" icon="diagram-project" href="/pt/reporter/how-report-generation-works">
    O caminho que vai de uma requisição de relatório a um arquivo que você baixa.
  </Card>

  <Card title="Referência de templates" icon="code" href="/pt/reporter/template-reference">
    Cada tag, filtro e operador que a sintaxe aceita.
  </Card>

  <Card title="Formatos de template" icon="file-lines" href="/pt/reporter/template-examples">
    Um template trabalhado por formato de saída.
  </Card>

  <Card title="Conceitos centrais do Reporter" icon="cubes" href="/pt/reporter/reporter-core-concepts">
    Templates, fontes de dados, relatórios e prazos em um só lugar.
  </Card>
</CardGroup>
