<a id="template-settings"></a>
<a id="id1"></a>
# Template Settings

Settings let the user generating a document change what it contains without editing the Template. A Draft summary might offer a "Include Forms?" tick box, or a choice of the order to list Forms in.

Settings are defined on the *Settings* tab of the Document Template editor. Each one becomes a control in the generation dialog, and its value arrives in the Template through the `settings` dictionary.

<a id="defining-a-setting"></a>
## Defining a Setting

Each row on the Settings tab describes one control:

| Column | Meaning |
| --- | --- |
| Name | The key used to read the value inside the Template, e.g. `settings.get("form_order")`. Required, and must be unique within the Template. Case is preserved, so a Setting named `Form_Order` must be read as `Form_Order`. |
| Display Name | The label shown next to the control in the generation dialog. Required, and must be unique within the Template. **This is not the name used in the Template** — see [Name and Display Name](#template-settings-name-vs-display-name). |
| Description | Help text shown with the control, to explain to the user what the Setting does. |
| Type | One of *Boolean*, *Text*, *Choice* or *Draft*. See [Setting Types](#setting-types) below. |
| Possible Values | For *Choice* Settings only, the comma separated list of options to offer. |
| Default | The value used when the user does not change the control. |
| Multiple | For *Draft* Settings only: *True* lets the user choose several Drafts rather than one. |
| Required | For *Text* and *Draft* Settings only: *True* means the Setting must have a value before the document can be generated. The generation dialog keeps *Generate* disabled, and names the Settings still to be filled in, until each Required Setting has one. A Text Setting holding only spaces has no value. A *Boolean* or *Choice* Setting always has a value, so it cannot be Required. |

<a id="setting-types"></a>
## Setting Types

The type decides both the control the user is offered and the Python type the Template receives.

- **Type:** Boolean

  **Control:** A tick box

  **Value in the Template:** A real Python `True` or `False`, so it can be tested directly:

  ```jinja
  {% if settings.get("do_forms") %}...{% endif %}
  ```

  The Default must be `True` or `False`.

- **Type:** Text

  **Control:** A text box

  **Value in the Template:** A string, empty rather than missing when the user clears the box:

  ```jinja
  <para>{{ settings.get("preamble") }}</para>
  ```

- **Type:** Choice

  **Control:** A drop-down of the Possible Values

  **Value in the Template:** The chosen option as a string, with surrounding spaces removed:

  ```jinja
  {% for form in draft.als_forms_set.all().order_by(settings.get("form_order")) %}
  ```

  Possible Values is required, and any Default must be one of them.

- **Type:** Draft

  **Control:** A drop-down of the Drafts in the Project the document is generated in. For a Template run from a Draft, that is the Draft's own Project. When Multiple is *True*, a list from which the user may choose several.

  **Value in the Template:** The chosen Draft, or `None` when none is chosen:

  ```jinja
  {% if settings.get("baseline") %}
  <para>Compared with {{ settings.get("baseline").DraftName }}</para>
  {% endif %}
  ```

  The Default is a Draft name. The Draft with that name is chosen when the Project has one.

  When Multiple is *True*, a list of the chosen Drafts in Draft name order, empty when none is chosen:

  ```jinja
  {% for chosen in settings.get("drafts") %}
  <heading level="2">{{ chosen.DraftName }}</heading>
  {% endfor %}
  ```

  The Default is then Draft names separated by `|`, for example `Version 1|Version 2`. Any Draft with one of those names is chosen.

<a id="reading-settings-in-a-template"></a>
## Reading Settings in a Template

`settings` is an ordinary Python dictionary keyed by the Setting's **Name**:

```jinja
Ordered by: {{ settings.get("form_order") }}
{% if settings.get("do_forms") %}
    {% for form in draft.als_forms_set.all().order_by(settings.get("form_order")) %}
    <heading level="2">{{ form.DraftFormName }}</heading>
    {% endfor %}
{% endif %}
```

**Every Setting defined on the Template is always present in the dictionary.** If the user does not change a control, its Default is used, so there is no need to supply a fallback for the ordinary case:

```jinja
{# Both work, but the Default has already been applied — the "Ordinal" here is never reached #}
{{ settings.get("form_order", "Ordinal") }}
{{ settings.get("form_order") }}
```

A second argument to `get()` is still worth having if you want a Template to survive a Setting being renamed or removed, because a name that is not defined is simply absent:

```jinja
{{ settings.get("subtitle", "") }}
```

> **Note:** Settings are shared by every scope. A *Draft Object List* Template reads its Settings exactly as a *Draft Home* Template does.

<a id="name-and-display-name"></a>
<a id="template-settings-name-vs-display-name"></a>
## Name and Display Name

The two are easy to confuse because the generation dialog only ever shows the Display Name.

- **Display Name** is what the user sees — "Order forms by".
- **Name** is what the Template reads — `form_order`.

Reading a Setting by its Display Name finds nothing. It does not fail: *get()* returns Python's `None` for a key that is not there, and the document ends up with the word "None" printed in it rather than the value or a blank:

```jinja
{{ settings.get("Order forms by") }}   {# prints "None" #}
{{ settings.get("form_order") }}       {# the value the user chose #}
```

Passing a fallback as the second argument turns that into something a reader can act on:

```jinja
{{ settings.get("Order forms by", "") }}
```

Choosing a Name that looks like a variable, and a Display Name written for a reader, keeps the two apart.

> **Note:** The same names are used when generating documents through the API, where Settings are supplied by Name. See [Generating Document Templates via the API](../../api/api_document_templates.html.md#api-document-templates).

<a id="testing-settings"></a>
## Testing Settings

The *Test* tab of the Document Template editor offers no Setting controls: it runs the Template with the saved Default of every Setting. To exercise the other branches of a Template, either save a different Default temporarily, or generate the document from the page it belongs to, where the user controls are offered.

A Required Setting is checked on the Test tab too. If its Default is empty, or names no Draft in the Project or Draft chosen to test on, the run does not start and the message names the Setting.
