diff --git a/README.md b/README.md index a48be38..16a4904 100644 --- a/README.md +++ b/README.md @@ -115,3 +115,36 @@ func loadTemplates(templatesDir string) multitemplate.Renderer { return r } ``` + +### Partial render + +Allows rendering a specific template/block defined in a file with `template#block` syntax. + +See [example/partial/example.go](example/partial/example.go), [htmx ~ Template Fragments](https://htmx.org/essays/template-fragments/) + +```go +func main() { + router := gin.Default() + router.HTMLRender = createMyRender() + + // Route to render full template + router.GET("/", func(c *gin.Context) { + c.HTML(200, "index", gin.H{ + "items": []gin.H{ + {"name": "Apple"}, + {"name": "Banana"}, + {"name": "Cherry"}, + }, + }) + }) + + // Route to render partial template using "index#item" syntax + router.GET("/item", func(c *gin.Context) { + c.HTML(200, "index#item", gin.H{ + "name": "Watermelon", + }) + }) + + router.Run(":8080") +} +``` diff --git a/dynamic.go b/dynamic.go index 113148a..1e1d3b4 100644 --- a/dynamic.go +++ b/dynamic.go @@ -248,12 +248,14 @@ func (r DynamicRender) AddFromFilesFuncsWithOptions( // Instance supply render string func (r DynamicRender) Instance(name string, data interface{}) render.Render { - builder, ok := r[name] + tmplName, partialName := parseTemplateName(name) + builder, ok := r[tmplName] if !ok { - panic(fmt.Sprintf("Dynamic template with name %s not found", name)) + panic(fmt.Sprintf("Dynamic template with name %s not found", tmplName)) } return render.HTML{ Template: builder.buildTemplate(), + Name: partialName, Data: data, } } diff --git a/example/partial/example.go b/example/partial/example.go new file mode 100644 index 0000000..2c54674 --- /dev/null +++ b/example/partial/example.go @@ -0,0 +1,41 @@ +package main + +import ( + "log" + + "github.com/gin-contrib/multitemplate" + "github.com/gin-gonic/gin" +) + +func createMyRender() multitemplate.Renderer { + r := multitemplate.NewRenderer() + r.AddFromFiles("index", "templates/base.html", "templates/item.html") + return r +} + +func main() { + router := gin.Default() + router.HTMLRender = createMyRender() + + // Route to render full template + router.GET("/", func(c *gin.Context) { + c.HTML(200, "index", gin.H{ + "items": []gin.H{ + {"name": "Apple"}, + {"name": "Banana"}, + {"name": "Cherry"}, + }, + }) + }) + + // Route to render partial template using "index#item" syntax + router.GET("/item", func(c *gin.Context) { + c.HTML(200, "index#item", gin.H{ + "name": "Watermelon", + }) + }) + + if err := router.Run(":8080"); err != nil { + log.Fatal(err) + } +} diff --git a/example/partial/templates/base.html b/example/partial/templates/base.html new file mode 100644 index 0000000..4f675bf --- /dev/null +++ b/example/partial/templates/base.html @@ -0,0 +1,2 @@ +
Hello, world
+{{range .items}}{{template "item" .}}{{end}} \ No newline at end of file diff --git a/example/partial/templates/item.html b/example/partial/templates/item.html new file mode 100644 index 0000000..363e618 --- /dev/null +++ b/example/partial/templates/item.html @@ -0,0 +1 @@ +{{define "item"}}Hello, world
+{{range .items}}{{block "item" .}}