easygen icon indicating copy to clipboard operation
easygen copied to clipboard

Wiki: Using Nested Templates

Open suntong opened this issue 4 years ago • 0 comments

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:

https://github.com/go-easygen/easygen/blob/bd7819275ab39372e2826e239b6fdf5672530d7c/test/nested_thanks.tmpl#L1-L6

The driving data format is simple, and can be easily guessed from the template file:

https://github.com/go-easygen/easygen/blob/bd7819275ab39372e2826e239b6fdf5672530d7c/test/nested_data.yaml#L1-L5

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:

https://github.com/go-easygen/easygen/blob/bd7819275ab39372e2826e239b6fdf5672530d7c/test/nested_header_footer.ref#L5-L19

Check out the nested_header.tmpl and nested_footer.tmpl files for more details. And here they are FYC:

https://github.com/go-easygen/easygen/blob/23ee6943d7f8396676dcf5a17a4f24a3177fdea6/test/nested_header.tmpl#L1-L5

https://github.com/go-easygen/easygen/blob/23ee6943d7f8396676dcf5a17a4f24a3177fdea6/test/nested_footer.tmpl#L1-L8

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) ):

https://github.com/go-easygen/easygen/blob/bd7819275ab39372e2826e239b6fdf5672530d7c/test/sgdisk.yaml#L14-L25

https://github.com/go-easygen/easygen/blob/bd7819275ab39372e2826e239b6fdf5672530d7c/test/sgdisk-inc.tmpl#L1-L3

https://github.com/go-easygen/easygen/blob/bd7819275ab39372e2826e239b6fdf5672530d7c/test/sgdisk-emb.tmpl#L1

$ 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

  • https://stackoverflow.com/a/43428047/2125837
  • https://play.golang.org/p/gkdtvvJ1bb

https://github.com/go-easygen/easygen/blob/bd7819275ab39372e2826e239b6fdf5672530d7c/test/nested_demo_argsa.tmpl#L1-L5

Using the above nested_data.yaml file, with

easygen nested_demo_argsa.tmpl nested_data.yaml

will get:

https://github.com/go-easygen/easygen/blob/bd7819275ab39372e2826e239b6fdf5672530d7c/test/nested_demo_argsa.ref#L1

Using argsm

Based on

  • https://stackoverflow.com/a/43428608/2125837
  • https://play.golang.org/p/q2_eN-BSA3B

https://github.com/go-easygen/easygen/blob/bd7819275ab39372e2826e239b6fdf5672530d7c/test/nested_demo_argsm.tmpl#L1-L2

easygen nested_demo_argsm.tmpl nested_data.yaml

will get:

https://github.com/go-easygen/easygen/blob/bd7819275ab39372e2826e239b6fdf5672530d7c/test/nested_demo_argsm.ref#L1

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

  • https://stackoverflow.com/a/52086395/2125837 and
  • https://play.golang.org/p/Jzf4GK2ZZfG

https://github.com/go-easygen/easygen/blob/ca8d40675c04eafe128ed147b366beff3ca7a913/test/nested_demo_argsm_iterate.tmpl#L1-L10

easygen nested_demo_argsm_iterate.tmpl nested_data.yaml

will get:

https://github.com/go-easygen/easygen/blob/ca8d40675c04eafe128ed147b366beff3ca7a913/test/nested_demo_argsm_iterate.ref#L1-L12

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

suntong avatar Sep 26 '21 00:09 suntong