diff --git a/sui/api/api.go b/sui/api/api.go index cbb665a7..4840041d 100644 --- a/sui/api/api.go +++ b/sui/api/api.go @@ -156,6 +156,14 @@ var dsl = []byte(` "body": "?:content", "headers": { "Content-Type": "?:type"} } + }, + + { + "path": "/:id/preview/:template_id/*route", + "method": "GET", + "process": "sui.Preview.Render", + "in": ["$param.id", "$param.template_id", "$param.path", "$header.Referer", "$query.r", "$query.t"], + "out": {"status": 200, "type": "text/html; charset=utf-8"} } ], } diff --git a/sui/api/process.go b/sui/api/process.go index 6accaef6..4e3f51ed 100644 --- a/sui/api/process.go +++ b/sui/api/process.go @@ -41,6 +41,8 @@ func init() { "editor.source": EditorSource, "editor.renderaftersavetemp": EditorRenderAfterSaveTemp, "editor.sourceaftersavetemp": EditorSourceAfterSaveTemp, + + "preview.render": PreviewRender, }) } @@ -531,6 +533,44 @@ func EditorSourceAfterSaveTemp(process *process.Process) interface{} { return EditorSource(process) } +// PreviewRender handle the render page request +func PreviewRender(process *process.Process) interface{} { + + process.ValidateArgNums(3) + sui := get(process) + id := process.ArgsString(0) + templateID := process.ArgsString(1) + route := route(process, 2) + referer := process.ArgsString(3, "") + + // reqData := process.ArgsString(4) + // timestamp := process.Args[4].(*timestamp.Timestamp) + + req := &core.Request{ + Method: "GET", + AssetRoot: fmt.Sprintf("/api/__yao/sui/v1/%s/asset/%s/@assets", id, templateID), + Referer: referer, + } + + tmpl, err := sui.GetTemplate(templateID) + if err != nil { + exception.New(err.Error(), 500).Throw() + } + + page, err := tmpl.Page(route) + if err != nil { + exception.New(err.Error(), 500).Throw() + } + + // Request data + html, err := page.PreviewRender(req) + if err != nil { + exception.New(err.Error(), 500).Throw() + } + + return html +} + // get the sui func get(process *process.Process) core.SUI { sui, has := core.SUIs[process.ArgsString(0)] diff --git a/sui/api/process_test.go b/sui/api/process_test.go index dad09d18..51d1c7e4 100644 --- a/sui/api/process_test.go +++ b/sui/api/process_test.go @@ -568,6 +568,25 @@ func TestEditorRenderWithQuery(t *testing.T) { assert.NotEmpty(t, res.(*core.ResponseEditorRender).HTML) } +func TestPreviewRender(t *testing.T) { + load(t) + defer clean() + + // test demo + p, err := process.Of("sui.preview.render", "demo", "tech-blue", "/index") + if err != nil { + t.Fatal(err) + } + + res, err := p.Exec() + if err != nil { + t.Fatal(err) + } + + assert.IsType(t, "", res) + assert.NotEmpty(t, res) +} + func TestEditorPageSource(t *testing.T) { load(t) defer clean() diff --git a/sui/core/compile.go b/sui/core/compile.go index 2de47774..cb2af16f 100644 --- a/sui/core/compile.go +++ b/sui/core/compile.go @@ -1,7 +1,9 @@ package core import ( + "fmt" "regexp" + "strings" "github.com/evanw/esbuild/pkg/api" "github.com/yaoapp/gou/runtime/transform" @@ -46,3 +48,65 @@ func (page *Page) CompileCSS(source []byte, minify bool) ([]byte, error) { } return source, nil } + +// CompileHTML compile the html +func (page *Page) CompileHTML(source []byte, minify bool) ([]byte, error) { + return source, nil +} + +// BuildHTML build the html +func (page *Page) BuildHTML(assetRoot string) (string, error) { + + html := string(page.Document) + if page.Codes.HTML.Code != "" { + html = strings.Replace(html, "{{ __page }}", page.Codes.HTML.Code, 1) + } + + code := strings.ReplaceAll(html, "@assets", assetRoot) + res, err := page.CompileHTML([]byte(code), false) + if err != nil { + return "", err + } + + return string(res), nil +} + +// BuildStyle build the style +func (page *Page) BuildStyle(assetRoot string) (string, error) { + if page.Codes.CSS.Code == "" { + return "", nil + } + + code := strings.ReplaceAll(page.Codes.CSS.Code, "@assets", assetRoot) + res, err := page.CompileCSS([]byte(code), false) + if err != nil { + return "", err + } + + return fmt.Sprintf("\n", res), nil +} + +// BuildScript build the script +func (page *Page) BuildScript(assetRoot string) (string, error) { + + if page.Codes.JS.Code == "" && page.Codes.TS.Code == "" { + return "", nil + } + + if page.Codes.TS.Code != "" { + res, err := page.CompileTS([]byte(page.Codes.TS.Code), false) + if err != nil { + return "", err + } + + return fmt.Sprintf("\n", res), nil + } + + code := strings.ReplaceAll(page.Codes.JS.Code, "@assets", assetRoot) + res, err := page.CompileCSS([]byte(code), false) + if err != nil { + return "", err + } + + return fmt.Sprintf("\n", res), nil +} diff --git a/sui/core/core.go b/sui/core/core.go index e4a2095e..7b86132e 100644 --- a/sui/core/core.go +++ b/sui/core/core.go @@ -12,7 +12,7 @@ func Load(file string, id string) (*DSL, error) { return nil, err } - dsl := DSL{} + dsl := DSL{ID: id} err = application.Parse(file, data, &dsl) if err != nil { return nil, err diff --git a/sui/core/data.go b/sui/core/data.go index db1f09bf..1e2f5d0c 100644 --- a/sui/core/data.go +++ b/sui/core/data.go @@ -22,7 +22,7 @@ func (page *Page) Data(request *Request) (map[string]interface{}, map[string]int return nil, setting, nil } -// RenderHTML render for the html -func (page *Page) renderData(html string, data map[string]interface{}, warnings []string) (string, error) { +// Render render for the html +func (page *Page) Render(html string, data map[string]interface{}, warnings []string) (string, error) { return html, nil } diff --git a/sui/core/editor.go b/sui/core/editor.go index 2b11c9c9..dbe109b0 100644 --- a/sui/core/editor.go +++ b/sui/core/editor.go @@ -61,7 +61,7 @@ func (page *Page) EditorRender(request *Request) (*ResponseEditorRender, error) } if html != "" { - html, err := page.renderData(html, data, res.Warnings) + html, err := page.Render(html, data, res.Warnings) if err != nil { res.Warnings = append(res.Warnings, err.Error()) } diff --git a/sui/core/interfaces.go b/sui/core/interfaces.go index 59caf9ae..66a7dffd 100644 --- a/sui/core/interfaces.go +++ b/sui/core/interfaces.go @@ -49,6 +49,8 @@ type IPage interface { EditorStyleSource() SourceData EditorDataSource() SourceData + PreviewRender(request *Request) (string, error) + AssetScript() (*Asset, error) AssetStyle() (*Asset, error) } diff --git a/sui/core/preview.go b/sui/core/preview.go new file mode 100644 index 00000000..1e8a5ff7 --- /dev/null +++ b/sui/core/preview.go @@ -0,0 +1,84 @@ +package core + +import ( + "fmt" +) + +// PreviewRender render HTML for the preview +func (page *Page) PreviewRender(request *Request) (string, error) { + + warnings := []string{} + html, err := page.BuildHTML(request.AssetRoot) + if err != nil { + warnings = append(warnings, err.Error()) + } + + data, _, err := page.Data(request) + if err != nil { + warnings = append(warnings, err.Error()) + } + + html, err = page.Render(html, data, warnings) + if err != nil { + warnings = append(warnings, err.Error()) + } + + // Add Style & Script & Warning + doc, err := NewDocument([]byte(html)) + if err != nil { + warnings = append(warnings, err.Error()) + } + + // Add Style + style, err := page.BuildStyle(request.AssetRoot) + if err != nil { + warnings = append(warnings, err.Error()) + } + doc.Selection.Find("head").AppendHtml(style) + + // Add Script + script, err := page.BuildScript(request.AssetRoot) + if err != nil { + warnings = append(warnings, err.Error()) + } + doc.Selection.Find("body").AppendHtml(script) + + // Add Frame Height + if request.Referer != "" { + doc.Selection.Find("body").AppendHtml(` + + `) + } + + // Add Warning + if len(warnings) > 0 { + warningHTML := "