Golang模板 – 如何渲染模板?

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

Golang template - how to render templates?

问题

一个包含三个子模板的布局模板。

layout.html

  1. <html>
  2. <body>
  3. {{template "tags"}}
  4. {{template "content"}}
  5. {{template "comment"}}
  6. </body>
  7. </html>

tags.html

  1. {{define "tags"}}
  2. <div>
  3. {{.Name}}
  4. <div>
  5. {{end}}

content.html

  1. {{define "content"}}
  2. <div>
  3. <p>{{.Title}}</p>
  4. <p>{{.Content}}</p>
  5. </div>
  6. {{end}}

comment.html

  1. {{define "tags"}}
  2. <div>
  3. {{.Note}}
  4. </div>
  5. {{end}}

##gocode

  1. type Tags struct {
  2. Id int
  3. Name string
  4. }
  5. type Content struct {
  6. Id int
  7. Title string
  8. Content string
  9. }
  10. type Comment struct {
  11. Id int
  12. Note string
  13. }
  14. func main() {
  15. tags := &Tags{"Id":1, "Name":"golang"}
  16. Content := &Content{"Id":9, "Title":"Hello", "Content":"World!"}
  17. Comment := &Comment{"Id":2, "Note":"Good Day!"}
  18. }

我不确定如何渲染每个子模板并将结果组合到布局输出中。

谢谢。

英文:

One layout template with three children templates.

layout.html

  1. <html>
  2. <body>
  3. {{template "tags"}}
  4. {{template "content"}}
  5. {{template "comment"}}
  6. </body>
  7. </html>

tags.html

  1. {{define "tags"}}
  2. <div>
  3. {{.Name}}
  4. <div>
  5. {{end}}

content.html

  1. {{define "content"}}
  2. <div>
  3. <p>{{.Title}}</p>
  4. <p>{{.Content}}</p>
  5. </div>
  6. {{end}}

comment.html

  1. {{define "tags"}}
  2. <div>
  3. {{.Note}}
  4. </div>
  5. {{end}}

##gocode

  1. type Tags struct {
  2. Id int
  3. Name string
  4. }
  5. type Content struct {
  6. Id int
  7. Title string
  8. Content string
  9. }
  10. type Comment struct {
  11. Id int
  12. Note string
  13. }
  14. func main() {
  15. tags := &Tags{"Id":1, "Name":"golang"}
  16. Content := &Content{"Id":9, "Title":"Hello", "Content":"World!"}
  17. Comment := &Comment{"Id":2, "Note":"Good Day!"}
  18. }

I am confused that how to render each children template and combine the result to layout output.

Thanks.

答案1

得分: 26

如往常一样,文档是一个很好的起点。

我在游乐场上写了一个可工作的示例。

简要解释一下:

  1. 在结构体字面量中不需要使用字符串:&Tags{Id: 1},而不是&Tags{"Id":1}
  2. 你只能传递一个对象给模板执行,它会根据你在{{template <name> <arg>}}指令中的要求将对象分派给每个子模板。我使用了一个临时的Page结构体,但如果你喜欢的话,也可以使用map[string]interface{}
  3. 你需要解析每个模板(我在游乐场上使用了字符串,但如果你已经有了HTML文件,可以使用ParseFiles
  4. 我使用了os.Stdout来执行它,但你显然应该将其替换为相应的ResponseWriter

以下是完整的代码:

  1. package main
  2. import "fmt"
  3. import "html/template"
  4. import "os"
  5. var page = `<html>
  6. <body>
  7. {{template "tags" .Tags}}
  8. {{template "content" .Content}}
  9. {{template "comment" .Comment}}
  10. </body>
  11. </html>`
  12. var tags = `{{define "tags"}}
  13. <div>
  14. {{.Name}}
  15. <div>
  16. {{end}}`
  17. var content = `{{define "content"}}
  18. <div>
  19. <p>{{.Title}}</p>
  20. <p>{{.Content}}</p>
  21. </div>
  22. {{end}}`
  23. var comment = `{{define "comment"}}
  24. <div>
  25. {{.Note}}
  26. </div>
  27. {{end}}`
  28. type Tags struct {
  29. Id int
  30. Name string
  31. }
  32. type Content struct {
  33. Id int
  34. Title string
  35. Content string
  36. }
  37. type Comment struct {
  38. Id int
  39. Note string
  40. }
  41. type Page struct {
  42. Tags *Tags
  43. Content *Content
  44. Comment *Comment
  45. }
  46. func main() {
  47. pagedata := &Page{
  48. Tags: &Tags{Id: 1, Name: "golang"},
  49. Content: &Content{Id: 9, Title: "Hello", Content: "World!"},
  50. Comment: &Comment{Id: 2, Note: "Good Day!"},
  51. }
  52. tmpl := template.New("page")
  53. var err error
  54. if tmpl, err = tmpl.Parse(page); err != nil {
  55. fmt.Println(err)
  56. }
  57. if tmpl, err = tmpl.Parse(tags); err != nil {
  58. fmt.Println(err)
  59. }
  60. if tmpl, err = tmpl.Parse(comment); err != nil {
  61. fmt.Println(err)
  62. }
  63. if tmpl, err = tmpl.Parse(content); err != nil {
  64. fmt.Println(err)
  65. }
  66. tmpl.Execute(os.Stdout, pagedata)
  67. }
英文:

As always, the doc is a good place to start.

I wrote a working example on the playground

To explain a bit:

  1. You don't need strings in struct literals: &amp;Tags{Id: 1}, not &amp;Tags{&quot;Id&quot;:1}
  2. You can only pass a single object to your template to execute, which will dispatch objects to each subtemplate as you require in the {{template &lt;name&gt; &lt;arg&gt;}} instruction. I used a ad-hoc Page struct, but a map[string]interface{} would do if you prefer.
  3. You need to parse each template (I used strings in the Playground, but ParseFiles would do if you have your html files already)
  4. I used os.Stdout to execute it, but you should obviously replace that by the corresponding ResponseWriter

And the whole code:

  1. package main
  2. import &quot;fmt&quot;
  3. import &quot;html/template&quot;
  4. import &quot;os&quot;
  5. var page = `&lt;html&gt;
  6. &lt;body&gt;
  7. {{template &quot;tags&quot; .Tags}}
  8. {{template &quot;content&quot; .Content}}
  9. {{template &quot;comment&quot; .Comment}}
  10. &lt;/body&gt;
  11. &lt;/html&gt;`
  12. var tags = `{{define &quot;tags&quot;}}
  13. &lt;div&gt;
  14. {{.Name}}
  15. &lt;div&gt;
  16. {{end}}`
  17. var content = `{{define &quot;content&quot;}}
  18. &lt;div&gt;
  19. &lt;p&gt;{{.Title}}&lt;/p&gt;
  20. &lt;p&gt;{{.Content}}&lt;/p&gt;
  21. &lt;/div&gt;
  22. {{end}}`
  23. var comment = `{{define &quot;comment&quot;}}
  24. &lt;div&gt;
  25. {{.Note}}
  26. &lt;/div&gt;
  27. {{end}}`
  28. type Tags struct {
  29. Id int
  30. Name string
  31. }
  32. type Content struct {
  33. Id int
  34. Title string
  35. Content string
  36. }
  37. type Comment struct {
  38. Id int
  39. Note string
  40. }
  41. type Page struct {
  42. Tags *Tags
  43. Content *Content
  44. Comment *Comment
  45. }
  46. func main() {
  47. pagedata := &amp;Page{Tags:&amp;Tags{Id:1, Name:&quot;golang&quot;},
  48. Content: &amp;Content{Id:9, Title:&quot;Hello&quot;, Content:&quot;World!&quot;},
  49. Comment: &amp;Comment{Id:2, Note:&quot;Good Day!&quot;}}
  50. tmpl := template.New(&quot;page&quot;)
  51. var err error
  52. if tmpl, err = tmpl.Parse(page); err != nil {
  53. fmt.Println(err)
  54. }
  55. if tmpl, err = tmpl.Parse(tags); err != nil {
  56. fmt.Println(err)
  57. }
  58. if tmpl, err = tmpl.Parse(comment); err != nil {
  59. fmt.Println(err)
  60. }
  61. if tmpl, err = tmpl.Parse(content); err != nil {
  62. fmt.Println(err)
  63. }
  64. tmpl.Execute(os.Stdout, pagedata)
  65. }

huangapple
  • 本文由 发表于 2013年10月24日 00:11:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/19546896.html
匿名

发表评论

匿名网友

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

确定