diff options
author | Simon Ser <contact@emersion.fr> | 2019-12-10 16:00:50 +0100 |
---|---|---|
committer | Simon Ser <contact@emersion.fr> | 2019-12-10 16:00:53 +0100 |
commit | a9a607b9b26c5d63e773deb639f2abf9d4847f8c (patch) | |
tree | 6ae294516596ce700ade04dbb6b7f6783a1190db | |
parent | c5afd1a61b06b3d5bd7287d1596b05d4c18ac138 (diff) | |
download | alps-a9a607b9b26c5d63e773deb639f2abf9d4847f8c.tar.gz alps-a9a607b9b26c5d63e773deb639f2abf9d4847f8c.zip |
Allow plugins to add new routes
References: https://todo.sr.ht/~sircmpwn/koushin/6
-rw-r--r-- | README.md | 2 | ||||
-rw-r--r-- | plugin.go | 34 | ||||
-rw-r--r-- | server.go | 4 |
3 files changed, 40 insertions, 0 deletions
@@ -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 @@ -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() @@ -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 } |