Custom delimiters
Jinja2’s {{ }} collides with Helm, Go text/template, GitHub Actions,
Terraform’s ${}-adjacent tooling and plenty of other things you might want to
scaffold. deckctl solves this by letting each template pick its own delimiters.
The defaults
Section titled “The defaults”| Kind | Start | End |
|---|---|---|
| Variable | {{ | }} |
| Block | {% | %} |
| Comment | {# | #} |
Overriding them
Section titled “Overriding them”delimiters: variable_start: "[[" variable_end: "]]" block_start: "[%" block_end: "%]" comment_start: "[#" comment_end: "#]"You only need to set what you’re changing — anything omitted falls back to the
default. Each pair must be both set or both empty; setting
variable_start without variable_end fails validation.
Now a Helm chart renders safely:
# values.yaml.tmpl — rendered by deckctl using [[ ]]replicaCount: [[ replicas ]]image: repository: [[ image_repo ]] tag: "[[ image_tag ]]"# templates/deployment.yaml.tmpl — Helm's own {{ }} passes straight throughapiVersion: apps/v1kind: Deploymentmetadata: name: {{ include "chart.fullname" . }}spec: replicas: {{ .Values.replicaCount }}The other option: don’t add a suffix
Section titled “The other option: don’t add a suffix”Delimiters only matter for files deckctl actually renders. A file with no
template suffix is copied byte-for-byte, {{ }} and all:
helm-chart/ deckctl.yaml Chart.yaml.tmpl ← rendered (needs variables) values.yaml.tmpl ← rendered (needs variables) templates/deployment.yaml ← copied verbatim, Helm syntax untouched templates/service.yaml ← copied verbatimThis is usually the simpler answer for Helm: only the handful of files that genuinely need substitution get a suffix, and the chart templates stay as-is with no delimiter gymnastics.
Reach for custom delimiters when a single file needs both — deckctl
substitution and literal {{ }} in the output.
Which delimiters to pick
Section titled “Which delimiters to pick”Any string works, but a few conventions:
| Delimiters | Good for |
|---|---|
[[ ]] / [% %] / [# #] | Helm, Go templates, anything using {{ }} |
<< >> / <% %> | ERB-ish contexts, or when [ is meaningful (JSON/HCL lists) |
{{{ }}} | Mustache-adjacent contexts — but easy to misread; avoid |
Pick something that cannot appear literally in the file type you’re generating.
Copier’s _envops
Section titled “Copier’s _envops”Copier templates express the same thing through _envops, and deckctl maps it
one-to-one:
_envops: variable_start_string: "[[" variable_end_string: "]]" block_start_string: "[%" block_end_string: "%]" comment_start_string: "[#" comment_end_string: "#]"See Copier compatibility.
Verifying
Section titled “Verifying”--dry-run prints the rendered content of every file, which is the fastest way
to confirm the delimiters do what you think:
deckctl template apply helm-chart /tmp/out --source local --dry-run