render.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. // Copyright 2014 Manu Martinez-Almeida. All rights reserved.
  2. // Use of this source code is governed by a MIT style
  3. // license that can be found in the LICENSE file.
  4. package render
  5. import (
  6. "encoding/json"
  7. "encoding/xml"
  8. "fmt"
  9. "html/template"
  10. "net/http"
  11. )
  12. type (
  13. Render interface {
  14. Render(http.ResponseWriter, int, ...interface{}) error
  15. }
  16. jsonRender struct{}
  17. xmlRender struct{}
  18. plainTextRender struct{}
  19. htmlPlainRender struct{}
  20. redirectRender struct{}
  21. htmlDebugRender struct {
  22. files []string
  23. globs []string
  24. }
  25. HTMLRender struct {
  26. Template *template.Template
  27. }
  28. )
  29. var (
  30. JSON = jsonRender{}
  31. XML = xmlRender{}
  32. HTMLPlain = htmlPlainRender{}
  33. Plain = plainTextRender{}
  34. Redirect = redirectRender{}
  35. HTMLDebug = &htmlDebugRender{}
  36. )
  37. func writeHeader(w http.ResponseWriter, code int, contentType string) {
  38. w.Header().Set("Content-Type", contentType+"; charset=utf-8")
  39. w.WriteHeader(code)
  40. }
  41. func (_ jsonRender) Render(w http.ResponseWriter, code int, data ...interface{}) error {
  42. writeHeader(w, code, "application/json")
  43. encoder := json.NewEncoder(w)
  44. return encoder.Encode(data[0])
  45. }
  46. func (_ redirectRender) Render(w http.ResponseWriter, code int, data ...interface{}) error {
  47. w.Header().Set("Location", data[0].(string))
  48. w.WriteHeader(code)
  49. return nil
  50. }
  51. func (_ xmlRender) Render(w http.ResponseWriter, code int, data ...interface{}) error {
  52. writeHeader(w, code, "application/xml")
  53. encoder := xml.NewEncoder(w)
  54. return encoder.Encode(data[0])
  55. }
  56. func (_ plainTextRender) Render(w http.ResponseWriter, code int, data ...interface{}) (err error) {
  57. writeHeader(w, code, "text/plain")
  58. format := data[0].(string)
  59. args := data[1].([]interface{})
  60. if len(args) > 0 {
  61. _, err = w.Write([]byte(fmt.Sprintf(format, args...)))
  62. } else {
  63. _, err = w.Write([]byte(format))
  64. }
  65. return
  66. }
  67. func (_ htmlPlainRender) Render(w http.ResponseWriter, code int, data ...interface{}) error {
  68. writeHeader(w, code, "text/html")
  69. format := data[0].(string)
  70. args := data[1].([]interface{})
  71. var err error
  72. if len(args) > 0 {
  73. _, err = w.Write([]byte(fmt.Sprintf(format, args...)))
  74. } else {
  75. _, err = w.Write([]byte(format))
  76. }
  77. return err
  78. }
  79. func (r *htmlDebugRender) AddGlob(pattern string) {
  80. r.globs = append(r.globs, pattern)
  81. }
  82. func (r *htmlDebugRender) AddFiles(files ...string) {
  83. r.files = append(r.files, files...)
  84. }
  85. func (r *htmlDebugRender) Render(w http.ResponseWriter, code int, data ...interface{}) error {
  86. writeHeader(w, code, "text/html")
  87. file := data[0].(string)
  88. obj := data[1]
  89. t := template.New("")
  90. if len(r.files) > 0 {
  91. if _, err := t.ParseFiles(r.files...); err != nil {
  92. return err
  93. }
  94. }
  95. for _, glob := range r.globs {
  96. if _, err := t.ParseGlob(glob); err != nil {
  97. return err
  98. }
  99. }
  100. return t.ExecuteTemplate(w, file, obj)
  101. }
  102. func (html HTMLRender) Render(w http.ResponseWriter, code int, data ...interface{}) error {
  103. writeHeader(w, code, "text/html")
  104. file := data[0].(string)
  105. obj := data[1]
  106. return html.Template.ExecuteTemplate(w, file, obj)
  107. }