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
|
page.AppName = c.Container.Config.App.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse the templates in the page and store them in a cache, if not yet done
|
// Parse and execute the templates for the Page
|
||||||
if err := c.parsePageTemplates(page); err != nil {
|
// As mentioned in the documentation for the Page struct, the templates used for the page will be:
|
||||||
ctx.Logger().Errorf("failed to parse templates: %v", err)
|
// 1. The layout/base template specified in Page.Layout
|
||||||
return echo.NewHTTPError(http.StatusInternalServerError, "Internal server error")
|
// 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 {
|
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")
|
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")
|
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
|
// Redirect redirects to a given route name with optional route parameters
|
||||||
func (c *Controller) Redirect(ctx echo.Context, route string, routeParams ...interface{}) error {
|
func (c *Controller) Redirect(ctx echo.Context, route string, routeParams ...interface{}) error {
|
||||||
return ctx.Redirect(http.StatusFound, ctx.Echo().Reverse(route, routeParams))
|
return ctx.Redirect(http.StatusFound, ctx.Echo().Reverse(route, routeParams))
|
||||||
|
|
|
||||||
|
|
@ -127,7 +127,7 @@ func TestController_RenderPage(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check the template cache
|
// Check the template cache
|
||||||
parsed, err := c.Templates.Load("controller", p.Name)
|
parsed, err := c.TemplateRenderer.Load("controller", p.Name)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
// Check that all expected templates were parsed.
|
// Check that all expected templates were parsed.
|
||||||
|
|
@ -135,7 +135,7 @@ func TestController_RenderPage(t *testing.T) {
|
||||||
expectedTemplates := make(map[string]bool)
|
expectedTemplates := make(map[string]bool)
|
||||||
expectedTemplates[p.Name+config.TemplateExt] = true
|
expectedTemplates[p.Name+config.TemplateExt] = true
|
||||||
expectedTemplates[p.Layout+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)
|
require.NoError(t, err)
|
||||||
for _, f := range components {
|
for _, f := range components {
|
||||||
expectedTemplates[f.Name()] = true
|
expectedTemplates[f.Name()] = true
|
||||||
|
|
|
||||||
|
|
@ -19,15 +19,15 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type Container struct {
|
type Container struct {
|
||||||
Web *echo.Echo
|
Web *echo.Echo
|
||||||
Config *config.Config
|
Config *config.Config
|
||||||
Cache *cache.Cache
|
Cache *cache.Cache
|
||||||
cacheClient *redis.Client
|
cacheClient *redis.Client
|
||||||
Database *sql.DB
|
Database *sql.DB
|
||||||
ORM *ent.Client
|
ORM *ent.Client
|
||||||
Mail *MailClient
|
Mail *MailClient
|
||||||
Auth *AuthClient
|
Auth *AuthClient
|
||||||
Templates *TemplateRenderer
|
TemplateRenderer *TemplateRenderer
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewContainer() *Container {
|
func NewContainer() *Container {
|
||||||
|
|
@ -140,12 +140,12 @@ func (c *Container) initAuth() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Container) initTemplateRenderer() {
|
func (c *Container) initTemplateRenderer() {
|
||||||
c.Templates = NewTemplateRenderer(c.Config)
|
c.TemplateRenderer = NewTemplateRenderer(c.Config)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Container) initMail() {
|
func (c *Container) initMail() {
|
||||||
var err error
|
var err error
|
||||||
c.Mail, err = NewMailClient(c.Config, c.Templates)
|
c.Mail, err = NewMailClient(c.Config, c.TemplateRenderer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Sprintf("failed to create mail client: %v", err))
|
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.ORM)
|
||||||
assert.NotNil(t, c.Mail)
|
assert.NotNil(t, c.Mail)
|
||||||
assert.NotNil(t, c.Auth)
|
assert.NotNil(t, c.Auth)
|
||||||
|
assert.NotNil(t, c.TemplateRenderer)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,20 @@ func NewTemplateRenderer(cfg *config.Config) *TemplateRenderer {
|
||||||
return t
|
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 {
|
func (t *TemplateRenderer) Parse(module, key, name string, files []string, directories []string) error {
|
||||||
cacheKey := t.getCacheKey(module, key)
|
cacheKey := t.getCacheKey(module, key)
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue