Using Nested Templates
To include other Go templates from within templates, there exist a template function to be used inside template tags, which takes a “template name” and optionally a data cursor. For example the {{ template "header" }} and {{ template "footer" }} in the following example:
|
{{ template "header" }} |
|
Dear {{ .Name }}, |
|
|
|
Thank you for your order! Your order number is {{ .OrderNumber }} and it |
|
has been shipped on {{ .ShipDate }}. |
|
{{ template "footer" }} |
The driving data format is simple, and can be easily guessed from the template file:
|
Name: Sam |
|
OrderNumber: 123456 |
|
Price: 1234.56 |
|
Shipped: true |
|
ShipDate: "Wednesday, January 06, 2021" |
To put them together, use the following command (which is a short form for the equally working "easygen nested_header.tmpl,nested_footer.tmpl,nested_thanks.tmpl nested_data.yaml" command):
easygen nested_header,nested_footer,nested_thanks nested_data
It'll give what is expected:
|
WidgetCo, Ltd. |
|
463 Shoe Factory Rd. |
|
Hamford, VT 20202 |
|
|
|
Dear Sam, |
|
|
|
Thank you for your order! Your order number is 123456 and it |
|
has been shipped on Wednesday, January 06, 2021. |
|
|
|
|
|
2021-09-25 |
|
|
|
Thank you for your business, |
|
WidgetCo Order Fulfillment Department |
|
Ph: 818-555-0123 Email: orders@widgetco.com |
Check out the nested_header.tmpl and nested_footer.tmpl files for more details. And here they are FYC:
|
{{define "header"}} |
|
WidgetCo, Ltd. |
|
463 Shoe Factory Rd. |
|
Hamford, VT 20202 |
|
{{end}} |
|
{{define "footer"}} |
|
|
|
{{date "I"}} |
|
|
|
Thank you for your business, |
|
WidgetCo Order Fulfillment Department |
|
Ph: 818-555-0123 Email: orders@widgetco.com |
|
{{end}} |
Credit: the template and data are based from this blog post.
Passing Variables between Templates
The template action used to include nested templates also allows a second parameter to pass data to the nested template. Like the following example from here (Noticed that it was gone as of 2021-09-20, so putting my personal cache here):
// Define a nested template called header
{{define "header"}}
<h1>{{.}}</h1>
{{end}}
// Call template and pass a name parameter
{{range .Items}}
<div class="item">
{{template "header" .Name}}
<span class="price">${{.Price}}</span>
</div>
{{end}}
Example in easygen test case ( sgdisk-emb.tmpl & sgdisk-inc.tmpl (Note the usage of {{ template "sgdisk_cmd" .}} in it) ):
|
Partitions: |
|
- Name: bios_boot |
|
Type: ef02 |
|
Size: +200M |
|
|
|
- Name: linux_boot |
|
Type: 8300 |
|
Size: +20G |
|
|
|
- Name: windows |
|
Type: "0700" |
|
Size: +30G |
|
sgdisk -Z {{.Disk}} |
|
{{range .Partitions}} |
|
{{ template "sgdisk_cmd" .}}{{end}} |
|
{{define "sgdisk_cmd"}} sgdisk -n 0:0:{{.Size}} -t 0:{{.Type}} -c 0:"{{.Name}}"{{end}} |
$ easygen sgdisk-emb,sgdisk-inc sgdisk
sgdisk -Z /dev/sdb
sgdisk -n 0:0:+200M -t 0:ef02 -c 0:"bios_boot"
sgdisk -n 0:0:+20G -t 0:8300 -c 0:"linux_boot"
sgdisk -n 0:0:+30G -t 0:0700 -c 0:"windows"
sgdisk -n 0:0:+10G -t 0:8200 -c 0:"linux_swap"
sgdisk -n 0:0:+12G -t 0:8300 -c 0:"os1"
sgdisk -n 0:0:+12G -t 0:8300 -c 0:"os2"
sgdisk -n 0:0:+12G -t 0:8300 -c 0:"os3"
sgdisk -n 0:0:0 -t 0:8300 -c 0:"data"
Passing more arguments to Nested Templates
What if we need to pass more than one arguments to to the nested template?
Using argsa
Based on
|
{{define "t1"}} |
|
{{- index . 0}} {{index . 1}} {{index . 2}} {{(index . 3).Name}} {{(index . 3).OrderNumber}} |
|
{{end -}} |
|
|
|
Got: {{template "t1" argsa 543 false 0.1234 .}} |
Using the above nested_data.yaml file, with
easygen nested_demo_argsa.tmpl nested_data.yaml
will get:
|
Got: 543 false 0.1234 Sam 123456 |
Using argsm
Based on
|
{{template "image_row" argsm "a" 1 "b" "somestring" "c" .}} |
|
{{define "image_row"}}a={{$.a}}, b={{$.b}}, c.Shipped={{$.c.Shipped}}, c.Price={{$.c.Price}}{{end}} |
easygen nested_demo_argsm.tmpl nested_data.yaml
will get:
|
a=1, b=somestring, c.Shipped=true, c.Price=1234.56 |
Using loop inside a Go template
What if we need to loop over the nested template, and pass the current loop number to the nested template, apart from the rest of the existing arguments?
Based on
|
{{- define "T1"}}Apple{{.i}} at {{.c.Price}} - {{.c.Shipped}}{{end}} {{- define "T2"}}Ape{{end}} |
|
{{- range $val := iterate "5" }} |
|
{{- template "T2"}} ate {{template "T1" argsm "c" $ "i" (printf "%06d" $val)}}{{ $val }} |
|
{{end }} |
|
{{- range $val := iterate "2" (ENV "__START") }} |
|
{{- template "T2"}} ate {{template "T1" argsm "c" $ "i" (printf "%06d" $val)}}{{ $val }} |
|
{{end }} |
|
{{- range $val := iterate "1003" "1001" }} |
|
{{- template "T2"}} ate {{template "T1" argsm "c" $ "i" (printf "%06d" $val)}}{{ $val }} |
|
{{end }} |
easygen nested_demo_argsm_iterate.tmpl nested_data.yaml
will get:
|
Ape ate Apple000000 at 1234.56 - true0 |
|
Ape ate Apple000001 at 1234.56 - true1 |
|
Ape ate Apple000002 at 1234.56 - true2 |
|
Ape ate Apple000003 at 1234.56 - true3 |
|
Ape ate Apple000004 at 1234.56 - true4 |
|
Ape ate Apple000005 at 1234.56 - true5 |
|
Ape ate Apple000000 at 1234.56 - true0 |
|
Ape ate Apple000001 at 1234.56 - true1 |
|
Ape ate Apple000002 at 1234.56 - true2 |
|
Ape ate Apple001001 at 1234.56 - true1001 |
|
Ape ate Apple001002 at 1234.56 - true1002 |
|
Ape ate Apple001003 at 1234.56 - true1003 |
I.e., the undefined (or invalid) environment variable __START will be interpreted as starting at zero (0).
When it is defined:
$ __START=1 easygen nested_demo_argsm_iterate.tmpl nested_data.yaml | diff -wU1 nested_demo_argsm_iterate.ref -
--- nested_demo_argsm_iterate.ref 2021-09-26 09:29:00.172699800 -0400
+++ - 2021-09-26 09:35:48.721988500 -0400
@@ -6,3 +6,2 @@
Ape ate Apple000005 at 1234.56 - true5
-Ape ate Apple000000 at 1234.56 - true0
Ape ate Apple000001 at 1234.56 - true1
Using Nested Templates
To include other Go templates from within templates, there exist a template function to be used inside template tags, which takes a “template name” and optionally a data cursor. For example the
{{ template "header" }}and{{ template "footer" }}in the following example:easygen/test/nested_thanks.tmpl
Lines 1 to 6 in bd78192
The driving data format is simple, and can be easily guessed from the template file:
easygen/test/nested_data.yaml
Lines 1 to 5 in bd78192
To put them together, use the following command (which is a short form for the equally working "
easygen nested_header.tmpl,nested_footer.tmpl,nested_thanks.tmpl nested_data.yaml" command):easygen nested_header,nested_footer,nested_thanks nested_dataIt'll give what is expected:
easygen/test/nested_header_footer.ref
Lines 5 to 19 in bd78192
Check out the nested_header.tmpl and nested_footer.tmpl files for more details. And here they are FYC:
easygen/test/nested_header.tmpl
Lines 1 to 5 in 23ee694
easygen/test/nested_footer.tmpl
Lines 1 to 8 in 23ee694
Credit: the template and data are based from this blog post.
Passing Variables between Templates
The
templateaction used to include nested templates also allows a second parameter to pass data to the nested template. Like the following example from here (Noticed that it was gone as of 2021-09-20, so putting my personal cache here):Example in
easygentest case ( sgdisk-emb.tmpl & sgdisk-inc.tmpl (Note the usage of{{ template "sgdisk_cmd" .}}in it) ):easygen/test/sgdisk.yaml
Lines 14 to 25 in bd78192
easygen/test/sgdisk-inc.tmpl
Lines 1 to 3 in bd78192
easygen/test/sgdisk-emb.tmpl
Line 1 in bd78192
Passing more arguments to Nested Templates
What if we need to pass more than one arguments to to the nested template?
Using argsa
Based on
easygen/test/nested_demo_argsa.tmpl
Lines 1 to 5 in bd78192
Using the above nested_data.yaml file, with
easygen nested_demo_argsa.tmpl nested_data.yamlwill get:
easygen/test/nested_demo_argsa.ref
Line 1 in bd78192
Using argsm
Based on
easygen/test/nested_demo_argsm.tmpl
Lines 1 to 2 in bd78192
easygen nested_demo_argsm.tmpl nested_data.yamlwill get:
easygen/test/nested_demo_argsm.ref
Line 1 in bd78192
Using loop inside a Go template
What if we need to loop over the nested template, and pass the current loop number to the nested template, apart from the rest of the existing arguments?
Based on
easygen/test/nested_demo_argsm_iterate.tmpl
Lines 1 to 10 in ca8d406
easygen nested_demo_argsm_iterate.tmpl nested_data.yamlwill get:
easygen/test/nested_demo_argsm_iterate.ref
Lines 1 to 12 in ca8d406
I.e., the undefined (or invalid) environment variable
__STARTwill be interpreted as starting at zero (0).When it is defined: