全局模板数据

When doing ExecuteTemplate I see all examples using &whateversruct{Title: "title info", Body: "body info"} to send data to the template to replace the info. I was wondering if its possible to not have to create a struct outside my handler function because every handler function I have is not going to have the same Title, Body. It would be nice to be able to send it a map that replaces the template info. Any thoughts or ideas?

Currently - loosely written

type Info struct {
    Title string
    Body string
}

func View(w http.ResponseWriter) {
    temp.ExecuteTemplate(w, temp.Name(), &Info{Title: "title", Body: "body"})
}

Just seems like creating the struct is unnecessary. And the struct would not be the same for each function you create. So you would have to create a struct for each function (that I know of).

That struct is just an example. You could pass in the struct from the outside too, or you could use a map as you suggested. A struct is nice because the type of the struct can document what fields the template expects, but it's not required.

All of these should work:

func View(w http.ResponseWriter, info Info) {
    temp.ExecuteTemplate(w, temp.Name(), &info)
}

func View(w http.ResponseWriter, info *Info) {
    temp.ExecuteTemplate(w, temp.Name(), info)
}

func View(w http.ResponseWriter, info map[string]interface{}) {
    temp.ExecuteTemplate(w, temp.Name(), info)
}

You are totally right Kevin!!! I like this totally better. Thanks!!!

func View(w http.ResponseWriter) {
    info := make(map[string]string)
    info["Title"] = "About Page"
    info["Body"] = "Body Info"
    temp.ExecuteTemplate(w, temp.Name(), info)
}

To augment Kevin's answer: An anonymous struct will yield much the same behaviour:

func View(w http.ResponseWriter) {
    data := struct {
        Title string
        Body  string
    } {
        "About page",
        "Body info",
    }

    temp.ExecuteTemplate(w, temp.Name(), &data)
}

An important distinction between applying a template to a struct vs. to a map: with a map, you can make references in your template which don't exist in your map; the template will execute with no errors and the references will just be empty. If you process against a struct and make a reference to something that doesn't exist in your struct, the template execution returns an error.

Referencing items which don't exist in your map can be useful. Consider the menu.html and the getPage() function in views.go in this sample webapp: https://bitbucket.org/jzs/sketchground/src. By using a map for the menu, the active menu item is easily highlighted.

A simple illustration of this difference:

package main

import (
    "fmt"
    "html/template"
    "os"
)

type Inventory struct {
    Material string
    Count    uint
}

func main() {
    // prep the template
    tmpl, err := template.New("test").Parse("{{.Count}} items are made of {{.Material}} - {{.Foo}}
")
    if err != nil {
        panic(err)
    }

    // map first
    sweaterMap := map[string]string{"Count": "17", "Material": "wool"}
    err = tmpl.Execute(os.Stdout, sweaterMap)
    if err != nil {
        fmt.Println("Error!")
        fmt.Println(err)
    }

    // struct second
    sweaters := Inventory{"wool", 17}
    err = tmpl.Execute(os.Stdout, sweaters)
    if err != nil {
        fmt.Println("Error!")
        fmt.Println(err)
    }
}