# Template Authoring Notes Templates are directory-based. Each template directory contains `template.json` plus a required `files/` directory with renderable content. ## Template loading and rendering flow 1. `LibraryManager` finds template directories containing `template.json`. 2. `Template` loads and validates manifest metadata. 3. Manifest variables are normalized into the runtime variable collection shape. 4. Defaults are merged from template, user config, var-files, and CLI overrides. 5. Sections are sorted and dependency constraints are validated. 6. Variables are resolved dynamically according to `needs` constraints. 7. Files under `files/` render through the custom-delimiter Jinja environment. 8. Rendered output is sanitized. 9. Optional semantic or kind-specific validation runs. ## Template structure Minimal `template.json` shape: ```json { "slug": "my-template", "kind": "compose", "metadata": { "name": "My Template", "description": "A template description.", "version": { "name": "v1.0.0" } }, "variables": [ { "name": "general", "title": "General", "items": [ { "name": "service_name", "type": "str", "title": "Service name", "default": "demo" } ] } ] } ``` ## Template delimiters For `0.2.0+`, templates use custom Jinja-like delimiters: - Variables: `<< variable_name >>` - Blocks: `<% if condition %> ... <% endif %>` - Comments: `<# comment #>` Default Jinja delimiters such as `{{ variable }}` are intentionally left untouched so downstream tools like Ansible can use them literally. Legacy `.j2` behavior is no longer supported for new `template.json` templates. Renderable content lives under `files/`, and output paths match the relative paths under `files/`. ## Metadata versioning `metadata.version` is a structured object and may be partial. Supported fields include: - `name` - `source_dep_name` - `source_dep_version` - `source_dep_digest` - `upstream_ref` - `notes` This separates the user-facing template version label from tracked upstream dependency metadata. ## Application versions Application/image versions should generally be hardcoded in template files, for example: ```yaml image: nginx:1.25.3 ``` Do not create variables such as `nginx_version` unless there is a strong technical reason, such as multi-component version pinning. Hardcoding tested versions avoids mismatches between variables and validated template output. ## Variables Variable precedence, lowest to highest: 1. Template defaults from `template.json` 2. User config defaults 3. Var-file values 4. CLI `--var` overrides Variable types: - `str` - `int` - `float` - `bool` - `email` - `url` - `hostname` - `enum` - `secret` Common variable properties: - `default` - default value - `title` - prompt/display title - `description` - description/help text - `required` - require non-empty value - `needs` - conditional visibility constraint - `config.options` - enum options - `config.placeholder` - input placeholder - `config.autogenerated` - secret autogeneration settings ## Sections and dependencies Variable groups become sections. Sections can define: - `toggle` - auto-created boolean variable that enables/disables the section - `needs` - section dependency by section key Variable-level `needs` constraints use this format: - `var_name=value` - `var_name!=value` - `var1=value1;var2=value2` - `network_mode=bridge,macvlan` where comma means OR Dependency validation detects missing dependencies, circular dependencies, and self-dependencies. ## Validation Template validation includes: - manifest shape validation - custom-delimiter Jinja syntax validation - undeclared variable detection - rendering validation Generic semantic validation is provided by `cli/core/validators.py`, including YAML and Docker Compose-oriented checks where applicable. Kind-specific validation lives under `cli/core/validation/` and can be enabled with module validation options such as `--kind` or matrix validation where supported. ## Docker Compose notes When using Traefik with Docker Compose and multiple networks, include the Traefik network label so Traefik routes through the intended network: ```yaml traefik.docker.network: << traefik_network >> ``` For Swarm/Compose-specific label placement, follow existing template patterns before introducing new ones. ## Shortcodes Template descriptions may use emoji-style shortcodes such as `:warning:`, `:info:`, or `:docker:`. Display code maps these to Nerd Font icons. Add new shortcodes in the display/icon layer, not directly in template rendering code.