A webmail client. Forked from https://git.sr.ht/~migadu/alps
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.
 
 
 
 

142 lines
3.2 KiB

  1. package alps
  2. import (
  3. "html/template"
  4. "net/http"
  5. "path/filepath"
  6. "github.com/labstack/echo/v4"
  7. )
  8. type goPlugin struct {
  9. p *GoPlugin
  10. }
  11. func (p *goPlugin) Name() string {
  12. return p.p.Name
  13. }
  14. func (p *goPlugin) LoadTemplate(t *template.Template) error {
  15. t.Funcs(p.p.templateFuncs)
  16. paths, err := filepath.Glob(PluginDir + "/" + p.p.Name + "/public/*.html")
  17. if err != nil {
  18. return err
  19. }
  20. if len(paths) > 0 {
  21. if _, err := t.ParseFiles(paths...); err != nil {
  22. return err
  23. }
  24. }
  25. return nil
  26. }
  27. func (p *goPlugin) SetRoutes(group *echo.Group) {
  28. for _, r := range p.p.routes {
  29. h := r.Handler
  30. group.Add(r.Method, r.Path, func(ectx echo.Context) error {
  31. return h(ectx.(*Context))
  32. })
  33. }
  34. group.Static("/plugins/"+p.p.Name+"/assets", PluginDir+"/"+p.p.Name+"/public/assets")
  35. }
  36. func (p *goPlugin) Inject(ctx *Context, name string, data RenderData) error {
  37. if f, ok := p.p.injectFuncs["*"]; ok {
  38. if err := f(ctx, data); err != nil {
  39. return err
  40. }
  41. }
  42. if f, ok := p.p.injectFuncs[name]; ok {
  43. return f(ctx, data)
  44. }
  45. return nil
  46. }
  47. func (p *goPlugin) Close() error {
  48. return nil
  49. }
  50. type goPluginRoute struct {
  51. Method string
  52. Path string
  53. Handler HandlerFunc
  54. }
  55. // GoPlugin is a helper to create Go plugins.
  56. //
  57. // Use this struct to define your plugin, then call RegisterPluginLoader:
  58. //
  59. // p := GoPlugin{Name: "my-plugin"}
  60. // // Define routes, template functions, etc
  61. // alps.RegisterPluginLoader(p.Loader())
  62. type GoPlugin struct {
  63. Name string
  64. routes []goPluginRoute
  65. templateFuncs template.FuncMap
  66. injectFuncs map[string]InjectFunc
  67. }
  68. // HandlerFunc is a function serving HTTP requests.
  69. type HandlerFunc func(*Context) error
  70. // AddRoute registers a new HTTP route.
  71. func (p *GoPlugin) AddRoute(method, path string, handler HandlerFunc) {
  72. p.routes = append(p.routes, goPluginRoute{method, path, handler})
  73. }
  74. func (p *GoPlugin) DELETE(path string, handler HandlerFunc) {
  75. p.AddRoute(http.MethodDelete, path, handler)
  76. }
  77. func (p *GoPlugin) GET(path string, handler HandlerFunc) {
  78. p.AddRoute(http.MethodGet, path, handler)
  79. }
  80. func (p *GoPlugin) POST(path string, handler HandlerFunc) {
  81. p.AddRoute(http.MethodPost, path, handler)
  82. }
  83. func (p *GoPlugin) PUT(path string, handler HandlerFunc) {
  84. p.AddRoute(http.MethodPut, path, handler)
  85. }
  86. // TemplateFuncs registers new template functions.
  87. func (p *GoPlugin) TemplateFuncs(funcs template.FuncMap) {
  88. if p.templateFuncs == nil {
  89. p.templateFuncs = make(template.FuncMap, len(funcs))
  90. }
  91. for k, f := range funcs {
  92. p.templateFuncs[k] = f
  93. }
  94. }
  95. // InjectFunc is a function that injects data prior to rendering a template.
  96. type InjectFunc func(ctx *Context, data RenderData) error
  97. // Inject registers a function to execute prior to rendering a template. The
  98. // special name "*" matches any template.
  99. func (p *GoPlugin) Inject(name string, f InjectFunc) {
  100. if p.injectFuncs == nil {
  101. p.injectFuncs = make(map[string]InjectFunc)
  102. }
  103. p.injectFuncs[name] = f
  104. }
  105. // Plugin returns an object implementing Plugin.
  106. func (p *GoPlugin) Plugin() Plugin {
  107. return &goPlugin{p}
  108. }
  109. // Loader returns a loader function for this plugin.
  110. func (p *GoPlugin) Loader() PluginLoaderFunc {
  111. return func(*Server) ([]Plugin, error) {
  112. return []Plugin{p.Plugin()}, nil
  113. }
  114. }