Skip to main content

Loops and Conditions in the Mapping File

The mapping file is rendered with Pebble before it is read, so a for loop and an if work in it. A loop writes a file or a whole folder once for each item of a list, and a condition decides whether a file is generated, and under what name. (For loops and conditions inside a template file, see Conditions and Loops.)


Repeating in a loop​

The mapping file is rendered with Pebble before it is read, so a for loop around the items of an entry creates one item per element of a list from your configuration. A list such as modules can live in the json section of codebaker.config.json5, where users can edit it in the dialog.

To keep the file valid JSON5 in your editor, put the two loop tags in their own comments and leave one real item in between:

"modules/module-template": [
// CodeBaker: {% for m in modules %}
{ target: "{{ m.key }}", data: { key: "{{ m.key }}", label: "{{ m.label }}" } },
// CodeBaker: {% endfor %}
],

With modules = alpha, beta, gamma, the whole modules/module-template folder is generated three times. The target is relative to the source's parent folder (modules/), so the clones land at modules/alpha/, modules/beta/ and modules/gamma/, and module-template itself is not generated. Each clone's files see that item's data (key, label).

Generation only ever writes: removing a module from the list later does not delete the folder that was generated earlier.



Conditions: generate or name a file depending on a variable​

Because the mapping file is rendered with Pebble first, if works in it as well as for. It gives you two things.

Conditional generation​

Decide whether a file or folder is generated at all. Use if and else around two versions of the entry, and let the else side say false:

mapping: {
// CodeBaker: {% if withApi %}
"api.php": ["api/Api.php"],
// CodeBaker: {% else %}
"api.php": false,
// CodeBaker: {% endif %}
}

With withApi on, the file is written to api/Api.php. With it off, it is not written at all.

Always add the else branch

An if without an else is not enough to leave a file out. When the condition is false the entry simply does not exist, and a file that is not listed is copied as it is, under its original name (api.php). Say false in the else side whenever the file should not be generated.

The same works for one item of a repeat list. Add a whole item only when it is needed:

"card.html": [
{ target: "cards/a.html", data: { title: "Alpha" } },
// CodeBaker: {% if extra %}
{ target: "cards/b.html", data: { title: "Beta" } },
// CodeBaker: {% endif %}
],

Conditional naming​

A target is text that is rendered too, so it can contain conditions, filters and expressions. This is where to use the full Pebble syntax for an output file name: the names of the files in the template itself only take simple placeholders. Both forms work:

// A prefix that only appears when the condition holds: SoftModel.php or Model.php
"model.php": ["{% if soft %}Soft{% endif %}Model.php"],

// Pick between two values: old/User.php or app/User.php
"model.php": ["{{ legacy ? 'old' : 'app' }}/{{ name }}.php"],

The conditions use the variables from your configuration and the dialog, the same as anywhere else. A flag such as withApi is a vars entry whose value is "true" or "false", which switches {% if %} on and off (see the Configuration Reference).



Next​