feat: Add and optimize SUI CompileAsComponent support
This commit is contained in:
parent
a435b1ad6e
commit
cf45040a1c
5 changed files with 155 additions and 19 deletions
|
|
@ -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
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -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{}
|
||||
|
|
|
|||
|
|
@ -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("<div>"+page.Route+" {{ type }} {{ bind }} </div>"), 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 {
|
||||
|
|
|
|||
|
|
@ -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), `<script src="/unit-test/assets/js/import.js"></script>`)
|
||||
assert.Contains(t, string(content), `<script name="config" type="json">`)
|
||||
assert.Contains(t, string(content), `<script name="data" type="json">`)
|
||||
assert.Contains(t, string(content), `<script name="global" type="json">`)
|
||||
|
||||
}
|
||||
|
||||
func TestTemplateBuildAsComponent(t *testing.T) {
|
||||
tests := prepare(t)
|
||||
defer clean()
|
||||
|
||||
tmpl, err := tests.Web.GetTemplate("default")
|
||||
if err != nil {
|
||||
t.Fatalf("GetTemplate error: %v", err)
|
||||
}
|
||||
|
||||
err = tmpl.Build(&core.BuildOption{SSR: true})
|
||||
if err != nil {
|
||||
t.Fatalf("Components error: %v", err)
|
||||
}
|
||||
|
||||
cselect := "/flowbite/components/edit/select.jit"
|
||||
cinput := "/flowbite/components/edit/input.jit"
|
||||
|
||||
// Check JIT
|
||||
root := application.App.Root()
|
||||
public := tmpl.(*Template).local.GetPublic()
|
||||
path := filepath.Join(root, "public", public.Root)
|
||||
assert.FileExists(t, filepath.Join(path, cselect))
|
||||
assert.FileExists(t, filepath.Join(path, cinput))
|
||||
|
||||
content, err := os.ReadFile(filepath.Join(path, cselect))
|
||||
if err != nil {
|
||||
t.Fatalf("ReadFile error: %v", err)
|
||||
}
|
||||
|
||||
assert.NotContains(t, string(content), "body")
|
||||
assert.NotContains(t, string(content), `<script name="config" type="json">`)
|
||||
assert.NotContains(t, string(content), `<script name="data" type="json">`)
|
||||
assert.NotContains(t, string(content), `<script name="global" type="json">`)
|
||||
assert.Contains(t, string(content), "function Init()")
|
||||
assert.Contains(t, string(content), `type="flowbite-edit-select"`)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@ func prepare(t *testing.T) TestCase {
|
|||
if err != nil {
|
||||
t.Fatalf("New error: %v", err)
|
||||
}
|
||||
core.SUIs["web"] = web
|
||||
|
||||
testDSL, err := core.Load("/suis/test.sui.yao", "test")
|
||||
if err != nil {
|
||||
|
|
@ -108,6 +109,7 @@ func prepare(t *testing.T) TestCase {
|
|||
if err != nil {
|
||||
t.Fatalf("New error: %v", err)
|
||||
}
|
||||
core.SUIs["test"] = test
|
||||
return TestCase{
|
||||
Test: test,
|
||||
Web: web,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue