diff --git a/sui/api/guards.go b/sui/api/guards.go index 9d90ca97..bfde62c1 100644 --- a/sui/api/guards.go +++ b/sui/api/guards.go @@ -399,9 +399,6 @@ func (r *Request) scriptGuardExec(c *gin.Context, name string, args []interface{ message := err.Error() if strings.HasPrefix(message, "Exception|") { parts := strings.Split(message, ": ") - - fmt.Println(parts) - if len(parts) > 1 { codestr := strings.TrimPrefix(parts[0], "Exception|") message := parts[1] diff --git a/sui/api/process.go b/sui/api/process.go index 093f1d09..b116d374 100644 --- a/sui/api/process.go +++ b/sui/api/process.go @@ -20,13 +20,15 @@ func init() { process.RegisterGroup("sui", map[string]process.Handler{ "setting": Setting, - "render": Render, - "run": Run, + "render": Render, // do not use this in script or flow, this is an internal method. Use the template.render instead + "run": Run, // do not use this in script or flow, this is an internal method. Use the template.run instead "template.get": TemplateGet, "template.find": TemplateFind, "template.asset": TemplateAsset, "template.assetupload": TemplateAssetUpload, + "template.render": TemplateRender, + // "template.run": TemplateRun, "locale.get": LocaleGet, "theme.get": ThemeGet, diff --git a/sui/api/render.go b/sui/api/render.go index 211d0ccb..8b3380c9 100644 --- a/sui/api/render.go +++ b/sui/api/render.go @@ -5,6 +5,7 @@ import ( "github.com/gin-gonic/gin" "github.com/yaoapp/gou/process" + "github.com/yaoapp/kun/exception" "github.com/yaoapp/yao/sui/core" ) @@ -115,3 +116,61 @@ func (r *Request) renderHTML(c *core.Cache, name string, html string, data core. return html, nil } + +// TemplateRender render the template asset +func TemplateRender(process *process.Process) interface{} { + process.ValidateArgNums(4) + sui := get(process) + tmpl, err := sui.GetTemplate(process.ArgsString(1)) + if err != nil { + exception.New(err.Error(), 500).Throw() + } + + root, err := sui.PublicRootWithSid(process.Sid) + if err != nil { + exception.New(err.Error(), 500).Throw() + } + + source := process.ArgsString(2) + page := tmpl.CreatePage(source) + route := page.Get().Route + doc, _, err := page.Get().Build(core.NewBuildContext(nil), &core.BuildOption{ + PublicRoot: root, + IgnoreDocument: true, + JitMode: true, + }) + if err != nil { + exception.New(err.Error(), 500).Throw() + return nil + } + + data := process.ArgsMap(3) + opt := process.ArgsMap(4, map[string]interface{}{}) + option := core.ParserOption{ + Theme: opt["theme"], + Locale: opt["locale"], + Debug: false, + DisableCache: true, + Route: route, + Root: root, + Script: nil, + Imports: nil, + Request: nil, + } + + parser := core.NewTemplateParser(core.Data(data), &option) + sel := doc.Find("body") + err = parser.RenderSelection(sel) + if err != nil { + exception.New(err.Error(), 500).Throw() + } + + sel.Find("[sui-hide]").Remove() + parser.Tidy(sel) + html, err := sel.Html() + if err != nil { + exception.New(err.Error(), 500).Throw() + } + + return html +} diff --git a/sui/api/render_test.go b/sui/api/render_test.go new file mode 100644 index 00000000..c86a3040 --- /dev/null +++ b/sui/api/render_test.go @@ -0,0 +1,62 @@ +package api + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/yaoapp/gou/process" +) + +func TestTemplateRender(t *testing.T) { + prepare(t) + defer clean() + + args := []any{"test", "advanced", "
{{ name}}
", map[string]any{"name": "test"}} + p, err := process.Of("sui.template.render", args...) + if err != nil { + t.Fatal(err) + } + + res, err := p.Exec() + if err != nil { + t.Fatal(err) + } + assert.Equal(t, "
test
", res) +} + +func TestTemplateRenderWithComponent(t *testing.T) { + prepare(t) + defer clean() + source := ` +
+

Component Render {{ name }}

+
+
+ + {{ upper(item) }} {{ name }} + +
+
+
+ ` + args := []any{"test", "advanced", source, map[string]any{"name": "test"}, map[string]any{"theme": "dark"}} + p, err := process.Of("sui.template.render", args...) + if err != nil { + t.Fatal(err) + } + + res, err := p.Exec() + if err != nil { + t.Fatal(err) + } + + assert.Contains(t, res, "Component Render test") + assert.Contains(t, res, "FOO test") + assert.Contains(t, res, "BAR test") +} diff --git a/sui/core/interfaces.go b/sui/core/interfaces.go index 7149cba7..a73b511b 100644 --- a/sui/core/interfaces.go +++ b/sui/core/interfaces.go @@ -37,6 +37,7 @@ type ITemplate interface { PageTree(route string) ([]*PageTreeNode, error) Page(route string) (IPage, error) PageExist(route string) bool + CreatePage(html string) IPage CreateEmptyPage(route string, setting *PageSetting) (IPage, error) RemovePage(route string) error GetPageFromAsset(asset string) (IPage, error) diff --git a/sui/storages/local/page.go b/sui/storages/local/page.go index 841be543..2ed568c3 100644 --- a/sui/storages/local/page.go +++ b/sui/storages/local/page.go @@ -5,6 +5,7 @@ import ( "path/filepath" "strings" + "github.com/google/uuid" jsoniter "github.com/json-iterator/go" "github.com/yaoapp/kun/log" "github.com/yaoapp/yao/sui/core" @@ -268,6 +269,30 @@ func (page *Page) SaveAs(route string, setting *core.PageSetting) (core.IPage, e return page.tmpl.Page(route) } +// CreatePage create a new page by the source +func (tmpl *Template) CreatePage(source string) core.IPage { + name := uuid.New().String() + route := "/" + uuid.New().String() + return &Page{ + tmpl: tmpl, + Page: &core.Page{ + Route: route, + TemplateID: tmpl.ID, + SuiID: tmpl.local.ID, + Path: filepath.Join(tmpl.Root, route), + Name: name, + Codes: core.SourceCodes{ + HTML: core.Source{File: fmt.Sprintf("%s.html", name), Code: source}, + CSS: core.Source{File: fmt.Sprintf("%s.css", name)}, + JS: core.Source{File: fmt.Sprintf("%s.js", name)}, + TS: core.Source{File: fmt.Sprintf("%s.ts", name)}, + LESS: core.Source{File: fmt.Sprintf("%s.less", name)}, + CONF: core.Source{File: fmt.Sprintf("%s.config", name)}, + }, + }, + } +} + // CreateEmptyPage create a new empty func (tmpl *Template) CreateEmptyPage(route string, setting *core.PageSetting) (core.IPage, error) { if tmpl.PageExist(route) { diff --git a/sui/storages/local/page_test.go b/sui/storages/local/page_test.go index 62badeed..351bbce1 100644 --- a/sui/storages/local/page_test.go +++ b/sui/storages/local/page_test.go @@ -590,3 +590,35 @@ func TestPageAssetStyle(t *testing.T) { assert.NotEmpty(t, asset.Content) assert.Equal(t, "text/css; charset=utf-8", asset.Type) } + +func TestCreatePage(t *testing.T) { + tests := prepare(t) + defer clean() + + tmpl, err := tests.Test.GetTemplate("advanced") + if err != nil { + t.Fatalf("GetTemplate error: %v", err) + } + + page := tmpl.CreatePage("
Test
") + if page == nil { + t.Fatalf("CreatePage error") + } + + doc, _, err := page.Get().Build(core.NewBuildContext(nil), &core.BuildOption{ + PublicRoot: tmpl.GetRoot(), + IgnoreDocument: true, + JitMode: true, + }) + if err != nil { + t.Fatalf("Compile error: %v", err) + } + + sel := doc.Find("body") + html, err := sel.Html() + if err != nil { + t.Fatalf("Html error: %v", err) + } + + assert.Equal(t, "
Test
", html) +}