aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Ser <contact@emersion.fr>2019-12-10 16:00:50 +0100
committerSimon Ser <contact@emersion.fr>2019-12-10 16:00:53 +0100
commita9a607b9b26c5d63e773deb639f2abf9d4847f8c (patch)
tree6ae294516596ce700ade04dbb6b7f6783a1190db
parentc5afd1a61b06b3d5bd7287d1596b05d4c18ac138 (diff)
downloadalps-a9a607b9b26c5d63e773deb639f2abf9d4847f8c.tar.gz
alps-a9a607b9b26c5d63e773deb639f2abf9d4847f8c.zip
Allow plugins to add new routes
References: https://todo.sr.ht/~sircmpwn/koushin/6
-rw-r--r--README.md2
-rw-r--r--plugin.go34
-rw-r--r--server.go4
3 files changed, 40 insertions, 0 deletions
diff --git a/README.md b/README.md
index 7aa62f4..edb4aa5 100644
--- a/README.md
+++ b/README.md
@@ -23,6 +23,8 @@ API:
* `koushin.on_render(name, f)`: prior to rendering the template `name`, call
`f` with the template data
* `koushin.set_filter(name, f)`: set a template function
+* `koushin.set_route(method, path, f)`: register a new HTTP route, `f` will be
+ called with the HTTP context
## License
diff --git a/plugin.go b/plugin.go
index 9464d60..a25f34b 100644
--- a/plugin.go
+++ b/plugin.go
@@ -13,15 +13,23 @@ import (
type Plugin interface {
Name() string
Filters() template.FuncMap
+ SetRoutes(group *echo.Group)
Render(name string, data interface{}) error
Close() error
}
+type luaRoute struct {
+ method string
+ path string
+ f *lua.LFunction
+}
+
type luaPlugin struct {
filename string
state *lua.LState
renderCallbacks map[string]*lua.LFunction
filters template.FuncMap
+ routes []luaRoute
}
func (p *luaPlugin) Name() string {
@@ -60,6 +68,14 @@ func (p *luaPlugin) setFilter(l *lua.LState) int {
return 0
}
+func (p *luaPlugin) setRoute(l *lua.LState) int {
+ method := l.CheckString(1)
+ path := l.CheckString(2)
+ f := l.CheckFunction(3)
+ p.routes = append(p.routes, luaRoute{method, path, f})
+ return 0
+}
+
func (p *luaPlugin) Render(name string, data interface{}) error {
f, ok := p.renderCallbacks[name]
if !ok {
@@ -82,6 +98,23 @@ func (p *luaPlugin) Filters() template.FuncMap {
return p.filters
}
+func (p *luaPlugin) SetRoutes(group *echo.Group) {
+ for _, r := range p.routes {
+ group.Match([]string{r.method}, r.path, func(ctx echo.Context) error {
+ err := p.state.CallByParam(lua.P{
+ Fn: r.f,
+ NRet: 0,
+ Protect: true,
+ }, luar.New(p.state, ctx))
+ if err != nil {
+ return fmt.Errorf("Lua plugin error: %v", err)
+ }
+
+ return nil
+ })
+ }
+}
+
func (p *luaPlugin) Close() error {
p.state.Close()
return nil
@@ -100,6 +133,7 @@ func loadLuaPlugin(filename string) (*luaPlugin, error) {
l.SetGlobal("koushin", mt)
l.SetField(mt, "on_render", l.NewFunction(p.onRender))
l.SetField(mt, "set_filter", l.NewFunction(p.setFilter))
+ l.SetField(mt, "set_route", l.NewFunction(p.setRoute))
if err := l.DoFile(filename); err != nil {
l.Close()
diff --git a/server.go b/server.go
index 0ab7f24..678a5e4 100644
--- a/server.go
+++ b/server.go
@@ -204,5 +204,9 @@ func New(e *echo.Echo, options *Options) error {
e.Static("/assets", "public/assets")
e.Static("/themes", "public/themes")
+ for _, p := range s.plugins {
+ p.SetRoutes(e.Group(""))
+ }
+
return nil
}