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

static.go 4.1 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  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. var tplFileSys = NewTemplateFileSystem()
  92. // HTMLRenderer implements the macaron handler for serving HTML templates.
  93. func HTMLRenderer() macaron.Handler {
  94. return macaron.Renderer(macaron.RenderOptions{
  95. Funcs: NewFuncMap(),
  96. TemplateFileSystem: tplFileSys,
  97. })
  98. }
  99. // JSONRenderer implements the macaron handler for serving JSON templates.
  100. func JSONRenderer() macaron.Handler {
  101. return macaron.Renderer(macaron.RenderOptions{
  102. Funcs: NewFuncMap(),
  103. TemplateFileSystem: tplFileSys,
  104. HTMLContentType: "application/json",
  105. })
  106. }
  107. // Mailer provides the templates required for sending notification mails.
  108. func Mailer() *template.Template {
  109. for _, funcs := range NewFuncMap() {
  110. templates.Funcs(funcs)
  111. }
  112. for _, assetPath := range AssetNames() {
  113. if !strings.HasPrefix(assetPath, "mail/") {
  114. continue
  115. }
  116. if !strings.HasSuffix(assetPath, ".tmpl") {
  117. continue
  118. }
  119. content, err := Asset(assetPath)
  120. if err != nil {
  121. log.Warn("Failed to read embedded %s template. %v", assetPath, err)
  122. continue
  123. }
  124. templates.New(
  125. strings.TrimPrefix(
  126. strings.TrimSuffix(
  127. assetPath,
  128. ".tmpl",
  129. ),
  130. "mail/",
  131. ),
  132. ).Parse(string(content))
  133. }
  134. customDir := path.Join(setting.CustomPath, "templates", "mail")
  135. if com.IsDir(customDir) {
  136. files, err := com.StatDir(customDir)
  137. if err != nil {
  138. log.Warn("Failed to read %s templates dir. %v", customDir, err)
  139. } else {
  140. for _, filePath := range files {
  141. if !strings.HasSuffix(filePath, ".tmpl") {
  142. continue
  143. }
  144. content, err := ioutil.ReadFile(path.Join(customDir, filePath))
  145. if err != nil {
  146. log.Warn("Failed to read custom %s template. %v", filePath, err)
  147. continue
  148. }
  149. templates.New(
  150. strings.TrimSuffix(
  151. filePath,
  152. ".tmpl",
  153. ),
  154. ).Parse(string(content))
  155. }
  156. }
  157. }
  158. return templates
  159. }