Provide combined parse and execute method for the template renderer.
This commit is contained in:
parent
92bb2d9d7b
commit
0e2625bf51
5 changed files with 46 additions and 46 deletions
|
|
@ -47,16 +47,26 @@ func (c *Controller) RenderPage(ctx echo.Context, page Page) error {
|
|||
page.AppName = c.Container.Config.App.Name
|
||||
}
|
||||
|
||||
// Parse the templates in the page and store them in a cache, if not yet done
|
||||
if err := c.parsePageTemplates(page); err != nil {
|
||||
ctx.Logger().Errorf("failed to parse templates: %v", err)
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Internal server error")
|
||||
}
|
||||
// Parse and execute the templates for the Page
|
||||
// As mentioned in the documentation for the Page struct, the templates used for the page will be:
|
||||
// 1. The layout/base template specified in Page.Layout
|
||||
// 2. The content template specified in Page.Name
|
||||
// 3. All templates within the components directory
|
||||
// Also included is the function map provided by the funcmap package
|
||||
buf, err := c.Container.TemplateRenderer.ParseAndExecute(
|
||||
"controller",
|
||||
page.Name,
|
||||
page.Layout,
|
||||
[]string{
|
||||
fmt.Sprintf("layouts/%s", page.Layout),
|
||||
fmt.Sprintf("pages/%s", page.Name),
|
||||
},
|
||||
[]string{"components"},
|
||||
page,
|
||||
)
|
||||
|
||||
// Execute the parsed templates to render the page
|
||||
buf, err := c.executeTemplates(page)
|
||||
if err != nil {
|
||||
ctx.Logger().Errorf("failed to execute templates: %v", err)
|
||||
ctx.Logger().Errorf("failed to parse and execute templates: %v", err)
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Internal server error")
|
||||
}
|
||||
|
||||
|
|
@ -105,31 +115,6 @@ func (c *Controller) cachePage(ctx echo.Context, page Page, html *bytes.Buffer)
|
|||
ctx.Logger().Infof("cached page")
|
||||
}
|
||||
|
||||
// parsePageTemplates parses the templates for the given Page and caches them to avoid duplicate operations
|
||||
// If the configuration indicates that the environment is local, the cache is bypassed for template changes
|
||||
// can be seen without having to restart the application.
|
||||
// As mentioned in the documentation for the Page struct, the templates used for the page will be:
|
||||
// 1. The layout/based template specified in Page.Layout
|
||||
// 2. The content template specified in Page.Name
|
||||
// 3. All templates within the components directory
|
||||
// Also included is the function map provided by the funcmap package
|
||||
func (c *Controller) parsePageTemplates(page Page) error {
|
||||
return c.Container.Templates.Parse(
|
||||
"controller",
|
||||
page.Name,
|
||||
page.Layout,
|
||||
[]string{
|
||||
fmt.Sprintf("layouts/%s", page.Layout),
|
||||
fmt.Sprintf("pages/%s", page.Name),
|
||||
},
|
||||
[]string{"components"})
|
||||
}
|
||||
|
||||
// executeTemplates executes the cached templates belonging to Page and renders the Page within them
|
||||
func (c *Controller) executeTemplates(page Page) (*bytes.Buffer, error) {
|
||||
return c.Container.Templates.Execute("controller", page.Name, page.Layout, page)
|
||||
}
|
||||
|
||||
// Redirect redirects to a given route name with optional route parameters
|
||||
func (c *Controller) Redirect(ctx echo.Context, route string, routeParams ...interface{}) error {
|
||||
return ctx.Redirect(http.StatusFound, ctx.Echo().Reverse(route, routeParams))
|
||||
|
|
|
|||
|
|
@ -127,7 +127,7 @@ func TestController_RenderPage(t *testing.T) {
|
|||
}
|
||||
|
||||
// Check the template cache
|
||||
parsed, err := c.Templates.Load("controller", p.Name)
|
||||
parsed, err := c.TemplateRenderer.Load("controller", p.Name)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Check that all expected templates were parsed.
|
||||
|
|
@ -135,7 +135,7 @@ func TestController_RenderPage(t *testing.T) {
|
|||
expectedTemplates := make(map[string]bool)
|
||||
expectedTemplates[p.Name+config.TemplateExt] = true
|
||||
expectedTemplates[p.Layout+config.TemplateExt] = true
|
||||
components, err := ioutil.ReadDir(c.Templates.GetTemplatesPath() + "/components")
|
||||
components, err := ioutil.ReadDir(c.TemplateRenderer.GetTemplatesPath() + "/components")
|
||||
require.NoError(t, err)
|
||||
for _, f := range components {
|
||||
expectedTemplates[f.Name()] = true
|
||||
|
|
|
|||
|
|
@ -19,15 +19,15 @@ import (
|
|||
)
|
||||
|
||||
type Container struct {
|
||||
Web *echo.Echo
|
||||
Config *config.Config
|
||||
Cache *cache.Cache
|
||||
cacheClient *redis.Client
|
||||
Database *sql.DB
|
||||
ORM *ent.Client
|
||||
Mail *MailClient
|
||||
Auth *AuthClient
|
||||
Templates *TemplateRenderer
|
||||
Web *echo.Echo
|
||||
Config *config.Config
|
||||
Cache *cache.Cache
|
||||
cacheClient *redis.Client
|
||||
Database *sql.DB
|
||||
ORM *ent.Client
|
||||
Mail *MailClient
|
||||
Auth *AuthClient
|
||||
TemplateRenderer *TemplateRenderer
|
||||
}
|
||||
|
||||
func NewContainer() *Container {
|
||||
|
|
@ -140,12 +140,12 @@ func (c *Container) initAuth() {
|
|||
}
|
||||
|
||||
func (c *Container) initTemplateRenderer() {
|
||||
c.Templates = NewTemplateRenderer(c.Config)
|
||||
c.TemplateRenderer = NewTemplateRenderer(c.Config)
|
||||
}
|
||||
|
||||
func (c *Container) initMail() {
|
||||
var err error
|
||||
c.Mail, err = NewMailClient(c.Config, c.Templates)
|
||||
c.Mail, err = NewMailClient(c.Config, c.TemplateRenderer)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("failed to create mail client: %v", err))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,4 +14,5 @@ func TestNewContainer(t *testing.T) {
|
|||
assert.NotNil(t, c.ORM)
|
||||
assert.NotNil(t, c.Mail)
|
||||
assert.NotNil(t, c.Auth)
|
||||
assert.NotNil(t, c.TemplateRenderer)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,6 +44,20 @@ func NewTemplateRenderer(cfg *config.Config) *TemplateRenderer {
|
|||
return t
|
||||
}
|
||||
|
||||
func (t *TemplateRenderer) ParseAndExecute(module, key, name string, files []string, directories []string, data interface{}) (*bytes.Buffer, error) {
|
||||
var buf *bytes.Buffer
|
||||
var err error
|
||||
|
||||
if err = t.Parse(module, key, name, files, directories); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if buf, err = t.Execute(module, key, name, data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return buf, nil
|
||||
}
|
||||
|
||||
func (t *TemplateRenderer) Parse(module, key, name string, files []string, directories []string) error {
|
||||
cacheKey := t.getCacheKey(module, key)
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue