From 5eaaa3474fef030f50e0d43ffeb90c6e3b85eb09 Mon Sep 17 00:00:00 2001 From: Thanatat Tamtan Date: Sat, 23 Sep 2023 12:14:55 +0700 Subject: [PATCH] implement ctx.Render (#107) * implement render * add test --- context.go | 35 +++++++++++++++++++++++++++++++++++ context_test.go | 13 +++++++++++++ 2 files changed, 48 insertions(+) diff --git a/context.go b/context.go index 12ad84b..63f9e58 100644 --- a/context.go +++ b/context.go @@ -7,6 +7,7 @@ import ( "encoding/hex" "encoding/json" "fmt" + "html/template" "io" "net" "net/http" @@ -266,6 +267,40 @@ func (ctx *Context) Component(name string, data any) error { return ctx.CopyFrom(buf) } +// Render renders html template +func (ctx *Context) Render(tmpl string, data any) error { + // TODO: cache template + // TODO: use pre-defined template func + t, err := template.New("").Parse(tmpl) + if err != nil { + return err + } + + return ctx.executeTemplate(t, data) +} + +func (ctx *Context) executeTemplate(t *template.Template, data any) error { + if !ctx.etag { + ctx.setContentType("text/html; charset=utf-8") + return filterRenderError(t.Execute(ctx.w, data)) + } + + buf := getBytes() + defer putBytes(buf) + + err := t.Execute(buf, data) + if err != nil { + return err + } + + if ctx.setETag(buf.Bytes()) { + return nil + } + + ctx.setContentType("text/html; charset=utf-8") + return ctx.CopyFrom(buf) +} + func (ctx *Context) setContentType(value string) { if len(ctx.w.Header().Get("Content-Type")) == 0 { ctx.w.Header().Set("Content-Type", value) diff --git a/context_test.go b/context_test.go index 583baf0..ae737ac 100644 --- a/context_test.go +++ b/context_test.go @@ -776,6 +776,19 @@ func TestContext(t *testing.T) { assert.Equal(t, w.Body.String(), "hello, world") }) + t.Run("Render", func(t *testing.T) { + w := httptest.NewRecorder() + r := httptest.NewRequest(http.MethodPost, "/", nil) + + app := hime.New() + ctx := hime.NewAppContext(app, w, r) + + assert.NoError(t, ctx.Render(`hello, {{.}}`, "world")) + assert.Equal(t, w.Code, http.StatusOK) + assert.Equal(t, w.Header().Get("Content-Type"), "text/html; charset=utf-8") + assert.Equal(t, w.Body.String(), "hello, world") + }) + t.Run("BindJSON", func(t *testing.T) { w := httptest.NewRecorder() r := httptest.NewRequest(http.MethodPost, "/", bytes.NewReader([]byte(`{"a":1}`)))