> For the complete documentation index, see [llms.txt](https://docs.apryse.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.apryse.com/core/generate-via-template/data-model.md).

# Document Generation Data Model

Learn how to use moustache templates and JSON dictionaries for dynamic document creation. Explore text, image, and structured input formats with practical examples. Contact us for custom template need

## General principles

* Each document will have one or more template `keys`, denoted by the `{{` start tag, and `}}` closing tag -- these are often referred to as "moustache templates" (turn the `{` around 90 degrees, and it looks like a moustache...).
* The API should be supplied with a json dictionary, where each template key within the document is a property within the dictionary. The value associated with each key can take a number of forms, as described below.
* There are a number of error conditions for invalid template documents and invalid JSON. These errors will cause an exception to be thrown with a descriptive message.

To see templates in practice check out [this list of examples](/core/create/generate-via-template.md#examples).

This data model will be expanded going forward in order to meet customer needs. If you require a specific feature, or don't believe that the current template framework can meet your needs, then please contact us.

## Format for content values

### Text String

Can be one of:

* Simple string: `"key":"Value Text"`
* A JSON object with the `text` property: `"key": {"text": "Value Text"}`
* A JSON object with the `text_lines` property: `"key": {"text_lines": ["Line 1", "Line 2"]}`. The inserted text strings will be separated by line breaks.

### Images

An image value is a JSON dictionary with the following required properties:

* `image_url`: \[string] On web systems this can be a URL, on server/desktop systems it is expected to be a local filesystem path (absolute, or relative to the process working directory).
* **both `width` and `height`, or `size`:** \[number or string] Physical image dimensions. If a number is used, it will be interpreted as points. If a string is used, it may be accompanied with absolute css length units, for example: `"width": "1in"`.

Take a look at the [image insertion example](/core/create/generate-via-template.md#insert-images) to see this in practical usage.

### QR code

A QR code can be generated to encode alphanumeric data using the following properties:

* `qr_code`: \[string] this is the data that will be encoded in the QR code. As an example, this is commonly a URL.
* `size`: \[number or string] Physical qr code size. If a number is used, it will be interpreted as points. If a string is used, it may be accompanied with absolute css length units, for example: `"width": "1in"`.
* **`error_correction_level`**: (optional) \[number or string] The QR code error correction level. Higher values allow data recovery with larger portions of the QR code damaged, but create more dense QR codes. Valid values are `0, 1, 2, 3` or `"L", "M", "Q", "H"`. The default if this property is not supplied is `"Q"`.

### Structured input

Structured input inserts document content that is more powerful that simple text replacement. It supports dynamic document structure, formatting, and styling. To insert structured input, use a JSON dictionary with one of the following properties:

* `html`: \[string] HTML input or
* `markdown`: \[string] Markdown input

Not all features of html and markdown are supported, for more information please see: [structured input](/core/generate-via-template/structured-input.md)

### Objects

The JSON data can also be organized into objects. The tag `{{a.b}}` will retrieve the value of property `b` in object `a`: `{"a": {"b": "value"} }`.

## Loops

Loops can be used to repeat content in a document and fill in unique data for each repetition. A Loop over the key `var` is created using the syntax `{{loop var}} ... {{endloop}}`:

![](https://3779731113-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fziw3GiL98Xfj63F3He8h%2Fuploads%2Fgit-blob-384022f9474ea4e90e9e6f50e14ed433c4dd7bb8%2F4c877f2c132b1e393c85ad2c70790f025f62c0a3-848x482.png?alt=media)

The corresponding JSON value for the loop key must be an array of objects. The loop body is duplicated for each item in the array, and the tags in the body of the loop use values that are overridden by the JSON object in each iteration of the loop. Example JSON:

{% tabs %}
{% tab title="JSON" %}
{% code lineNumbers="true" %}

```json
{
    "var": [
        {"item": "First iteration."},
        {"item": "Second iteration."}
    ]
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

Produces:

![](https://3779731113-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fziw3GiL98Xfj63F3He8h%2Fuploads%2Fgit-blob-78ada321ae4bbafd84a1038f7ee9ad2e0e58d3bb%2Fd080a7f734d9dcc1249cd41f5ae8802b171aefcb-712x408.png?alt=media)

Loops can be nested and combined with conditionals.

### List Loops

To generate a bulleted or numbered list with dynamic content, you can create a list loop as follows:

1. The `{{loop}}` tag must be within an item of the list.
2. The `{{endloop}}` tag must be within a different item of the list.

Example:

![](https://3779731113-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fziw3GiL98Xfj63F3He8h%2Fuploads%2Fgit-blob-d39a486ca69a798352e1ddadd96422d4d1f68940%2F6fa3f7b769112560ca708841f90f19bcbe86c2f9-899x350.png?alt=media)

The JSON for list loops uses the same format as normal loops. Note: If there is any extra text (including whitespace) in the `{{loop}}` or `{{endloop}}` list items, those items will not be removed. For more details, see: [content removal](/core/create/generate-via-template/advanced.md#behavior-for-empty-loops-and-false-conditionals).

### Table Row Loops

To generate a table with dynamic row content, add a table in the template document with the desired column structure, following the constraints:

1. The `{{loop}}` tag must be in the first column.
2. The `{{endloop}}` tag must be in the last column (if the table only has one column, it can't be in the same cell as the `{{loop}}` tag, otherwise it would loop within the cell, so place the `{{endloop}}` tag in the next row).

Example:

![](https://3779731113-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fziw3GiL98Xfj63F3He8h%2Fuploads%2Fgit-blob-12494152eafeee29e2e15a5909c9e72f4c3e7b8f%2F9c095a49cd5f6e88c1a7ef15c9b4c05b5baa0bec-804x286.png?alt=media)

The JSON for tables row loops uses the same format as normal loops.

## Conditionals

Conditionals can be used to conditionally include content in a document. A conditional on the key `cond` is created using the syntax `{{if cond}} ... {{endif}}`:

![](https://3779731113-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fziw3GiL98Xfj63F3He8h%2Fuploads%2Fgit-blob-f8e6f764fdf5ba782c732e3383484765a067bd9e%2Fd51521cebfd06e5425b20d7e9c73ceb5d8d6e2da-900x405.png?alt=media)

The JSON value corresponding to the condition key (`cond` here) is converted to a boolean. It is evaluated as false when either:

* The key is not present in the JSON
* The value is `false`, `""`, `0`, or `null`

If the evaluated value is false, the conditional's body is removed.

Conditionals can also have an `{{else}}` clause:

![](https://3779731113-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fziw3GiL98Xfj63F3He8h%2Fuploads%2Fgit-blob-d7518f2aedd1868901c758e8d80d95a6ae619098%2Fa3a5916b67e2c355f2a61ac99da22be81d7fc0d0-904x622.png?alt=media)

The else clause body will be removed if and only if the condition evaluates to true.

### Operators

Tag expressions can also use operators. There are currently five operators:

1. `<expr>.<key>`: evaluates expr (must evaluate to a JSON object), then returns the property given by "key". "key" is limited to alphanumeric characters.
2. `not(<expr>)`: evaluates `expr`, converts it to a boolean, and inverts the result.
3. `equal(<expr>, <expr>)`: evaluates each expression and returns true if they have the same value. Template keys can be compared to strings by using a string literal enclosed in single or double quotes. For example: `equal(country, 'United States')`.
4. `empty(<expr>)`: evaluates `expr` (must evaluate to a JSON array), and returns if the array is empty.
5. `format_date(<date>, <fmt>)`: evaluates `date` and `fmt` (both must evaluate to a string), and returns the date formatted according to the format. `date` must be in ISO 8601 format. `fmt` must follow the Microsoft Excel date formatting pattern, for example `"mmm dd"`.

These operators can also be used in combination. For example: `{{if not(equal(customer.first_name, 'Paul'))}}`.

## Further Reading

For more information, see the following resources:

[Advanced features](/core/create/generate-via-template/advanced.md) For a specification of advanced features, and greater detail on behavior

[Live Web Sample](https://sdk.apryse.com/samples/web/samples/advanced/template-fill/) To try a live sample of template filling using our WebViewer

[Structured input](/core/generate-via-template/structured-input.md) For inserting dynamic content using html or markdown


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.apryse.com/core/generate-via-template/data-model.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
