armnotstrong
armnotstrong

Reputation: 9065

How can I get the struct field of a map elem in Go's html/template?

I have a Struct Task:

type Task struct {
   cmd string
   args []string
   desc string
}

And I init a map which take the above Task struct as a value and a string as a key(the task name)

var taskMap = map[string]Task{
    "find": Task{
        cmd: "find",
        args: []string{"/tmp/"},
        desc: "find files in /tmp dir",
    },
    "grep": Task{
        cmd: "grep",
        args:[]string{"foo","/tmp/*", "-R"},
        desc: "grep files match having foo",
    },
}

and I want to parse a html page using html/template just using the above taskMap.

func listHandle(w http.ResponseWriter, r *http.Request){
    t, _ := template.ParseFiles("index.tmpl")
    t.Execute(w, taskMap)
}

Here is the index.tmpl:

<html>
{{range $key, $value := .}}
   <li>Task Name:        {{$key}}</li>
   <li>Task Value:       {{$value}}</li>
   <li>Task description: {{$value.desc}}</li>
{{end}}
</html>

I can get the $key and value printed successfully, but When It comes to the field of Task using {{$value.desc}} it wont work.

How can I get the desc of each task in this case?

Upvotes: 4

Views: 955

Answers (1)

icza
icza

Reputation: 418575

Note: you can try/check out your working modified code in the Go Playground.


If you want the template package to be able to access the fields, you have to export the fields. You can export a field by starting it with an uppercase letter:

type Task struct {
   cmd string
   args []string
   Desc string
}

Note that I only changed Desc here, you have to uppercase any other fields you want to refer to in the template.

After this exporting, change all references to uppercase Desc of course:

var taskMap = map[string]Task{
    "find": Task{
        cmd: "find",
        args: []string{"/tmp/"},
        Desc: "find files in /tmp dir",
    },
    "grep": Task{
        cmd: "grep",
        args:[]string{"foo","/tmp/*", "-R"},
        Desc: "grep files match having foo",
    },
}

And also in the template:

<html>
{{range $key, $value := .}}
   <li>Task Name:        {{$key}}</li>
   <li>Task Value:       {{$value}}</li>
   <li>Task description: {{$value.Desc}}</li>
{{end}}
</html>

Output:

<html>

<li>Task Name:        find</li>
<li>Task Value:       {find [/tmp/] find files in /tmp dir}</li>
<li>Task description: find files in /tmp dir</li>

<li>Task Name:        grep</li>
<li>Task Value:       {grep [foo /tmp/* -R] grep files match having foo}</li>
<li>Task description: grep files match having foo</li>

</html>

Upvotes: 3

Related Questions