Tip: Go template usage tips - go-easygen/easygen GitHub Wiki
https://stackoverflow.com/questions/34917099/go-template-comparison-operators-on-missing-map-key
it gives an error if the key doesn't exist
Use the index function:
{{if eq (index .MyMap "KeyThatDoesntExist") "mystring"}}
{{.}}
{{end}}
The index
function returns the zero value for the map value type when the key is not in the map. The zero value for the map in the question is the empty string.
https://dev-qa.com/1835828/how-do-i-check-the-length-of-an-array-in-golang-html-templates
How do I check the length of an array in Golang html templates?
That's the way to do it.
{{ $length := len .YourArray }}
{{ if eq $length 0 }}
array has zero length
{{ end }}
Simply display the size as follows {{ len .YourArray }}
See
See also, https://medium.com/learning-the-go-programming-language/comparing-values-in-go-8f7b002e767a
https://github.com/hashicorp/consul-template/issues/267
You can use Go's template print
and printf
functions: http://golang.org/pkg/text/template/.
{{$first := "data"}}{{$second := "base"}}
{{range service (print $first $second) "any"}}
upstream {{.ID}} { {{.Address}}:{{.Port}}; } {{end}}
if you need to concatenate an int with a string.
{{ range $hkey, $hval := scratch.Get "map" }}
{{ $combine := (printf "%v@%v" $hkey $hval) }}
{{ $combine }}
{{end}}
https://stackoverflow.com/questions/54156119/range-over-string-slice-in-golang-template
I have a struct that contains a slice of type string like the following.
type Data struct { DataFields []string }
Within my html template file I would like to range over the string slice. However, the individual fields are just strings without any struct name. How can I loop over a slice that contains a simple type such as string, int, etc?
Use .
to refer to a simple values like a string, int, etc.
{{range .DataFields}}{{.}}{{end}}
You can also assign to a template variable as in {{range $v := .DataFields}}{{$v}}{{end}}
, but that's extra work. Embrace the .
.
Or assign it to a variable, similar to a normal Go range clause:
{{range $element := .DataFields}} {{$element}} {{end}}
From the docs for text/template (serves as interface docs for html/template):
{{range pipeline}} T1 {{end}}
The value of the pipeline must be an array, slice, map, or channel.
If the value of the pipeline has length zero, nothing is output;
otherwise, <b>dot is set to the successive elements of the array,
slice, or map</b> and T1 is executed. If the value is a map and the
keys are of basic type with a defined order ("comparable"), the
elements will be visited in sorted key order.</pre>
...
A pipeline inside an action may initialize a variable to capture the result. The initialization has syntax
$variable := pipeline
...
If a "range" action initializes a variable, the variable is set to the successive elements of the iteration. Also, a "range" may declare two variables, separated by a comma:
range $index, $element := pipeline
in which case $index and $element are set to the successive values of the array/slice index or map key and element, respectively. Note that if there is only one variable, it is assigned the element; this is opposite to the convention in Go range clauses.
(bold portions emphasized by me)
So one can lookup a constant key on variable map $x with
$x.key1
, but is it possible to doamap.$key
?
A simpler way would be to do: {{.Amap.key1}}
. However, this will only work if the key is alphanumeric. If not, you'll need to access it using index
.
{{index .Amap "key1"}}
From the [documentation][https://golang.org/pkg/text/template/#hdr-Arguments]:
- The name of a key of the data, which must be a map, preceded
by a period, such as
.Key
The result is the map element value indexed by the key.
Key invocations may be chained and combined with fields to any
depth:
.Field1.Key1.Field2.Key2
Although the key must be an alphanumeric identifier, unlike with
field names they do not need to start with an upper case letter.
Keys can also be evaluated on variables, including chaining:
$x.key1.key2
How do I access an array item (e.g. a2) in templates?
You need to use the index
template function.
{{index .a 2}}
How do I directly access substrings (e.g. s[:2]) in Go templates?
You may use the slice
template function on string
s too (it was added in Go 1.13):
slice slice returns the result of slicing its first argument by the remaining arguments. Thus "slice x 1 2" is, in Go syntax, x[1:2], while "slice x" is x[:], "slice x 1" is x[1:], and "slice x 1 2 3" is x[1:2:3]. The first argument must be a string, slice, or array.
For example:
t := template.Must(template.New("").Parse(`{{ slice . 0 2 }}`))
if err := t.Execute(os.Stdout, "abcdef"); err != nil {
panic(err)
}
This will output (try it on the Go Playground):
ab
Don't forget that Go strings store the UTF-8 encoded byte sequence, and indexing and slicing strings uses the byte index (not the rune
index). This matters when the string contains multi-byte runes, like in this example:
t := template.Must(template.New("").Parse(`{{ slice . 0 3 }}`))
if err := t.Execute(os.Stdout, "世界"); err != nil {
panic(err)
}
This will output a single rune
(try it on the Go Playground):
世
https://go.dev/play/p/olgfaazf5tb
package main
import (
"os"
"text/template"
)
func main() {
t := template.Must(template.New("").Parse(`{{ slice . 3 9 }}`))
if err := t.Execute(os.Stdout, "abc世界def"); err != nil {
panic(err)
}
}