gotmpl_inline Transform
Execute an inline Go template directly in the panconf configuration. This transform provides the same functionality as gotmpl but without requiring a separate template file.
Usage
node:
database:
from_file: database.yaml
cache:
from_file: cache.yaml
config:
to_file: config.yaml
transform:
gotmpl_inline:
tmpl: |
services:
database:
{{ .database | toYaml | nindent 4 }}
cache:
{{ .cache | toYaml | nindent 4 }}
Template Context
Templates have access to:
| Variable |
Description |
.nodeName |
Parsed node data (direct access to fields) |
.meta.nodeName.path |
Node file path (via .meta) |
.meta.nodeName.format |
Node file format (via .meta) |
.self |
Input data in hybrid nodes (nodes with from_* + transform) |
.meta.self.path |
Input file path in hybrid nodes |
Template Functions
All Sprig functions are available, plus these panconf-specific functions:
| Function |
Example |
Description |
toYaml |
{{ .config | toYaml }} |
Convert value to YAML string |
toToml |
{{ .config | toToml }} |
Convert value to TOML string |
toJson |
{{ .config | toJson }} |
Convert value to JSON string (Sprig) |
nindent |
{{ .config | toYaml | nindent 2 }} |
Add newline and indent (Sprig) |
indent |
{{ .config | toYaml | indent 2 }} |
Add indent without newline (Sprig) |
env |
{{ env "HOME" }} |
Get environment variable (Sprig) |
Output Format
The template output must be valid YAML or JSON. This is because panconf parses the output to enable:
- Re-encoding to different formats (JSON, YAML, TOML)
- Using the output as input for other nodes via
{{.nodeName}}
Examples
Basic Composition
Compose multiple configs into a single structured output:
node:
app:
from_file: app.yaml
db:
from_file: database.yaml
config:
to_file: config.yaml
transform:
gotmpl_inline:
tmpl: |
application:
{{ .app | toYaml | nindent 2 }}
database:
{{ .db | toYaml | nindent 2 }}
Extract and Transform
Extract specific fields and transform them:
node:
source:
from_file: full-config.yaml
minimal:
to_file: minimal.json
transform:
gotmpl_inline:
tmpl: |
{
"name": "{{ .source.app.name }}",
"version": "{{ .source.app.version }}",
"debug": {{ .source.settings.debug | default false }}
}
Using Intermediate Nodes
Combine with intermediate nodes for complex pipelines:
node:
base:
from_file: base.yaml
env:
from_file: production.yaml
# Intermediate: merge configs (no file written)
merged:
transform:
deepMerge:
- "{{.base}}"
- "{{.env}}"
# Final: wrap merged config with metadata
final:
to_file: config.yaml
transform:
gotmpl_inline:
tmpl: |
metadata:
generated: "{{ now | date "2006-01-02T15:04:05Z07:00" }}"
environment: production
config:
{{ .merged | toYaml | nindent 2 }}
Iterating Over Glob Documents
Access individual files from a glob input. Glob documents are named by filename stem:
node:
services:
from_glob: "services/*.yaml" # e.g., api.yaml, web.yaml
manifest:
to_file: manifest.yaml
transform:
gotmpl_inline:
tmpl: |
services:
api:
{{ .services.api | toYaml | nindent 4 }}
web:
{{ .services.web | toYaml | nindent 4 }}
For dynamic iteration over all glob documents, use jq instead:
node:
services:
from_glob: "services/*.yaml"
manifest:
to_file: manifest.yaml
transform:
jq: |
{
services: $services | to_entries | map({
name: .key,
config: .value
})
}
Using Environment Variables
node:
config:
from_file: config.yaml
final:
to_file: config.json
transform:
gotmpl_inline:
tmpl: |
{
"environment": "{{ env "APP_ENV" | default "development" }}",
"config": {{ .config | toJson }}
}
Conditional Content
node:
config:
from_file: config.yaml
output:
to_file: output.yaml
transform:
gotmpl_inline:
tmpl: |
app:
name: {{ .config.name }}
{{- if .config.debug }}
debug:
enabled: true
level: {{ .config.debugLevel | default "info" }}
{{- end }}
Comparison with gotmpl
| Aspect |
gotmpl |
gotmpl_inline |
| Template location |
Separate file |
Inline in panconf config |
| Additional data files |
Supported via args |
Not supported |
.Data variable |
Available |
Not available |
| Best for |
Complex templates, reusable templates |
Simple transformations, composition |
Use gotmpl_inline when:
- The template is short and specific to this config
- You want everything in one file
- You're mainly composing/restructuring existing inputs
Use gotmpl when:
- The template is complex or reusable
- You need additional data files merged into
.Data
- You prefer templates in separate files
Common Patterns
Wrap Config with Metadata
gotmpl_inline:
tmpl: |
version: "1.0"
generated: "{{ now | date "2006-01-02" }}"
data:
{{ .source | toYaml | nindent 2 }}
Merge and Restructure
gotmpl_inline:
tmpl: |
combined:
from_a: {{ .a.value }}
from_b: {{ .b.value }}
nested:
{{ .c | toYaml | nindent 4 }}
Generate Lists
gotmpl_inline:
tmpl: |
items:
{{- range $key, $val := .config }}
- key: {{ $key }}
value: {{ $val }}
{{- end }}