embed.go 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. package templates
  2. import (
  3. "bytes"
  4. "embed"
  5. "io"
  6. "io/fs"
  7. "os"
  8. "path"
  9. "strings"
  10. "github.com/cockroachdb/errors"
  11. "gopkg.in/macaron.v1"
  12. "gogs.io/gogs/internal/osutil"
  13. )
  14. //go:embed *.tmpl **/*
  15. var files embed.FS
  16. // fileSystem implements the macaron.TemplateFileSystem interface.
  17. type fileSystem struct {
  18. files []macaron.TemplateFile
  19. }
  20. func (fs *fileSystem) ListFiles() []macaron.TemplateFile {
  21. return fs.files
  22. }
  23. func (fs *fileSystem) Get(name string) (io.Reader, error) {
  24. for i := range fs.files {
  25. if fs.files[i].Name()+fs.files[i].Ext() == name {
  26. return bytes.NewReader(fs.files[i].Data()), nil
  27. }
  28. }
  29. return nil, errors.Newf("file %q not found", name)
  30. }
  31. func mustNames(fsys fs.FS) []string {
  32. var names []string
  33. walkDirFunc := func(path string, d fs.DirEntry, err error) error {
  34. if !d.IsDir() {
  35. names = append(names, path)
  36. }
  37. return nil
  38. }
  39. if err := fs.WalkDir(fsys, ".", walkDirFunc); err != nil {
  40. panic("assetNames failure: " + err.Error())
  41. }
  42. return names
  43. }
  44. // NewTemplateFileSystem returns a macaron.TemplateFileSystem instance for embedded assets.
  45. // The argument "dir" can be used to serve subset of embedded assets. Template file
  46. // found under the "customDir" on disk has higher precedence over embedded assets.
  47. func NewTemplateFileSystem(dir, customDir string) macaron.TemplateFileSystem {
  48. if dir != "" && !strings.HasSuffix(dir, "/") {
  49. dir += "/"
  50. }
  51. var err error
  52. var tmplFiles []macaron.TemplateFile
  53. names := mustNames(files)
  54. for _, name := range names {
  55. if !strings.HasPrefix(name, dir) {
  56. continue
  57. }
  58. // Check if corresponding custom file exists
  59. var data []byte
  60. fpath := path.Join(customDir, name)
  61. if osutil.IsFile(fpath) {
  62. data, err = os.ReadFile(fpath)
  63. } else {
  64. data, err = files.ReadFile(name)
  65. }
  66. if err != nil {
  67. panic(err)
  68. }
  69. name = strings.TrimPrefix(name, dir)
  70. ext := path.Ext(name)
  71. name = strings.TrimSuffix(name, ext)
  72. tmplFiles = append(tmplFiles, macaron.NewTplFile(name, data, ext))
  73. }
  74. return &fileSystem{files: tmplFiles}
  75. }