Allow plugins to add new routes
References: https://todo.sr.ht/~sircmpwn/koushin/6
This commit is contained in:
parent
c5afd1a61b
commit
a9a607b9b2
3 changed files with 40 additions and 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
|
||||
|
||||
|
|
34
plugin.go
34
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()
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue