diff --git a/.github/testdata/main.tmpl b/.github/testdata/main.tmpl
new file mode 100644
index 00000000..456d6bb5
--- /dev/null
+++ b/.github/testdata/main.tmpl
@@ -0,0 +1 @@
+
I'm main
\ No newline at end of file
diff --git a/app.go b/app.go
index eb6f7617..a8a123d5 100644
--- a/app.go
+++ b/app.go
@@ -174,6 +174,11 @@ type Config struct {
// Default: nil
Views Views `json:"-"`
+ // Views Layout is the global layout for all template render until override on Render function.
+ //
+ // Default: ""
+ ViewsLayout string `json:"views_layout"`
+
// The amount of time allowed to read the full request including body.
// It is reset after the request handler has returned.
// The connection's read deadline is reset when the connection opens.
diff --git a/ctx.go b/ctx.go
index 757ec93c..da365f5a 100644
--- a/ctx.go
+++ b/ctx.go
@@ -888,6 +888,12 @@ func (c *Ctx) Render(name string, bind interface{}, layouts ...string) error {
defer bytebufferpool.Put(buf)
if c.app.config.Views != nil {
+ // Render template based on global layout if exists
+ if len(layouts) == 0 && c.app.config.ViewsLayout != "" {
+ layouts = []string{
+ c.app.config.ViewsLayout,
+ }
+ }
// Render template from Views
if err := c.app.config.Views.Render(buf, name, bind, layouts...); err != nil {
return err
diff --git a/ctx_test.go b/ctx_test.go
index c7488b44..b374f73f 100644
--- a/ctx_test.go
+++ b/ctx_test.go
@@ -1639,7 +1639,11 @@ type testTemplateEngine struct {
}
func (t *testTemplateEngine) Render(w io.Writer, name string, bind interface{}, layout ...string) error {
- return t.templates.ExecuteTemplate(w, name, bind)
+ if len(layout) == 0 {
+ return t.templates.ExecuteTemplate(w, name, bind)
+ }
+ _ = t.templates.ExecuteTemplate(w, name, bind)
+ return t.templates.ExecuteTemplate(w, layout[0], bind)
}
func (t *testTemplateEngine) Load() error {
@@ -1662,6 +1666,21 @@ func Test_Ctx_Render_Engine(t *testing.T) {
utils.AssertEqual(t, "Hello, World!
", string(c.Response().Body()))
}
+// go test -run Test_Ctx_Render_Engine_With_View_Layout
+func Test_Ctx_Render_Engine_With_View_Layout(t *testing.T) {
+ engine := &testTemplateEngine{}
+ engine.Load()
+ app := New(Config{ViewsLayout: "main.tmpl"})
+ app.config.Views = engine
+ c := app.AcquireCtx(&fasthttp.RequestCtx{})
+ defer app.ReleaseCtx(c)
+ err := c.Render("index.tmpl", Map{
+ "Title": "Hello, World!",
+ })
+ utils.AssertEqual(t, nil, err)
+ utils.AssertEqual(t, "Hello, World!
I'm main
", string(c.Response().Body()))
+}
+
// go test -v -run=^$ -bench=Benchmark_Ctx_Render_Engine -benchmem -count=4
func Benchmark_Ctx_Render_Engine(b *testing.B) {
engine := &testTemplateEngine{}