Ответ 1
Да. Я чувствую, что не нахожу решение, потому что не читаю пакет text/template
достаточно близко. Если вы используете html/template
, синтаксис один и тот же (и они говорят вам читать текст/шаблон;)). Вот полное рабочее решение для того, что вы, возможно, захотите сделать.
Файл Go:
package main
import (
"bytes"
"io/ioutil"
"os"
"strconv"
"text/template"
)
type Foo struct {
Id string
Name string
}
type Bar struct {
Id string
Name string
}
var foos []Foo
var bars []Bar
func main() {
foos = make([]Foo, 10)
bars = make([]Bar, 10)
for i := 0; i < 10; i++ {
foos[i] = Foo{strconv.Itoa(i), strconv.Itoa(i)} // just random strings
bars[i] = Bar{strconv.Itoa(10 * i), strconv.Itoa(10 * i)}
}
tmpl, err := ioutil.ReadFile("so.tmpl")
if err != nil {
panic(err)
}
buffer := bytes.NewBuffer(make([]byte, 0, len(tmpl)))
output := template.Must(template.New("FUBAR").Parse(string(tmpl)))
output.Execute(buffer, struct {
FooSlice []Foo
BarSlice []Bar
}{
FooSlice: foos,
BarSlice: bars,
})
outfile, err := os.Create("output.html")
if err != nil {
panic(err)
}
defer outfile.Close()
outfile.Write(buffer.Bytes())
}
Примечание. Возможно, вы можете сделать что-то, чтобы не загружать файл в промежуточный буфер (используйте ParseFiles
), я только что скопировал и вставил код, который я написал для одного из моих проектов.
Файл шаблона:
{{ $foos := .FooSlice }}
{{ $bars := .BarSlice }}
{{range $foo := $foos }}
<div>Foo {{$foo.Name}}</div>
<div>
{{range $bar := $bars}}
<div>Bar {{$bar.Name}} <input type="text" name="ids_{{$foo.Id}}_{{$bar.Id}}" /></div>
{{end}}
</div>
{{end}}
Две морали этой истории:
a) разумно использовать переменные в шаблонах, они полезны
b) диапазон в шаблонах также может устанавливать переменные, вам не нужно полагаться исключительно на $
или .