ace.go 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. package view
  2. import (
  3. "strings"
  4. "sync"
  5. "github.com/yosssi/ace"
  6. )
  7. // AceEngine represents the Ace view engine.
  8. // See the `Ace` package-level function for more.
  9. type AceEngine struct {
  10. *HTMLEngine
  11. indent string
  12. }
  13. // SetIndent string used for indentation.
  14. // Do NOT use tabs, only spaces characters.
  15. // Defaults to minified response, no indentation.
  16. func (s *AceEngine) SetIndent(indent string) *AceEngine {
  17. s.indent = indent
  18. return s
  19. }
  20. // Ace returns a new Ace view engine.
  21. // It shares the same exactly logic with the
  22. // html view engine, it uses the same exactly configuration.
  23. // The given "extension" MUST begin with a dot.
  24. // Ace minifies the response automatically unless
  25. // SetIndent() method is set.
  26. //
  27. // Read more about the Ace Go Parser: https://github.com/yosssi/ace
  28. //
  29. // Usage:
  30. // Ace("./views", ".ace") or
  31. // Ace(iris.Dir("./views"), ".ace") or
  32. // Ace(embed.FS, ".ace") or Ace(AssetFile(), ".ace") for embedded data.
  33. func Ace(fs interface{}, extension string) *AceEngine {
  34. s := &AceEngine{HTMLEngine: HTML(fs, extension), indent: ""}
  35. s.name = "Ace"
  36. funcs := make(map[string]interface{})
  37. once := new(sync.Once)
  38. s.middleware = func(name string, text []byte) (contents string, err error) {
  39. once.Do(func() { // on first template parse, all funcs are given.
  40. for k, v := range s.getBuiltinFuncs(name) {
  41. funcs[k] = v
  42. }
  43. for k, v := range s.funcs {
  44. funcs[k] = v
  45. }
  46. })
  47. // name = path.Join(path.Clean(directory), name)
  48. src := ace.NewSource(
  49. ace.NewFile(name, text),
  50. ace.NewFile("", []byte{}),
  51. []*ace.File{},
  52. )
  53. if strings.Contains(name, "layout") {
  54. for k, v := range s.layoutFuncs {
  55. funcs[k] = v
  56. }
  57. }
  58. opts := &ace.Options{
  59. Extension: extension[1:],
  60. FuncMap: funcs,
  61. DelimLeft: s.left,
  62. DelimRight: s.right,
  63. Indent: s.indent,
  64. }
  65. rslt, err := ace.ParseSource(src, opts)
  66. if err != nil {
  67. return "", err
  68. }
  69. t, err := ace.CompileResult(name, rslt, opts)
  70. if err != nil {
  71. return "", err
  72. }
  73. return t.Lookup(name).Tree.Root.String(), nil
  74. }
  75. return s
  76. }