Sunday, June 3, 2018

Golang - Text/template return key value

Leave a Comment

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

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment