diff --git a/pkgs/plugintypes/goblog.go b/pkgs/plugintypes/goblog.go index 2b1a5f1..ef97fec 100644 --- a/pkgs/plugintypes/goblog.go +++ b/pkgs/plugintypes/goblog.go @@ -25,8 +25,16 @@ type Database interface { // Post type Post interface { + // Get the post path + GetPath() string // Get a string array map with all the post's parameters GetParameters() map[string][]string + // Get the post section name + GetSection() string + // Get the published date string + GetPublished() string + // Get the updated date string + GetUpdated() string } // RenderContext diff --git a/pkgs/yaegiwrappers/go_goblog_app-app-pkgs-plugintypes.go b/pkgs/yaegiwrappers/go_goblog_app-app-pkgs-plugintypes.go index e2b6a7f..928c5e1 100644 --- a/pkgs/yaegiwrappers/go_goblog_app-app-pkgs-plugintypes.go +++ b/pkgs/yaegiwrappers/go_goblog_app-app-pkgs-plugintypes.go @@ -131,11 +131,27 @@ func (W _go_goblog_app_app_pkgs_plugintypes_Middleware) Prio() int { type _go_goblog_app_app_pkgs_plugintypes_Post struct { IValue interface{} WGetParameters func() map[string][]string + WGetPath func() string + WGetPublished func() string + WGetSection func() string + WGetUpdated func() string } func (W _go_goblog_app_app_pkgs_plugintypes_Post) GetParameters() map[string][]string { return W.WGetParameters() } +func (W _go_goblog_app_app_pkgs_plugintypes_Post) GetPath() string { + return W.WGetPath() +} +func (W _go_goblog_app_app_pkgs_plugintypes_Post) GetPublished() string { + return W.WGetPublished() +} +func (W _go_goblog_app_app_pkgs_plugintypes_Post) GetSection() string { + return W.WGetSection() +} +func (W _go_goblog_app_app_pkgs_plugintypes_Post) GetUpdated() string { + return W.WGetUpdated() +} // _go_goblog_app_app_pkgs_plugintypes_RenderContext is an interface wrapper for RenderContext type type _go_goblog_app_app_pkgs_plugintypes_RenderContext struct { diff --git a/plugins.go b/plugins.go index 9d5a834..070d08f 100644 --- a/plugins.go +++ b/plugins.go @@ -78,6 +78,22 @@ func (a *goBlog) GetPost(path string) (plugintypes.Post, error) { return a.getPost(path) } +func (p *post) GetPath() string { + return p.Path +} + func (p *post) GetParameters() map[string][]string { return p.Parameters } + +func (p *post) GetSection() string { + return p.Section +} + +func (p *post) GetPublished() string { + return p.Published +} + +func (p *post) GetUpdated() string { + return p.Updated +} diff --git a/render.go b/render.go index 9093ea0..e9851ed 100644 --- a/render.go +++ b/render.go @@ -4,7 +4,6 @@ import ( "io" "net/http" - "go.goblog.app/app/pkgs/bufferpool" "go.goblog.app/app/pkgs/contenttype" "go.goblog.app/app/pkgs/htmlbuilder" "go.goblog.app/app/pkgs/plugintypes" @@ -41,26 +40,35 @@ func (a *goBlog) renderWithStatusCode(w http.ResponseWriter, r *http.Request, st // Write status code w.WriteHeader(statusCode) // Render - buf := bufferpool.Get() - defer bufferpool.Put(buf) - f(htmlbuilder.NewHtmlBuilder(buf), data) - // Check if UI plugins are registered - uiPlugins := a.getPlugins(pluginUiType) - if len(uiPlugins) > 0 { - pluginBuf := bufferpool.Get() - defer bufferpool.Put(pluginBuf) - for _, plug := range uiPlugins { - pluginBuf.Reset() - plug.(plugintypes.UI).Render(&pluginRenderContext{ - blog: data.BlogString, - path: r.URL.Path, - }, buf, pluginBuf) - buf.Reset() - _, _ = io.Copy(buf, pluginBuf) - } - } + renderPipeReader, renderPipeWriter := io.Pipe() + go func() { + f(htmlbuilder.NewHtmlBuilder(renderPipeWriter), data) + renderPipeWriter.Close() + }() + // Run UI plugins + pluginPipeReader, pluginPipeWriter := io.Pipe() + go func() { + a.chainUiPlugins(a.getPlugins(pluginUiType), &pluginRenderContext{ + blog: data.BlogString, + path: r.URL.Path, + }, renderPipeReader, pluginPipeWriter) + pluginPipeWriter.Close() + }() // Return minified HTML - _ = a.min.Get().Minify(contenttype.HTML, w, buf) + _ = a.min.Get().Minify(contenttype.HTML, w, pluginPipeReader) +} + +func (a *goBlog) chainUiPlugins(plugins []any, rc *pluginRenderContext, rendered io.Reader, modified io.Writer) { + if len(plugins) == 0 { + _, _ = io.Copy(modified, rendered) + return + } + reader, writer := io.Pipe() + go func() { + plugins[0].(plugintypes.UI).Render(rc, rendered, writer) + _ = writer.Close() + }() + a.chainUiPlugins(plugins[1:], rc, reader, modified) } func (a *goBlog) checkRenderData(r *http.Request, data *renderData) {