全局模板数据

huangapple go评论79阅读模式
英文:

Global template data

问题

当使用ExecuteTemplate时,我看到所有的示例都使用&whateversruct{Title: "title info", Body: "body info"}来向模板发送数据以替换信息。我想知道是否有可能不必在处理程序函数外部创建一个结构体,因为我每个处理程序函数都不会有相同的Title和Body。能否发送一个替换模板信息的映射。有什么想法或者建议吗?

目前的代码大致如下:

<!-- language: lang-go -->

type Info struct {
    Title string
    Body string
}

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

似乎创建这个结构体是不必要的。而且对于每个创建的函数,结构体都不会相同。所以你需要为每个函数创建一个结构体(据我所知)。

英文:

When doing ExecuteTemplate I see all examples using &amp;whateversruct{Title: &quot;title info&quot;, Body: &quot;body info&quot;} 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
<!-- language: lang-go -->

type Info struct {
    Title string
    Body string
}

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

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).

答案1

得分: 15

为了补充Kevin的答案:一个匿名结构体将产生类似的行为:

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

    temp.ExecuteTemplate(w, temp.Name(), &data)
}
英文:

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
    } {
        &quot;About page&quot;,
        &quot;Body info&quot;,
    }

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

答案2

得分: 10

那个结构体只是一个例子。你也可以从外部传入结构体,或者像你建议的那样使用一个映射。结构体很好的地方在于结构体的类型可以说明模板期望的字段,但这不是必需的。

以下所有的方法都可以工作:

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)
}
英文:

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(), &amp;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)
}

答案3

得分: 6

应用模板到结构体和应用模板到映射之间的一个重要区别是:对于映射,你可以在模板中引用映射中不存在的内容;模板将会执行而不会报错,这些引用将会是空的。如果你对结构体进行处理并引用了结构体中不存在的内容,模板执行将会返回一个错误。

引用映射中不存在的内容是有用的。考虑一下这个示例Web应用中的menu.html和views.go中的getPage()函数:https://bitbucket.org/jzs/sketchground/src。通过使用映射来表示菜单,可以轻松地突出显示活动菜单项。

这个区别的一个简单示例:

package main

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

type Inventory struct {
	Material string
	Count    uint
}

func main() {
	// 准备模板
	tmpl, err := template.New("test").Parse("{{.Count}} items are made of {{.Material}} - {{.Foo}}\n")
	if err != nil {
		panic(err)
	}

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

	// 再使用结构体
	sweaters := Inventory{"wool", 17}
	err = tmpl.Execute(os.Stdout, sweaters)
	if err != nil {
		fmt.Println("Error!")
		fmt.Println(err)
	}
}
英文:

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 (
	&quot;fmt&quot;
	&quot;html/template&quot;
	&quot;os&quot;
)

type Inventory struct {
	Material string
	Count    uint
}

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

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

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

答案4

得分: 1

你是完全正确的Kevin!我非常喜欢这个。谢谢!

英文:

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

<!-- language: lang-go -->

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

huangapple
  • 本文由 发表于 2012年9月19日 04:23:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/12484398.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定