diff --git a/examples/template-blocks/layouts/default.html b/examples/template-blocks/layouts/default.html
new file mode 100644
index 00000000..a519fce9
--- /dev/null
+++ b/examples/template-blocks/layouts/default.html
@@ -0,0 +1,10 @@
+
+
+
+
+ {{block "head" .}} {{end}}
+
+
+{{block "body" .}} {{end}}
+
+
diff --git a/examples/template-blocks/main.go b/examples/template-blocks/main.go
new file mode 100644
index 00000000..1d0fe2f1
--- /dev/null
+++ b/examples/template-blocks/main.go
@@ -0,0 +1,19 @@
+package main
+
+import "github.com/gin-gonic/gin"
+
+func main() {
+ router := gin.Default()
+
+ router.AddHTMLTemplate("/", "layouts/default.html", "views/blocks1.html")
+ router.AddHTMLTemplate("/blocks2/", "layouts/default.html", "views/blocks2.html")
+
+ router.GET("/", render)
+ router.GET("/blocks2/", render)
+ router.Run(":8080")
+
+}
+
+func render(c *gin.Context) {
+ c.HTML(200, c.Request.URL.Path, gin.H{})
+}
diff --git a/examples/template-blocks/views/blocks1.html b/examples/template-blocks/views/blocks1.html
new file mode 100644
index 00000000..39c333b8
--- /dev/null
+++ b/examples/template-blocks/views/blocks1.html
@@ -0,0 +1,7 @@
+{{define "head"}}
+Blocks 1
+{{end}}
+
+{{define "body"}}
+Go to blocks 2
+{{end}}
diff --git a/examples/template-blocks/views/blocks2.html b/examples/template-blocks/views/blocks2.html
new file mode 100644
index 00000000..749d9b64
--- /dev/null
+++ b/examples/template-blocks/views/blocks2.html
@@ -0,0 +1,7 @@
+{{define "head"}}
+Blocks 2
+{{end}}
+
+{{define "body"}}
+Go to blocks 1
+{{end}}
diff --git a/gin.go b/gin.go
index fb1df9cd..19683914 100644
--- a/gin.go
+++ b/gin.go
@@ -147,6 +147,22 @@ func (engine *Engine) SetHTMLTemplate(templ *template.Template) {
engine.HTMLRender = render.HTMLProduction{Template: templ}
}
+// AddHTMLTemplate allow to use "block" template feature from go1.6
+func (engine *Engine) AddHTMLTemplate(name string, paths... string) {
+ var templateStorage render.TemplateStorage
+ t, ok := engine.HTMLRender.(render.TemplateStorage)
+ if ok {
+ templateStorage = t
+ } else {
+ if len(engine.trees) > 0 {
+ debugPrintWARNINGSetHTMLTemplate()
+ }
+ templateStorage = render.TemplateStorage{make(map[string]*template.Template)}
+ }
+ templateStorage.Storage[name] = template.Must(template.ParseFiles(paths...))
+ engine.HTMLRender = templateStorage
+}
+
// Adds handlers for NoRoute. It return a 404 code by default.
func (engine *Engine) NoRoute(handlers ...HandlerFunc) {
engine.noRoute = handlers
diff --git a/render/render_test.go b/render/render_test.go
index 7a6ffb7d..0107709c 100644
--- a/render/render_test.go
+++ b/render/render_test.go
@@ -128,3 +128,41 @@ func TestRenderHTMLTemplate(t *testing.T) {
assert.Equal(t, w.Body.String(), "Hello alexandernyquist")
assert.Equal(t, w.Header().Get("Content-Type"), "text/html; charset=utf-8")
}
+
+func TestRenderHTMLTemplateWithBlocks(t *testing.T) {
+ w := httptest.NewRecorder()
+
+ var indexTemplate = template.Must(template.New("").Parse(`{{block "first" .}}{{end}}{{block "second" .}}{{end}}`))
+
+ first := `{{define "first"}}{{.first}}{{end}}{{define "second"}}_{{.second}}{{end}}`
+ var firstT = template.Must(template.Must(indexTemplate.Clone()).Parse(first))
+ second := `{{define "first"}}{{.first}}{{end}}{{define "second"}}_{{.second}}{{end}}`
+ var secondT = template.Must(template.Must(indexTemplate.Clone()).Parse(second))
+
+ templateStorage := TemplateStorage{make(map[string]*template.Template)}
+ templateStorage.Storage["first"] = firstT
+ templateStorage.Storage["second"] = secondT
+
+ testMap := map[string]interface{}{
+ "second": "second",
+ "first": "first",
+ }
+
+ instance := templateStorage.Instance("first", testMap)
+
+ err := instance.Render(w)
+
+ assert.NoError(t, err)
+ assert.Equal(t, w.Body.String(), "first_second")
+ assert.Equal(t, w.Header().Get("Content-Type"), "text/html; charset=utf-8")
+
+ w = httptest.NewRecorder()
+
+ instance = templateStorage.Instance("second", testMap)
+
+ err = instance.Render(w)
+
+ assert.NoError(t, err)
+ assert.Equal(t, w.Body.String(), "first_second")
+ assert.Equal(t, w.Header().Get("Content-Type"), "text/html; charset=utf-8")
+}
diff --git a/render/template_storage.go b/render/template_storage.go
new file mode 100644
index 00000000..00e89b5e
--- /dev/null
+++ b/render/template_storage.go
@@ -0,0 +1,33 @@
+// Copyright 2014 Manu Martinez-Almeida. All rights reserved.
+// Use of this source code is governed by a MIT style
+// license that can be found in the LICENSE file.
+
+package render
+
+import (
+ "html/template"
+ "net/http"
+)
+
+type TemplateStorage struct {
+ Storage map[string]*template.Template
+}
+
+func (t TemplateStorage) Instance(name string, data interface{}) Render {
+ return HTMLWithBlock{
+ Template: t.Storage[name],
+ Name: name,
+ Data: data,
+ }
+}
+
+type HTMLWithBlock struct {
+ Template *template.Template
+ Name string
+ Data interface{}
+}
+
+func (r HTMLWithBlock) Render(w http.ResponseWriter) error {
+ writeContentType(w, htmlContentType)
+ return r.Template.Execute(w, r.Data)
+}