data — Data & Config Templates
The data template type generates hierarchical data files: HTML, JSON, YAML, XML, and TOML. No generator import is needed — the format is selected at call time. The body uses a bloc syntax that maps directly to nested tag or key structures.
Bloc Syntax
A bloc is a name, optional inline attributes, and an optional body of nested blocs and value attributes.
tagName(inlineAttr: value, ...) {
bodyAttr: value,
nestedTag(attr: val) {
deepAttr: "text"
}
}
All three parts — name, inline attrs, body — are optional. The same syntax generates HTML tags, JSON keys, and YAML keys depending on the format selected.
Value Types
String values use double quotes. Parameter substitution with $${ } works inside strings.
data [html, json] card(name: String, email: String) {
div(class: "user-card") {
h1: "$${name}",
p(class: "email"): "$${email}"
}
}
Numeric and boolean values need no quotes.
data [json, yaml] service(name: String) {
{
name: "$${name}",
port: 8080,
replicas: 3,
enabled: true
}
}
Arrays use square brackets.
data [json] config(app: String) {
{
name: "$${app}",
profiles: ["dev", "test", "prod"],
features: ["auth", "metrics"]
}
}
Supported Formats
HTML renders blocs as nested tags. Inline attrs become HTML attributes.
data [html] page(title: String, body: String) {
html {
head { title: "$${title}" },
body {
div(class: "container") {
h1: "$${title}",
p: "$${body}"
}
}
}
}
JSON and YAML render the top-level bloc as an object. Nested blocs become nested objects.
data [json, yaml] k8sDeployment(name: String, image: String) {
{
apiVersion: "apps/v1",
kind: "Deployment",
metadata {
name: "$${name}"
},
spec {
replicas: 1,
template {
spec {
containers: [
{ name: "$${name}", image: "$${image}" }
} } } } }
XML renders blocs as XML elements.
data [xml] androidManifest(app: String, pkg: String) {
manifest(xmlns:android: "http://schemas.android.com/apk/res/android",
package: "$${pkg}") {
application(android:label: "$${app}") {
<[ renderActivities(activities) ]>
}
}
}
TOML renders the structure as TOML tables and key-value pairs. ]
Includes
The <[ call() ]> syntax splices another template or function's output into the body.
data [html] table(headers: List, rows: List) {
table(class: "data-table") {
thead { <[ renderHeaders(headers) ]> },
tbody { <[ renderRows(rows) ]> }
}
}
data [html] th(label: String) spec {
th: "$${label}"
}
data [html] td(value: String) spec {
td: "$${value}"
}
Calling and Generating
Pass the format name as the first argument. Generator.generate() converts the leaf to a string.
func main(): String {
let jsonLeaf = config("myapp")
let yamlLeaf = config("myapp")
let json = Generator.generate(jsonLeaf)
let yaml = Generator.generate(yamlLeaf)
File.write("config.json", json, true)
File.write("config.yml", yaml, true)
return "done"
}
Wait — the format selector is the first argument. For a template declared as data [json, yaml] config(name: String), call config("json", "myapp") for JSON output and config("yaml", "myapp") for YAML.