render.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  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. // JSON binding
  17. jsonRender struct{}
  18. // XML binding
  19. xmlRender struct{}
  20. // Plain text
  21. plainRender struct{}
  22. // HTML Plain text
  23. htmlPlainRender struct{}
  24. // Redirects
  25. redirectRender struct{}
  26. // Redirects
  27. htmlDebugRender struct {
  28. files []string
  29. globs []string
  30. }
  31. // form binding
  32. HTMLRender struct {
  33. Template *template.Template
  34. }
  35. )
  36. var (
  37. JSON = jsonRender{}
  38. XML = xmlRender{}
  39. Plain = plainRender{}
  40. HTMLPlain = htmlPlainRender{}
  41. Redirect = redirectRender{}
  42. HTMLDebug = &htmlDebugRender{}
  43. )
  44. func writeHeader(w http.ResponseWriter, code int, contentType string) {
  45. w.Header().Set("Content-Type", contentType+"; charset=utf-8")
  46. w.WriteHeader(code)
  47. }
  48. func (_ jsonRender) Render(w http.ResponseWriter, code int, data ...interface{}) error {
  49. writeHeader(w, code, "application/json")
  50. encoder := json.NewEncoder(w)
  51. return encoder.Encode(data[0])
  52. }
  53. func (_ redirectRender) Render(w http.ResponseWriter, code int, data ...interface{}) error {
  54. w.Header().Set("Location", data[0].(string))
  55. w.WriteHeader(code)
  56. return nil
  57. }
  58. func (_ xmlRender) Render(w http.ResponseWriter, code int, data ...interface{}) error {
  59. writeHeader(w, code, "application/xml")
  60. encoder := xml.NewEncoder(w)
  61. return encoder.Encode(data[0])
  62. }
  63. func (_ plainRender) Render(w http.ResponseWriter, code int, data ...interface{}) error {
  64. writeHeader(w, code, "text/plain")
  65. format := data[0].(string)
  66. args := data[1].([]interface{})
  67. var err error
  68. if len(args) > 0 {
  69. _, err = w.Write([]byte(fmt.Sprintf(format, args...)))
  70. } else {
  71. _, err = w.Write([]byte(format))
  72. }
  73. return err
  74. }
  75. func (_ htmlPlainRender) Render(w http.ResponseWriter, code int, data ...interface{}) error {
  76. writeHeader(w, code, "text/html")
  77. format := data[0].(string)
  78. args := data[1].([]interface{})
  79. var err error
  80. if len(args) > 0 {
  81. _, err = w.Write([]byte(fmt.Sprintf(format, args...)))
  82. } else {
  83. _, err = w.Write([]byte(format))
  84. }
  85. return err
  86. }
  87. func (r *htmlDebugRender) AddGlob(pattern string) {
  88. r.globs = append(r.globs, pattern)
  89. }
  90. func (r *htmlDebugRender) AddFiles(files ...string) {
  91. r.files = append(r.files, files...)
  92. }
  93. func (r *htmlDebugRender) Render(w http.ResponseWriter, code int, data ...interface{}) error {
  94. writeHeader(w, code, "text/html")
  95. file := data[0].(string)
  96. obj := data[1]
  97. t := template.New("")
  98. if len(r.files) > 0 {
  99. if _, err := t.ParseFiles(r.files...); err != nil {
  100. return err
  101. }
  102. }
  103. for _, glob := range r.globs {
  104. if _, err := t.ParseGlob(glob); err != nil {
  105. return err
  106. }
  107. }
  108. return t.ExecuteTemplate(w, file, obj)
  109. }
  110. func (html HTMLRender) Render(w http.ResponseWriter, code int, data ...interface{}) error {
  111. writeHeader(w, code, "text/html")
  112. file := data[0].(string)
  113. obj := data[1]
  114. return html.Template.ExecuteTemplate(w, file, obj)
  115. }