I need to return form the text template key value which will be like comment and command like following
#Description for npm install npm install #Description for test npm test #Description for test2 run test2
For that I've created a function like the following:
// example with switch func (d Dependency) TypeCommand() Command { switch d.Type { case "runner": cmd1 := Command{"#Description for npm install", "npm install"} cmd2 := Command{"#Description for test", "npm test"} cmd3 := Command{"#Description for test2", "run test2"} case "runner2": return "test 2" } return "command_baz" }
The template is:
const tmpl = ` {{- range .File.Dependency}} {{.TypeCommand}} {{end}}` type Command struct { Info string Command string }
When I change the template to the following, I get an error:
const tmpl = ` {{- range .File.Dependency}} {{ TypeCommand .}} {{ range .Command}} {{ .Info }} {{ .Command }} {{end}} {{end}} '
executing "tmpl3.txt" at <.Command>: can't evaluate field Command in type *Dependency
I use this as reference.
2 Answers
Answers 1
The error message you're getting is because you're just throwing away the return value of TypeCommand
instead of passing it on to where you try to access its struct fields. We could fix that, but that's probably not what you wanted to do anyways, since your TypeCommand
function looks like it should probably be returning multiple commands instead of a single one. So let's re-write that first:
func (d Dependency) TypeCommand() []Command { switch d.Type { case "runner": return []Command{ Command{"#Description for npm install", "npm install"}, Command{"#Description for test", "npm test"}, Command{"#Description for test2", "run test2"}, } case "runner2": return []Command{Command{"#test 2", "foo"}} } return []Command{Command{"#command_baz", "baz"}} }
Now that we're returning multiple commands, we can just range over them in the template and they'll be automatically bound. I tweaked your template a little bit to the following:
const tmpl = ` {{- range .File.Dependency}} {{- range .TypeCommand }} {{ .Info}} {{ .Command}} {{- end}}{{end}}`
When I ran this in the Go Playground, this got me the following output, which seemed to be what you were going for:
#Description for npm install npm install #Description for test npm test #Description for test2 run test2 #test 2 foo
Answers 2
package main import ( "os" "text/template" ) type File struct { TypeVersion string `yaml:"_type-version"` Dependency []Dependency } type Dependency struct { Name string Type string CWD string } type Command struct { Info string Command string } func (d Dependency) TypeCommand() []Command { switch d.Type { case "runner": return []Command{ {"#Description for npm install", "npm install"}, {"#Description for test", "npm test"}, {"#Description for test2", "run test2"}, } case "runner2": return []Command{{"#test 2", "foo"}} } return []Command{{"#command_baz", "baz"}} } type Install map[string]string const tmpl = ` {{- range .File.Dependency}} {{- range .TypeCommand }} {{ .Info}} {{ .Command}} {{- end}}{{end}}` type API map[string]string func main() { f := new(File) f.Dependency = []Dependency{{ Name: "ui", Type: "runner", CWD: "/ui", }, { Name: "ui2", Type: "runner2", CWD: "/ui2", }} t, err := template.New("t").Parse(tmpl) if err != nil { panic(err) } var data struct { File *File API API } data.File = f if err := t.Execute(os.Stdout, data); err != nil { panic(err) } }
This Should Work Properly.
The main problem was with the return type of the method of Dependency
0 comments:
Post a Comment