From cf45040a1cb8e92e3557d0eeb8b6dcf4516579b3 Mon Sep 17 00:00:00 2001 From: Max Date: Fri, 5 Jul 2024 16:19:57 +0800 Subject: [PATCH] feat: Add and optimize SUI CompileAsComponent support --- sui/core/build.go | 22 ++++++----- sui/core/compile.go | 21 ++++++++++ sui/storages/local/build.go | 68 +++++++++++++++++++++++++++----- sui/storages/local/build_test.go | 61 ++++++++++++++++++++++++++++ sui/storages/local/local_test.go | 2 + 5 files changed, 155 insertions(+), 19 deletions(-) diff --git a/sui/core/build.go b/sui/core/build.go index 912a88dc..8dfbf19f 100644 --- a/sui/core/build.go +++ b/sui/core/build.go @@ -160,6 +160,18 @@ func (page *Page) parse(ctx *BuildContext, doc *goquery.Document, option *BuildO page.Translations = append(page.Translations, translations...) } + name, has := sel.Attr("is") + if has { + // Check if Just-In-Time Component ( "is" has variable ) + if ctx.isJitComponent(name) { + sel.SetAttr("s:jit", "true") + sel.SetAttr("s:root", public.Root) + ctx.addJitComponent(name) + return false + } + return true + } + tagName := sel.Get(0).Data if tagName == "page" { return true @@ -169,16 +181,6 @@ func (page *Page) parse(ctx *BuildContext, doc *goquery.Document, option *BuildO return false } - name, has := sel.Attr("is") - if has { - // Just in time component - if ctx.isJitComponent(name) { - sel.SetAttr("s:jit", "true") - sel.SetAttr("s:root", public.Root) - ctx.addJitComponent(name) - return false - } - } return has }) diff --git a/sui/core/compile.go b/sui/core/compile.go index c8f25d6e..460e8097 100644 --- a/sui/core/compile.go +++ b/sui/core/compile.go @@ -66,6 +66,27 @@ func (page *Page) Compile(ctx *BuildContext, option *BuildOption) (string, error return html, nil } +// CompileAsComponent compile the page as component +func (page *Page) CompileAsComponent(ctx *BuildContext, option *BuildOption) (string, error) { + + opt := *option + opt.IgnoreDocument = true + opt.WithWrapper = true + doc, warnings, err := page.Build(ctx, &opt) + if err != nil { + return "", err + } + + if warnings != nil && len(warnings) > 0 { + for _, warning := range warnings { + log.Warn("Compile page %s/%s/%s: %s", page.SuiID, page.TemplateID, page.Route, warning) + } + } + + page.ReplaceDocument(doc) + return doc.Find("body").Html() +} + // CompileJS compile the javascript func (page *Page) CompileJS(source []byte, minify bool) ([]byte, []string, error) { scripts := []string{} diff --git a/sui/storages/local/build.go b/sui/storages/local/build.go index bfccb013..ce111749 100644 --- a/sui/storages/local/build.go +++ b/sui/storages/local/build.go @@ -61,16 +61,14 @@ func (tmpl *Template) Build(option *core.BuildOption) error { // loaed pages tmpl.loaded = map[string]core.IPage{} for _, page := range pages { - perr := page.Load() + err := page.Load() if err != nil { - err = multierror.Append(perr) - continue + return err } - perr = page.Build(ctx, option) - if perr != nil { - err = multierror.Append(perr) - continue + err = page.Build(ctx, option) + if err != nil { + return err } tmpl.loaded[page.Get().Route] = page } @@ -180,7 +178,6 @@ func (page *Page) Build(globalCtx *core.GlobalBuildContext, option *core.BuildOp option.AssetRoot = filepath.Join(root, "assets") } - log.Trace("Build the page %s AssetRoot: %s", page.Route, option.AssetRoot) html, err := page.Page.Compile(ctx, option) if err != nil { return err @@ -229,7 +226,60 @@ func (page *Page) Build(globalCtx *core.GlobalBuildContext, option *core.BuildOp // BuildAsComponent build the page as component func (page *Page) BuildAsComponent(globalCtx *core.GlobalBuildContext, option *core.BuildOption) error { - return page.writeJitHTML([]byte("
"+page.Route+" {{ type }} {{ bind }}
"), option.Data) + + ctx := core.NewBuildContext(globalCtx) + if option.AssetRoot == "" { + root, err := page.tmpl.local.DSL.PublicRoot(option.Data) + if err != nil { + log.Error("SyncAssets: Get the public root error: %s. use %s", err.Error(), page.tmpl.local.DSL.Public.Root) + root = page.tmpl.local.DSL.Public.Root + } + option.AssetRoot = filepath.Join(root, "assets") + } + + html, err := page.Page.CompileAsComponent(ctx, option) + if err != nil { + return err + } + + // Save the html + err = page.writeJitHTML([]byte(html), option.Data) + if err != nil { + return err + } + + // Save the locale files + err = page.writeLocaleFiles(option.Data) + if err != nil { + return err + } + + // Jit Components + if globalCtx == nil { + jitComponents, err := page.tmpl.GlobRoutes(ctx.GetJitComponents(), true) + if err != nil { + return err + } + + for _, route := range jitComponents { + var err error + p := page.tmpl.loaded[route] + if p == nil { + p, err = page.tmpl.Page(route) + if err != nil { + err = multierror.Append(err) + continue + } + } + + err = p.BuildAsComponent(globalCtx, option) + if err != nil { + err = multierror.Append(err) + } + } + } + + return err } func (page *Page) publicFile(data map[string]interface{}) string { diff --git a/sui/storages/local/build_test.go b/sui/storages/local/build_test.go index 1cd7a2a9..edcf1c16 100644 --- a/sui/storages/local/build_test.go +++ b/sui/storages/local/build_test.go @@ -1,8 +1,12 @@ package local import ( + "os" + "path/filepath" "testing" + "github.com/stretchr/testify/assert" + "github.com/yaoapp/gou/application" "github.com/yaoapp/yao/sui/core" ) @@ -19,4 +23,61 @@ func TestTemplateBuild(t *testing.T) { if err != nil { t.Fatalf("Components error: %v", err) } + + index := "/index.sui" + + // Check SUI + root := application.App.Root() + public := tmpl.(*Template).local.GetPublic() + path := filepath.Join(root, "public", public.Root) + assert.FileExists(t, filepath.Join(path, index)) + + content, err := os.ReadFile(filepath.Join(path, index)) + if err != nil { + t.Fatalf("ReadFile error: %v", err) + } + + assert.Contains(t, string(content), "body") + assert.Contains(t, string(content), ``) + assert.Contains(t, string(content), `