Template configuration reference
This page is the lookup specification for template config.yaml files and
renderer-facing template directory behavior. Use it when maintaining a template
directory or diagnosing a rendering failure. For a task flow, see
Template author tasks; for design rationale, see
Template rendering explanation.
File contract
A template directory must contain config.yaml. The renderer reads it
before walking files; a missing file fails before any template file is rendered.
Empty files and comment-only files are treated as an empty mapping. When no
expr_styles.default or stmt_styles.default is supplied, the renderer
creates a default DSL style.
Only these top-level keys are accepted:
Key |
Type |
Meaning |
|---|---|---|
|
mapping |
Registers expression rendering styles used by |
|
mapping |
Registers operation-statement rendering styles used by |
|
mapping |
Adds Jinja2 globals through |
|
mapping |
Adds Jinja2 filters through the same object-loading mechanism. |
|
mapping |
Adds Jinja2 tests through the same object-loading mechanism. |
|
list of strings |
GitWildMatch-style patterns for input template files that should not be rendered or copied. |
Validation failures
The renderer fails fast on invalid configuration. The message includes the configuration file path and the failing key shape where available.
Marker |
Invalid shape |
Minimal counterexample |
|---|---|---|
|
YAML syntax cannot be parsed. |
|
|
Empty or comment-only file. |
Accepted as |
|
Root value is not a mapping. |
|
|
Root has a key outside the accepted set. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
One expression style entry is not a mapping. |
|
|
One expression style lacks |
|
|
One statement style entry is not a mapping. |
|
|
One statement style lacks |
|
|
|
|
|
One ignore item is not a string. |
|
Object-loading failures happen when the selected form is incomplete or cannot be imported:
Marker |
Invalid shape |
Effect |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
Import failure from |
Expression styles
An expression style maps a template-local style name to a canonical expression
renderer. Every style entry must contain base_lang. Extra keys override or
extend node templates for that style.
expr_styles:
c_scope_expr:
base_lang: c
Name: "scope->{{ node.name | to_c_identifier }}"
Use it from templates:
{{ transition.guard | expr_render(style='c_scope_expr') }}
Canonical style names and aliases are exact:
Canonical |
Aliases |
|---|---|
|
none |
|
none |
|
|
|
|
|
none |
|
|
|
|
|
|
|
|
Statement styles
A statement style renders assignments and if blocks in operation blocks. It
has the same base_lang requirement and may also set these fields:
Field |
Meaning |
|---|---|
|
Canonical statement language to start from. |
|
Expression renderer used inside statements. |
|
Expression template overrides scoped to statement rendering. |
|
Jinja template for persistent variable writes and reads. |
|
Jinja template for block-local temporary names. |
|
Assignment statement template. |
|
Optional declaration emitted when a temporary first appears. |
|
Mapping from inferred DSL types such as |
|
Fallback type when inference cannot decide. |
|
Control-flow templates for conditional blocks and empty branches. |
The renderer provides these helper signatures:
stmt_render(node, style='default', state_vars=None, var_types=None,
visible_names=None, visible_var_types=None,
indent=' ', level=0)
stmts_render(nodes, style='default', state_vars=None, var_types=None,
visible_names=None, visible_var_types=None,
indent=' ', level=0, sep='\n')
state_vars and var_types default to renderer-injected model variables
when a full StateMachine render is active. visible_names and
visible_var_types describe temporary variables already visible to the
statement renderer. sep controls how rendered statement strings are joined:
{{ action.operations | stmts_render(style='python_runtime', sep='\n') }}
Runtime statement renderer vs DSL echo renderer
Helper |
Contract |
Do not use for |
|---|---|---|
|
Render executable target-language statements. |
Raw DSL echo snippets. |
|
Render DSL-like text from operation statements. |
Runtime source code that must execute in Python, C, or another target. |
Counterexample: a DSL effect counter = counter + 1; rendered with
operation_stmt_render remains counter = counter + 1;. A Python runtime
style may need scope['counter'] = scope['counter'] + 1; a C runtime style
may need scope->counter = scope->counter + 1;.
Object-loading forms
globals, filters, and tests all pass values through
process_item_to_object.
Form |
YAML shape |
Registered object |
|---|---|---|
|
|
Callable mapping positional args to |
|
|
Jinja template |
|
|
Imported Python object. |
|
|
Literal value. |
|
A mapping with an unrecognized or missing |
Remaining mapping after |
|
Any non-mapping value under a config section, including scalars, lists, and |
Returned unchanged. |
C-family templates use type: import for render_c_action_body,
render_c_condition_body, render_c_reset_vars_body, to_c_identifier,
to_c_path_identifier, to_c_public_identifier,
to_c_public_macro_identifier, and is_c_public_identifier_reserved.
Jinja environment helpers
The default environment includes:
state constants:
INIT_STATEandEXIT_STATE;render helpers:
expr_render,stmt_render,stmts_render,operation_stmt_render, andoperation_stmts_render;text helpers:
normalize,to_identifier, andindent;normalizeusesunidecodeto transliterate Unicode text before identifier cleanup, so templates that accept non-ASCII machine names should test their emitted identifiers;render-time statement defaults:
_stmt_default_state_varsand_stmt_default_var_typesare injected only while rendering a fullStateMachineand supply default persistent variable names and types forstmt_render/stmts_renderwhen theirstate_vars/var_typesarguments are omitted;common Python builtins registered as filters, tests, or globals, including
str,set,dict,keys,values,enumerate,reversed, andfilter;operating-system environment variables from
os.environas globals when their names do not conflict with existing Jinja globals.
Environment variables are a convenience for controlled build environments. They are not a secret boundary: a trusted template can read any non-conflicting process environment variable visible to the generator process. A portable template should not depend on host-specific values unless that contract is documented by the project using the custom template.
File mapping, ignore, and clear semantics
Behavior |
Contract |
|---|---|
|
|
|
Non-template files copy with |
|
|
|
|
|
|
|
Parent directories are created for nested output paths. |
|
Rendered text is written as UTF-8 with |
|
Static assets are copied byte-for-byte. |
|
Output clearing unlinks symlinks, removes files, and recursively deletes directories. |
|
Other file types produce a defensive warning path. |
.git input ignoring does not protect an output directory. If --clear is
pointed at a working tree, the renderer follows output clearing rules for that
directory.
Built-in config examples
The built-in templates exercise the same contract:
pythondefines Python expression and statement styles and generated hook naming helpers.candc_polldefine C scope expression rendering, C runtime statement rendering, C identifier filters, and C runtime body helpers.cppandcpp_pollreuse the C-family helper layer while adding wrapper files; theirignoreslist also namesconfig.yamlredundantly, which is harmless because the renderer already skips the actual config file.
Legal and illegal examples
These examples are intentionally small. They show the shape accepted or rejected by the renderer; they are not complete production templates.
Case |
YAML |
Result |
|---|---|---|
Empty config. |
|
Legal. The renderer uses built-in defaults and no extra styles or helpers. |
Expression style. |
|
Legal. |
Statement style. |
|
Legal. The override affects assignment rendering for that style. |
Unknown key. |
|
Invalid. Move values under |
Wrong root. |
|
Invalid. The root must be a mapping. |
Invalid ignores. |
|
Invalid. |
Case |
YAML |
Result |
|---|---|---|
Canonical expression style. |
|
Legal. |
Alias expression style. |
|
Legal. The alias resolves to |
Statement style with expression language. |
|
Legal when |
Style is scalar. |
|
Invalid. Each style entry must be a mapping. |
Missing base. |
|
Invalid. |
Unknown base. |
|
Invalid unless the renderer later adds a |
Object-loading examples
Form |
YAML |
Notes |
|---|---|---|
Import a helper. |
|
The imported object is registered as a filter. |
Store a value. |
|
The literal value is available as |
Template callable with params. |
|
Positional arguments bind to |
Template callable without params. |
|
The callable renders the configured template without positional binding. |
Import target failure. |
|
Invalid at environment setup time; fix the Python import path. |
Unknown type. |
|
The remaining mapping is returned; do not use this as a public template pattern. |
Missing type. |
|
The mapping is returned as-is; use |
Statement helper examples
Call |
Use |
Boundary |
|---|---|---|
|
Render one executable statement node in Python syntax. |
Requires a statement node, not arbitrary text. |
|
Render a sequence of operation nodes for a target runtime style. |
Persistent variable and temporary-variable context matters. |
|
Render with a custom separator. |
Separator changes text layout, not semantics. |
|
Echo DSL-like operation text for docs or comments. |
Do not use as executable runtime source. |
Validation branch quick reference
Invalid shape |
Error family |
Repair |
|---|---|---|
Malformed YAML. |
YAML parse error. |
Fix indentation, quoting, or collection syntax before checking renderer facts. |
Comment-only file. |
Legal empty config. |
No repair needed; it behaves like |
|
Section type error. |
Use a mapping from style name to style mapping. |
|
Section type error. |
Use a mapping from test name to object-loading item. |
|
Ignore item type error. |
Quote each pattern as a string. |
|
Object-loading validation. |
Add the Jinja template string. |
|
Object-loading validation. |
Add the import path to the Python object. |
|
Object-loading validation. |
Add the literal value or remove the object if it is unused. |
Destructive output examples
ignores and .git protection apply to scanning the template input. They
do not protect the output directory. These examples are command-facing facts:
rendering with
--clearinto/tmp/generatedis appropriate when that directory is disposable;rendering with
--clearinto a project source directory can delete files in that directory before generation;static template files keep their original bytes, while rendered files are written as UTF-8 text with LF newlines;
a symlink already inside the output directory is unlinked during clear, not followed as a directory tree;
the defensive
clear-other-warningpath exists for uncommon file types and should not be presented as the primary cleanup behavior.
Review checklist
A template-config reference update is incomplete unless it answers these review questions:
did every top-level key keep a marker and visible row;
did every new validation branch get one legal repair and one invalid YAML shape;
did English and Chinese pages cover the same canonical style names, aliases, statement fields, object-loading forms, helpers, and file behaviors;
did the prose distinguish runtime statement rendering from DSL echo rendering;
did any destructive output behavior mention
--clearand the fact that input-side.gitignores do not protect output directories.