You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

196 lines
4.0 KiB

  1. // +build bindata
  2. // Copyright 2016 The Gitea Authors. All rights reserved.
  3. // Use of this source code is governed by a MIT-style
  4. // license that can be found in the LICENSE file.
  5. package templates
  6. import (
  7. "bytes"
  8. "fmt"
  9. "html/template"
  10. "io"
  11. "io/ioutil"
  12. "path"
  13. "strings"
  14. "code.gitea.io/gitea/modules/log"
  15. "code.gitea.io/gitea/modules/setting"
  16. "github.com/Unknwon/com"
  17. "gopkg.in/macaron.v1"
  18. )
  19. var (
  20. templates = template.New("")
  21. )
  22. type templateFileSystem struct {
  23. files []macaron.TemplateFile
  24. }
  25. func (templates templateFileSystem) ListFiles() []macaron.TemplateFile {
  26. return templates.files
  27. }
  28. func (templates templateFileSystem) Get(name string) (io.Reader, error) {
  29. for i := range templates.files {
  30. if templates.files[i].Name()+templates.files[i].Ext() == name {
  31. return bytes.NewReader(templates.files[i].Data()), nil
  32. }
  33. }
  34. return nil, fmt.Errorf("file '%s' not found", name)
  35. }
  36. func NewTemplateFileSystem() templateFileSystem {
  37. fs := templateFileSystem{}
  38. fs.files = make([]macaron.TemplateFile, 0, 10)
  39. for _, assetPath := range AssetNames() {
  40. if strings.HasPrefix(assetPath, "mail/") {
  41. continue
  42. }
  43. if !strings.HasSuffix(assetPath, ".tmpl") {
  44. continue
  45. }
  46. content, err := Asset(assetPath)
  47. if err != nil {
  48. log.Warn("Failed to read embedded %s template. %v", assetPath, err)
  49. continue
  50. }
  51. fs.files = append(fs.files, macaron.NewTplFile(
  52. strings.TrimSuffix(
  53. assetPath,
  54. ".tmpl",
  55. ),
  56. content,
  57. ".tmpl",
  58. ))
  59. }
  60. customDir := path.Join(setting.CustomPath, "templates")
  61. if com.IsDir(customDir) {
  62. files, err := com.StatDir(customDir)
  63. if err != nil {
  64. log.Warn("Failed to read %s templates dir. %v", customDir, err)
  65. } else {
  66. for _, filePath := range files {
  67. if strings.HasPrefix(filePath, "mail/") {
  68. continue
  69. }
  70. if !strings.HasSuffix(filePath, ".tmpl") {
  71. continue
  72. }
  73. content, err := ioutil.ReadFile(path.Join(customDir, filePath))
  74. if err != nil {
  75. log.Warn("Failed to read custom %s template. %v", filePath, err)
  76. continue
  77. }
  78. fs.files = append(fs.files, macaron.NewTplFile(
  79. strings.TrimSuffix(
  80. filePath,
  81. ".tmpl",
  82. ),
  83. content,
  84. ".tmpl",
  85. ))
  86. }
  87. }
  88. }
  89. return fs
  90. }
  91. // HTMLRenderer implements the macaron handler for serving HTML templates.
  92. func HTMLRenderer() macaron.Handler {
  93. return macaron.Renderer(macaron.RenderOptions{
  94. Funcs: NewFuncMap(),
  95. TemplateFileSystem: NewTemplateFileSystem(),
  96. })
  97. }
  98. // JSONRenderer implements the macaron handler for serving JSON templates.
  99. func JSONRenderer() macaron.Handler {
  100. return macaron.Renderer(macaron.RenderOptions{
  101. Funcs: NewFuncMap(),
  102. TemplateFileSystem: NewTemplateFileSystem(),
  103. HTMLContentType: "application/json",
  104. })
  105. }
  106. // Mailer provides the templates required for sending notification mails.
  107. func Mailer() *template.Template {
  108. for _, funcs := range NewFuncMap() {
  109. templates.Funcs(funcs)
  110. }
  111. for _, assetPath := range AssetNames() {
  112. if !strings.HasPrefix(assetPath, "mail/") {
  113. continue
  114. }
  115. if !strings.HasSuffix(assetPath, ".tmpl") {
  116. continue
  117. }
  118. content, err := Asset(assetPath)
  119. if err != nil {
  120. log.Warn("Failed to read embedded %s template. %v", assetPath, err)
  121. continue
  122. }
  123. templates.New(
  124. strings.TrimPrefix(
  125. strings.TrimSuffix(
  126. assetPath,
  127. ".tmpl",
  128. ),
  129. "mail/",
  130. ),
  131. ).Parse(string(content))
  132. }
  133. customDir := path.Join(setting.CustomPath, "templates", "mail")
  134. if com.IsDir(customDir) {
  135. files, err := com.StatDir(customDir)
  136. if err != nil {
  137. log.Warn("Failed to read %s templates dir. %v", customDir, err)
  138. } else {
  139. for _, filePath := range files {
  140. if !strings.HasSuffix(filePath, ".tmpl") {
  141. continue
  142. }
  143. content, err := ioutil.ReadFile(path.Join(customDir, filePath))
  144. if err != nil {
  145. log.Warn("Failed to read custom %s template. %v", filePath, err)
  146. continue
  147. }
  148. templates.New(
  149. strings.TrimSuffix(
  150. filePath,
  151. ".tmpl",
  152. ),
  153. ).Parse(string(content))
  154. }
  155. }
  156. }
  157. return templates
  158. }