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
|
* `koushin.on_render(name, f)`: prior to rendering the template `name`, call
|
||||||
`f` with the template data
|
`f` with the template data
|
||||||
* `koushin.set_filter(name, f)`: set a template function
|
* `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
|
## License
|
||||||
|
|
||||||
|
|
34
plugin.go
34
plugin.go
|
@ -13,15 +13,23 @@ import (
|
||||||
type Plugin interface {
|
type Plugin interface {
|
||||||
Name() string
|
Name() string
|
||||||
Filters() template.FuncMap
|
Filters() template.FuncMap
|
||||||
|
SetRoutes(group *echo.Group)
|
||||||
Render(name string, data interface{}) error
|
Render(name string, data interface{}) error
|
||||||
Close() error
|
Close() error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type luaRoute struct {
|
||||||
|
method string
|
||||||
|
path string
|
||||||
|
f *lua.LFunction
|
||||||
|
}
|
||||||
|
|
||||||
type luaPlugin struct {
|
type luaPlugin struct {
|
||||||
filename string
|
filename string
|
||||||
state *lua.LState
|
state *lua.LState
|
||||||
renderCallbacks map[string]*lua.LFunction
|
renderCallbacks map[string]*lua.LFunction
|
||||||
filters template.FuncMap
|
filters template.FuncMap
|
||||||
|
routes []luaRoute
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *luaPlugin) Name() string {
|
func (p *luaPlugin) Name() string {
|
||||||
|
@ -60,6 +68,14 @@ func (p *luaPlugin) setFilter(l *lua.LState) int {
|
||||||
return 0
|
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 {
|
func (p *luaPlugin) Render(name string, data interface{}) error {
|
||||||
f, ok := p.renderCallbacks[name]
|
f, ok := p.renderCallbacks[name]
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -82,6 +98,23 @@ func (p *luaPlugin) Filters() template.FuncMap {
|
||||||
return p.filters
|
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 {
|
func (p *luaPlugin) Close() error {
|
||||||
p.state.Close()
|
p.state.Close()
|
||||||
return nil
|
return nil
|
||||||
|
@ -100,6 +133,7 @@ func loadLuaPlugin(filename string) (*luaPlugin, error) {
|
||||||
l.SetGlobal("koushin", mt)
|
l.SetGlobal("koushin", mt)
|
||||||
l.SetField(mt, "on_render", l.NewFunction(p.onRender))
|
l.SetField(mt, "on_render", l.NewFunction(p.onRender))
|
||||||
l.SetField(mt, "set_filter", l.NewFunction(p.setFilter))
|
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 {
|
if err := l.DoFile(filename); err != nil {
|
||||||
l.Close()
|
l.Close()
|
||||||
|
|
|
@ -204,5 +204,9 @@ func New(e *echo.Echo, options *Options) error {
|
||||||
e.Static("/assets", "public/assets")
|
e.Static("/assets", "public/assets")
|
||||||
e.Static("/themes", "public/themes")
|
e.Static("/themes", "public/themes")
|
||||||
|
|
||||||
|
for _, p := range s.plugins {
|
||||||
|
p.SetRoutes(e.Group(""))
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue