From f23f73082d49e466c97b088efe75e73a34b1fb51 Mon Sep 17 00:00:00 2001 From: Yonghwan SO Date: Thu, 1 Nov 2018 01:39:24 +0900 Subject: [PATCH] removed local `partial` and integrated with plush's `partial` --- render/js.go | 29 +++----------------- render/js_test.go | 31 ++++++++++++++++----- render/partials_test.go | 54 +++++++++++++++++++++++++++++++++++++ render/render.go | 2 +- render/template.go | 60 ++++++++++++++++------------------------- 5 files changed, 106 insertions(+), 70 deletions(-) diff --git a/render/js.go b/render/js.go index 24ff8c057..9a8d5c565 100644 --- a/render/js.go +++ b/render/js.go @@ -1,11 +1,8 @@ package render import ( - "html/template" - "strings" - "github.com/gobuffalo/plush" - "github.com/pkg/errors" + "github.com/markbates/oncer" ) // JavaScript renders the named files using the 'application/javascript' @@ -41,28 +38,8 @@ func (e *Engine) JavaScript(names ...string) Renderer { } // JSTemplateEngine renders files with a `.js` extension through Plush. -// It also implements a new `partial` helper that will run non-JS partials -// through `JSEscapeString` before injecting. +// Deprecated: use github.com/gobuffalo/plush.BuffaloRenderer instead. func JSTemplateEngine(input string, data map[string]interface{}, helpers map[string]interface{}) (string, error) { - var pf partFunc - var ok bool - if pf, ok = helpers["partial"].(func(string, Data) (template.HTML, error)); !ok { - return "", errors.New("could not find a partial function") - } - - helpers["partial"] = func(name string, dd Data) (template.HTML, error) { - if strings.Contains(name, ".js") { - return pf(name, dd) - } - h, err := pf(name, dd) - if err != nil { - return "", errors.WithStack(err) - } - he := template.JSEscapeString(string(h)) - return template.HTML(he), nil - } - + oncer.Deprecate(0, "render.JSTemplateEngine", "Use github.com/gobuffalo/plush.BuffaloRenderer instead.") return plush.BuffaloRenderer(input, data, helpers) } - -type partFunc func(string, Data) (template.HTML, error) diff --git a/render/js_test.go b/render/js_test.go index 1f6c7d84d..c03a66339 100644 --- a/render/js_test.go +++ b/render/js_test.go @@ -1,4 +1,4 @@ -package render_test +package render import ( "bytes" @@ -8,7 +8,6 @@ import ( "strings" "testing" - "github.com/gobuffalo/buffalo/render" "github.com/gobuffalo/packr" "github.com/stretchr/testify/require" ) @@ -30,7 +29,7 @@ func Test_JavaScript(t *testing.T) { t.Run("without a layout", func(st *testing.T) { r := require.New(st) - j := render.New(render.Options{ + j := New(Options{ TemplatesBox: packr.NewBox(tmpDir), }).JavaScript @@ -51,7 +50,7 @@ func Test_JavaScript(t *testing.T) { _, err = layout.Write([]byte("<%= yield %>")) r.NoError(err) - re := render.New(render.Options{ + re := New(Options{ JavaScriptLayout: filepath.Base(layout.Name()), TemplatesBox: packr.NewBox(tmpDir), }) @@ -94,7 +93,7 @@ func Test_JavaScript_JS_Partial(t *testing.T) { r.NoError(err) defer os.RemoveAll(dir) - re := render.New(render.Options{ + re := New(Options{ TemplatesBox: packr.NewBox(dir), }) @@ -115,6 +114,26 @@ func Test_JavaScript_JS_Partial(t *testing.T) { r.Equal("let a = 1;\nalert('hi!');", bb.String()) } +func Test_JavaScript_JS_Partial_Without_Extension(t *testing.T) { + r := require.New(t) + + const testJS = "let a = 1;\n<%= partial(\"part\") %>" + const partJS = "alert('Hi <%= name %>!');" + + err := withHTMLFile("test.js", testJS, func(e *Engine) { + err := withHTMLFile("_part.js", partJS, func(e *Engine) { + bb := &bytes.Buffer{} + renderer := e.JavaScript("test.js") + r.Equal("application/javascript", renderer.ContentType()) + err := renderer.Render(bb, Data{"name": "Yonghwan"}) + r.NoError(err) + r.Equal("let a = 1;\nalert('Hi Yonghwan!');", bb.String()) + }) + r.NoError(err) + }) + r.NoError(err) +} + func Test_JavaScript_HTML_Partial(t *testing.T) { r := require.New(t) @@ -122,7 +141,7 @@ func Test_JavaScript_HTML_Partial(t *testing.T) { r.NoError(err) defer os.RemoveAll(dir) - re := render.New(render.Options{ + re := New(Options{ TemplatesBox: packr.NewBox(dir), }) diff --git a/render/partials_test.go b/render/partials_test.go index 95fe9ebba..bd6dd2f7c 100644 --- a/render/partials_test.go +++ b/render/partials_test.go @@ -75,6 +75,60 @@ func Test_Template_Partial_Form(t *testing.T) { } +func Test_Template_Partial_With_For(t *testing.T) { + r := require.New(t) + + const forHTML = `<%= for(user) in users { %><%= partial("row") %><% } %>` + const rowHTML = `Hi <%= user.Name %>, ` + const result = `Hi Mark, Hi Yonghwan,` + + users := []struct { + Name string + }{{Name: "Mark"}, {Name: "Yonghwan"}} + + err := withHTMLFile("for.html", forHTML, func(e *Engine) { + err := withHTMLFile("_row.html", rowHTML, func(e *Engine) { + + re := e.Template("text/html; charset=utf-8", "for.html") + bb := &bytes.Buffer{} + err := re.Render(bb, Data{"users": users}) + r.NoError(err) + r.Equal(result, strings.TrimSpace(bb.String())) + + }) + r.NoError(err) + }) + r.NoError(err) + +} + +func Test_Template_Partial_With_For_And_Local(t *testing.T) { + r := require.New(t) + + const forHTML = `<%= for(user) in users { %><%= partial("row", {say:"Hi"}) %><% } %>` + const rowHTML = `<%= say %> <%= user.Name %>, ` + const result = `Hi Mark, Hi Yonghwan,` + + users := []struct { + Name string + }{{Name: "Mark"}, {Name: "Yonghwan"}} + + err := withHTMLFile("for.html", forHTML, func(e *Engine) { + err := withHTMLFile("_row.html", rowHTML, func(e *Engine) { + + re := e.Template("text/html; charset=utf-8", "for.html") + bb := &bytes.Buffer{} + err := re.Render(bb, Data{"users": users}) + r.NoError(err) + r.Equal(result, strings.TrimSpace(bb.String())) + + }) + r.NoError(err) + }) + r.NoError(err) + +} + func Test_Template_Partial_Recursive_With_Global_And_Local_Context(t *testing.T) { r := require.New(t) diff --git a/render/render.go b/render/render.go index 1cbece885..2706dbfec 100644 --- a/render/render.go +++ b/render/render.go @@ -32,7 +32,7 @@ func New(opts Options) *Engine { opts.TemplateEngines["txt"] = plush.BuffaloRenderer } if _, ok := opts.TemplateEngines["js"]; !ok { - opts.TemplateEngines["js"] = JSTemplateEngine + opts.TemplateEngines["js"] = plush.BuffaloRenderer } if _, ok := opts.TemplateEngines["md"]; !ok { opts.TemplateEngines["md"] = MDTemplateEngine diff --git a/render/template.go b/render/template.go index f7c99ce6a..7bb17000e 100644 --- a/render/template.go +++ b/render/template.go @@ -1,7 +1,6 @@ package render import ( - "fmt" "html/template" "io" "os" @@ -17,7 +16,6 @@ type templateRenderer struct { *Engine contentType string names []string - data Data } func (s templateRenderer) ContentType() string { @@ -25,7 +23,6 @@ func (s templateRenderer) ContentType() string { } func (s *templateRenderer) Render(w io.Writer, data Data) error { - s.data = data var body template.HTML var err error for _, name := range s.names { @@ -39,39 +36,7 @@ func (s *templateRenderer) Render(w io.Writer, data Data) error { return nil } -func (s templateRenderer) partial(name string, dd Data) (template.HTML, error) { - d, f := filepath.Split(name) - name = filepath.Join(d, "_"+f) - m := Data{} - for k, v := range s.data { - m[k] = v - } - for k, v := range dd { - m[k] = v - } - - if _, ok := m["layout"]; ok { - - var body template.HTML - var err error - - body, err = s.exec(name, m) - if err != nil { - return body, err - } - m["yield"] = body - d, f := filepath.Split(fmt.Sprintf("%v", m["layout"])) - name = filepath.Join(d, "_"+f) - - } - - return s.exec(name, m) -} - -func (s templateRenderer) exec(name string, data Data) (template.HTML, error) { - ct := strings.ToLower(s.contentType) - data["contentType"] = ct - +func fixExtension(name string, ct string) string { if filepath.Ext(name) == "" { switch { case strings.Contains(ct, "html"): @@ -82,6 +47,27 @@ func (s templateRenderer) exec(name string, data Data) (template.HTML, error) { name += ".md" } } + return name +} + +// partialFeeder returns template string for the name from `TemplateBox`. +// It should be registered as helper named `partialFeeder` so plush can +// find it with the name. +func (s templateRenderer) partialFeeder(name string) (string, error) { + ct := strings.ToLower(s.contentType) + + d, f := filepath.Split(name) + name = filepath.Join(d, "_"+f) + name = fixExtension(name, ct) + + return s.TemplatesBox.FindString(name) +} + +func (s templateRenderer) exec(name string, data Data) (template.HTML, error) { + ct := strings.ToLower(s.contentType) + data["contentType"] = ct + + name = fixExtension(name, ct) // Try to use localized version templateName := name @@ -119,7 +105,7 @@ func (s templateRenderer) exec(name string, data Data) (template.HTML, error) { } helpers := map[string]interface{}{ - "partial": s.partial, + "partialFeeder": s.partialFeeder, } helpers = s.addAssetsHelpers(helpers)