aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--plugin.go2
-rw-r--r--plugin_go.go4
-rw-r--r--plugin_lua.go4
-rw-r--r--plugins/base/routes.go30
-rw-r--r--template.go44
5 files changed, 57 insertions, 27 deletions
diff --git a/plugin.go b/plugin.go
index 46fd1a7..6d5b730 100644
--- a/plugin.go
+++ b/plugin.go
@@ -18,7 +18,7 @@ type Plugin interface {
SetRoutes(group *echo.Group)
// Inject is called prior to rendering a template. It can extend the
// template data by setting new items in the Extra map.
- Inject(name string, data interface{}) error
+ Inject(name string, data RenderData) error
// Close is called when the plugin is unloaded.
Close() error
}
diff --git a/plugin_go.go b/plugin_go.go
index 43e9aea..407363c 100644
--- a/plugin_go.go
+++ b/plugin_go.go
@@ -40,7 +40,7 @@ func (p *goPlugin) SetRoutes(group *echo.Group) {
group.Static("/plugins/"+p.p.Name+"/assets", pluginDir+"/"+p.p.Name+"/public/assets")
}
-func (p *goPlugin) Inject(name string, data interface{}) error {
+func (p *goPlugin) Inject(name string, data RenderData) error {
if f, ok := p.p.injectFuncs["*"]; ok {
if err := f(data); err != nil {
return err
@@ -114,7 +114,7 @@ func (p *GoPlugin) TemplateFuncs(funcs template.FuncMap) {
}
// InjectFunc is a function that injects data prior to rendering a template.
-type InjectFunc func(data interface{}) error
+type InjectFunc func(data RenderData) error
// Inject registers a function to execute prior to rendering a template. The
// special name "*" matches any template.
diff --git a/plugin_lua.go b/plugin_lua.go
index 638f17c..816c7f1 100644
--- a/plugin_lua.go
+++ b/plugin_lua.go
@@ -68,7 +68,7 @@ func (p *luaPlugin) setRoute(l *lua.LState) int {
return 0
}
-func (p *luaPlugin) inject(name string, data interface{}) error {
+func (p *luaPlugin) inject(name string, data RenderData) error {
f, ok := p.renderCallbacks[name]
if !ok {
return nil
@@ -86,7 +86,7 @@ func (p *luaPlugin) inject(name string, data interface{}) error {
return nil
}
-func (p *luaPlugin) Inject(name string, data interface{}) error {
+func (p *luaPlugin) Inject(name string, data RenderData) error {
if err := p.inject("*", data); err != nil {
return err
}
diff --git a/plugins/base/routes.go b/plugins/base/routes.go
index fe3e946..f3f196a 100644
--- a/plugins/base/routes.go
+++ b/plugins/base/routes.go
@@ -116,12 +116,12 @@ func handleGetMailbox(ectx echo.Context) error {
return ctx.Render(http.StatusOK, "mailbox.html", &MailboxRenderData{
BaseRenderData: *koushin.NewBaseRenderData(ctx),
- Mailbox: mbox,
- Mailboxes: mailboxes,
- Messages: msgs,
- PrevPage: prevPage,
- NextPage: nextPage,
- Query: query,
+ Mailbox: mbox,
+ Mailboxes: mailboxes,
+ Messages: msgs,
+ PrevPage: prevPage,
+ NextPage: nextPage,
+ Query: query,
})
}
@@ -239,14 +239,14 @@ func handleGetPart(ctx *koushin.Context, raw bool) error {
}
return ctx.Render(http.StatusOK, "message.html", &MessageRenderData{
- BaseRenderData: *koushin.NewBaseRenderData(ctx),
- Mailboxes: mailboxes,
- Mailbox: mbox,
- Message: msg,
- Body: body,
- PartPath: partPathString,
- MailboxPage: int(mbox.Messages-msg.SeqNum) / messagesPerPage,
- Flags: flags,
+ BaseRenderData: *koushin.NewBaseRenderData(ctx),
+ Mailboxes: mailboxes,
+ Mailbox: mbox,
+ Message: msg,
+ Body: body,
+ PartPath: partPathString,
+ MailboxPage: int(mbox.Messages-msg.SeqNum) / messagesPerPage,
+ Flags: flags,
})
}
@@ -354,7 +354,7 @@ func handleCompose(ectx echo.Context) error {
return ctx.Render(http.StatusOK, "compose.html", &ComposeRenderData{
BaseRenderData: *koushin.NewBaseRenderData(ctx),
- Message: &msg,
+ Message: &msg,
})
}
diff --git a/template.go b/template.go
index 379b6d5..6286e08 100644
--- a/template.go
+++ b/template.go
@@ -20,18 +20,48 @@ type GlobalRenderData struct {
Username string
// TODO: list of mailboxes
- // Additional plugin-specific data
+ // additional plugin-specific data
Extra map[string]interface{}
}
// BaseRenderData is the base type for templates. It should be extended with
-// new template-specific fields.
+// additional template-specific fields:
+//
+// type MyRenderData struct {
+// BaseRenderData
+// // add additional fields here
+// }
type BaseRenderData struct {
- Global GlobalRenderData
- // Additional plugin-specific data
+ GlobalData GlobalRenderData
+ // additional plugin-specific data
Extra map[string]interface{}
}
+// Global implements RenderData.
+func (brd *BaseRenderData) Global() *GlobalRenderData {
+ return &brd.GlobalData
+}
+
+// RenderData is implemented by template data structs. It can be used to inject
+// additional data to all templates.
+type RenderData interface {
+ // GlobalData returns a pointer to the global render data.
+ Global() *GlobalRenderData
+}
+
+// NewBaseRenderData initializes a new BaseRenderData.
+//
+// It can be used by routes to pre-fill the base data:
+//
+// type MyRenderData struct {
+// BaseRenderData
+// // add additional fields here
+// }
+//
+// data := &MyRenderData{
+// BaseRenderData: *koushin.NewBaseRenderData(ctx),
+// // other fields...
+// }
func NewBaseRenderData(ctx *Context) *BaseRenderData {
global := GlobalRenderData{Extra: make(map[string]interface{})}
@@ -41,8 +71,8 @@ func NewBaseRenderData(ctx *Context) *BaseRenderData {
}
return &BaseRenderData{
- Global: global,
- Extra: make(map[string]interface{}),
+ GlobalData: global,
+ Extra: make(map[string]interface{}),
}
}
@@ -57,7 +87,7 @@ func (r *renderer) Render(w io.Writer, name string, data interface{}, ectx echo.
ctx := ectx.Get("context").(*Context)
for _, plugin := range ctx.Server.Plugins {
- if err := plugin.Inject(name, data); err != nil {
+ if err := plugin.Inject(name, data.(RenderData)); err != nil {
return fmt.Errorf("failed to run plugin '%v': %v", plugin.Name(), err)
}
}