Skip to content

Templating in command files

DWE uses two layers of interpolation in command definitions: the lightweight ${...} syntax and full Go text/template blocks. Both are evaluated by the same engine and may be mixed freely.

The full template engine — ${...} namespaces, the render context, Go template control flow, built-in functions, sprout registries, and conventions — is documented in Templates. This page only covers the parts specific to command files; everything else is cross-cutting.

Templates inside workspace/commands/ render against RenderContext:

PathContents
.RawMerged workspace.yml + defaults.yml + local.yml as a nested map
.ParamsResolved param values (map keyed by param name)
.ContextResolved context values (map keyed by context name)
.FilesResolved file artefacts (map keyed by file id; each has a .Path field)
.Host.UID / .Host.GIDHost UID/GID strings

The ${...} namespaces (${vars.db.x}, ${param.x}, ${context.x}, ${files.id.path}, ${host.uid}) route into these same fields. See Templates for the full namespace table.

Three template helpers are available only in command files; they are not registered in info or render-pack templates:

HelperUse
resolve .Raw <dot.path>Dot-path lookup in merged config (same as ${dot.path})
resolveMap .Params <key>Key lookup in a flat map (same as ${param.key} / ${context.key})
resolveFile .Files <id> <subkey>Subkey lookup in a resolved file artefact

They walk maps and return "" on miss — useful when the key has a dot or a numeric segment that breaks the direct .Raw.x.y form.

# helpers chained via pipe
files:
log:
access: write
path: ".dwe/logs/{{ .Params.task }}_{{ now | date \"2006-01-02_15-04-05\" }}.log"
mkdir: true
# pipeline form: pass a value through a function
env:
SCRIPT_NAME: '{{ .Params.script_path | pathBase }}'
# mixing the two syntaxes
path: "${param.dump_dir}/${param.database}{{ if .Params.dump_date }}_{{ now | date \"2006-01-02\" }}{{ end }}.sql.gz"
LocationTemplated
messages.success, messages.erroryes
confirmation_textyes
cmd, argv, workdir, compose_argsyes
env: map valuesyes
files.*.path, files.*.candidates[].path/glob/matchyes
params.*.default_from, context.*.fromno — plain dot-paths only
Workflow steps[].with[<key>], steps[].whenyes
description, group.title, group.descriptionno — printed verbatim by commands list / commands -i / completion

Command-template space (the full reference)

Section titled “Command-template space (the full reference)”

When the docs say “command template space” this is the set of expressions available inside any templated field of a command:

ExpressionMeaning
${<dot.path>}Lookup in merged DweConfig.Raw
${param.<name>}Resolved param
${context.<name>}Resolved context value
${files.<id>.path}Absolute path of a file artefact
${args}Pass-through arguments the caller wrote after -- — see Pass-through arguments. Valid in cmd:/argv: of shell / dwe / service_exec / service_run
${host.uid} / ${host.gid}Effective UID/GID for container --user
{{ .Raw.x.y }}Direct dot access on the merged config
{{ .Params.<name> }}Direct dot access on params
{{ .Context.<name> }}Direct dot access on context
{{ .Host.UID }}Host info (Go template form)
{{ now | date "..." }} / {{ pathBase }} / {{ pathDir }} / {{ appURL ... }}Helper functions (sprout + domain)

Use the simpler ${...} form for one-off lookups; reach for {{ ... }} when you need conditionals, comparisons, or pipelines.