diff --git a/cmd/sui/build.go b/cmd/sui/build.go
index 3ff94266..795e308d 100644
--- a/cmd/sui/build.go
+++ b/cmd/sui/build.go
@@ -88,7 +88,7 @@ var BuildCmd = &cobra.Command{
mode = "development"
}
- err = tmpl.Build(&core.BuildOption{SSR: true, AssetRoot: assetRoot, ExecScripts: true, ScriptMinify: minify, StyleMinify: minify})
+ warnings, err := tmpl.Build(&core.BuildOption{SSR: true, AssetRoot: assetRoot, ExecScripts: true, ScriptMinify: minify, StyleMinify: minify})
if err != nil {
fmt.Fprintln(os.Stderr, color.RedString(err.Error()))
return
@@ -99,6 +99,11 @@ var BuildCmd = &cobra.Command{
fmt.Println(color.YellowString("Build succeeded for %s in %s", mode, timecost))
return
}
+ if len(warnings) > 0 {
+ for _, warning := range warnings {
+ fmt.Println(color.YellowString("Warning: %s", warning))
+ }
+ }
fmt.Println(color.GreenString("Build succeeded for %s in %s", mode, timecost))
},
diff --git a/cmd/sui/watch.go b/cmd/sui/watch.go
index 2b738309..c599d3e6 100644
--- a/cmd/sui/watch.go
+++ b/cmd/sui/watch.go
@@ -98,11 +98,17 @@ var WatchCmd = &cobra.Command{
// Timecost
start := time.Now()
- err = tmpl.Build(&core.BuildOption{SSR: true, AssetRoot: assetRoot})
+ warnings, err := tmpl.Build(&core.BuildOption{SSR: true, AssetRoot: assetRoot})
if err != nil {
fmt.Fprint(os.Stderr, color.RedString(fmt.Sprintf("Failed: %s\n", err.Error())))
return
}
+
+ if len(warnings) > 0 {
+ for _, warning := range warnings {
+ fmt.Fprintln(os.Stderr, color.YellowString(warning))
+ }
+ }
end := time.Now()
timecost := end.Sub(start).Truncate(time.Millisecond)
fmt.Printf(color.GreenString("Success (%s)\n"), timecost.String())
diff --git a/sui/api/compile_test.go b/sui/api/compile_test.go
index 2434d1ec..02e9dccf 100644
--- a/sui/api/compile_test.go
+++ b/sui/api/compile_test.go
@@ -12,11 +12,12 @@ func TestCompile(t *testing.T) {
defer clean()
page := testPage(t)
- html, err := page.Compile(nil, &core.BuildOption{KeepPageTag: false})
+ html, warnings, err := page.Compile(nil, &core.BuildOption{KeepPageTag: false})
if err != nil {
t.Fatalf("Compile error: %v", err)
}
assert.Contains(t, html, `The basic test cases`)
+ assert.Len(t, warnings, 0)
}
func testPage(t *testing.T) *core.Page {
diff --git a/sui/api/process.go b/sui/api/process.go
index 56c7639b..ab572a3c 100644
--- a/sui/api/process.go
+++ b/sui/api/process.go
@@ -963,11 +963,14 @@ func BuildAll(process *process.Process) interface{} {
exception.New(err.Error(), 500).Throw()
}
- err = tmpl.Build(&core.BuildOption{SSR: ssr, AssetRoot: assetRoot, Data: data})
+ warnings, err := tmpl.Build(&core.BuildOption{SSR: ssr, AssetRoot: assetRoot, Data: data})
if err != nil {
exception.New(err.Error(), 500).Throw()
}
+ if warnings != nil && len(warnings) > 0 {
+ return warnings
+ }
return nil
}
@@ -1004,10 +1007,13 @@ func BuildPage(process *process.Process) interface{} {
}
data := process.ArgsMap(5, map[string]interface{}{})
- err = page.Build(nil, &core.BuildOption{SSR: ssr, AssetRoot: assetRoot, Data: data})
+ warnings, err := page.Build(nil, &core.BuildOption{SSR: ssr, AssetRoot: assetRoot, Data: data})
if err != nil {
exception.New(err.Error(), 500).Throw()
}
+ if warnings != nil && len(warnings) > 0 {
+ return warnings
+ }
return nil
}
diff --git a/sui/api/sui_test.go b/sui/api/sui_test.go
index aba20f8b..24cea679 100644
--- a/sui/api/sui_test.go
+++ b/sui/api/sui_test.go
@@ -37,10 +37,11 @@ func prepare(t *testing.T) {
t.Fatal(err)
}
- err = advanced.Build(&core.BuildOption{SSR: true, AssetRoot: "/unit-test/assets"})
+ warnings, err := advanced.Build(&core.BuildOption{SSR: true, AssetRoot: "/unit-test/assets"})
if err != nil {
t.Fatal(err)
}
+ assert.Len(t, warnings, 0)
}
func clean() {
diff --git a/sui/core/build.go b/sui/core/build.go
index 68c45886..372108d1 100644
--- a/sui/core/build.go
+++ b/sui/core/build.go
@@ -9,7 +9,6 @@ import (
"github.com/PuerkitoBio/goquery"
"github.com/fatih/color"
jsoniter "github.com/json-iterator/go"
- "github.com/yaoapp/kun/log"
"golang.org/x/net/html"
)
@@ -54,10 +53,13 @@ func (page *Page) Build(ctx *BuildContext, option *BuildOption) (*goquery.Docume
}
doc.Find("body").SetAttr("s:ns", namespace)
- err = page.buildComponents(doc, ctx, option)
+ warnings, err := page.buildComponents(doc, ctx, option)
if err != nil {
return nil, ctx.warnings, err
}
+ if warnings != nil && len(warnings) > 0 {
+ ctx.warnings = append(ctx.warnings, warnings...)
+ }
// Scripts
scripts, err := page.BuildScripts(ctx, option, "__page", namespace)
@@ -127,8 +129,13 @@ func (page *Page) BuildAsComponent(sel *goquery.Selection, ctx *BuildContext, op
}
body := doc.Selection.Find("body")
- if body.Length() > 1 {
- body.SetHtml("
" + html + "
")
+
+ if body.Children().Length() == 0 {
+ return "", fmt.Errorf("page %s as component should have one root element", page.Route)
+ }
+
+ if body.Children().Length() > 1 {
+ return "", fmt.Errorf("page %s as component should have only one root element", page.Route)
}
// Scripts
@@ -241,16 +248,17 @@ func (page *Page) copyProps(ctx *BuildContext, from *goquery.Selection, to *goqu
return nil
}
-func (page *Page) buildComponents(doc *goquery.Document, ctx *BuildContext, option *BuildOption) error {
+func (page *Page) buildComponents(doc *goquery.Document, ctx *BuildContext, option *BuildOption) ([]string, error) {
+ warnings := []string{}
sui := SUIs[page.SuiID]
if sui == nil {
- return fmt.Errorf("SUI %s not found", page.SuiID)
+ return warnings, fmt.Errorf("SUI %s not found", page.SuiID)
}
public := sui.GetPublic()
tmpl, err := sui.GetTemplate(page.TemplateID)
if err != nil {
- return err
+ return warnings, err
}
doc.Find("*").Each(func(i int, sel *goquery.Selection) {
@@ -279,15 +287,17 @@ func (page *Page) buildComponents(doc *goquery.Document, ctx *BuildContext, opti
sel.SetAttr("parsed", "true")
ipage, err := tmpl.Page(name)
if err != nil {
+ message := err.Error()
+ warnings = append(warnings, message)
setError(sel, err)
- log.Warn("Page %s/%s/%s: %s", page.SuiID, page.TemplateID, page.Route, err.Error())
return
}
err = ipage.Load()
if err != nil {
+ message := err.Error()
+ warnings = append(warnings, message)
setError(sel, err)
- log.Warn("Page %s/%s/%s: %s", page.SuiID, page.TemplateID, page.Route, err.Error())
return
}
@@ -295,14 +305,14 @@ func (page *Page) buildComponents(doc *goquery.Document, ctx *BuildContext, opti
component.parent = page
_, err = component.BuildAsComponent(sel, ctx, option)
if err != nil {
+ message := err.Error()
+ warnings = append(warnings, message)
setError(sel, err)
- log.Warn("Page %s/%s/%s: %s", page.SuiID, page.TemplateID, page.Route, err.Error())
return
}
- return
})
- return err
+ return warnings, nil
}
// BuildStyles build the styles for the page
diff --git a/sui/core/compile.go b/sui/core/compile.go
index 5feebe7c..6ab387c1 100644
--- a/sui/core/compile.go
+++ b/sui/core/compile.go
@@ -19,11 +19,11 @@ var importAssetsRe = regexp.MustCompile(`import\s*\t*\n*\s*['"]@assets\/([^'"]+)
var AssetsRe = regexp.MustCompile(`[` + quoteRe + `]@assets\/([^` + quoteRe + `]+)[` + quoteRe + `]`) // '@assets/foo.js' or "@assets/foo.js" or `@assets/foo`
// Compile the page
-func (page *Page) Compile(ctx *BuildContext, option *BuildOption) (string, error) {
+func (page *Page) Compile(ctx *BuildContext, option *BuildOption) (string, []string, error) {
doc, warnings, err := page.Build(ctx, option)
if err != nil {
- return "", err
+ return "", warnings, err
}
if warnings != nil && len(warnings) > 0 {
@@ -88,22 +88,22 @@ func (page *Page) Compile(ctx *BuildContext, option *BuildOption) (string, error
page.ReplaceDocument(doc)
html, err := doc.Html()
if err != nil {
- return "", err
+ return "", warnings, err
}
// @todo: Minify the html
- return html, nil
+ return html, warnings, nil
}
// CompileAsComponent compile the page as component
-func (page *Page) CompileAsComponent(ctx *BuildContext, option *BuildOption) (string, error) {
+func (page *Page) CompileAsComponent(ctx *BuildContext, option *BuildOption) (string, []string, error) {
opt := *option
opt.IgnoreDocument = true
opt.WithWrapper = true
doc, warnings, err := page.Build(ctx, &opt)
if err != nil {
- return "", err
+ return "", warnings, err
}
if warnings != nil && len(warnings) > 0 {
@@ -115,31 +115,33 @@ func (page *Page) CompileAsComponent(ctx *BuildContext, option *BuildOption) (st
body := doc.Find("body")
rawScripts, err := jsoniter.MarshalToString(ctx.scripts)
if err != nil {
- return "", err
+ return "", warnings, err
}
rawStyles, err := jsoniter.MarshalToString(ctx.styles)
if err != nil {
- return "", err
+ return "", warnings, err
}
rawOption, err := jsoniter.MarshalToString(option)
if err != nil {
- return "", err
+ return "", warnings, err
}
if body.Children().Length() == 0 {
- return "", fmt.Errorf("page %s as component should have one root element", page.Route)
+ return "", warnings, fmt.Errorf("page %s as component should have one root element", page.Route)
}
if body.Children().Length() > 1 {
- return "", fmt.Errorf("page %s as component should have only one root element", page.Route)
+ return "", warnings, fmt.Errorf("page %s as component should have only one root element", page.Route)
}
body.Children().First().AppendHtml(fmt.Sprintf(``+"\n", rawScripts))
body.Children().First().AppendHtml(fmt.Sprintf(``+"\n", rawStyles))
body.Children().First().AppendHtml(fmt.Sprintf(``+"\n", rawOption))
- return body.Html()
+
+ html, err := body.Html()
+ return html, warnings, err
}
// CompileJS compile the javascript
diff --git a/sui/core/interfaces.go b/sui/core/interfaces.go
index 795869e3..2f54d8d4 100644
--- a/sui/core/interfaces.go
+++ b/sui/core/interfaces.go
@@ -58,7 +58,7 @@ type ITemplate interface {
MediaSearch(query url.Values, page int, pageSize int) (MediaSearchResult, error)
- Build(option *BuildOption) error
+ Build(option *BuildOption) ([]string, error)
SyncAssets(option *BuildOption) error
SyncAssetFile(file string, option *BuildOption) error
GetRoot() string
@@ -92,8 +92,8 @@ type IPage interface {
AssetScript() (*Asset, error)
AssetStyle() (*Asset, error)
- Build(globalCtx *GlobalBuildContext, option *BuildOption) error
- BuildAsComponent(globalCtx *GlobalBuildContext, option *BuildOption) error
+ Build(globalCtx *GlobalBuildContext, option *BuildOption) ([]string, error)
+ BuildAsComponent(globalCtx *GlobalBuildContext, option *BuildOption) ([]string, error)
}
// IBlock is the interface for the block
diff --git a/sui/storages/local/build.go b/sui/storages/local/build.go
index f1d739e0..abd7d892 100644
--- a/sui/storages/local/build.go
+++ b/sui/storages/local/build.go
@@ -14,8 +14,9 @@ import (
)
// Build the template
-func (tmpl *Template) Build(option *core.BuildOption) error {
+func (tmpl *Template) Build(option *core.BuildOption) ([]string, error) {
var err error
+ warnings := []string{}
defer func() {
if option.ExecScripts {
tmpl.ExecBuildCompleteScripts()
@@ -32,12 +33,12 @@ func (tmpl *Template) Build(option *core.BuildOption) error {
}
}
if len(scriptsErrorMessages) > 0 {
- return fmt.Errorf("Build scripts error: %s", strings.Join(scriptsErrorMessages, ";\n"))
+ return warnings, fmt.Errorf("Build scripts error: %s", strings.Join(scriptsErrorMessages, ";\n"))
}
err = tmpl.Reload()
if err != nil {
- return err
+ return warnings, err
}
}
@@ -53,14 +54,14 @@ func (tmpl *Template) Build(option *core.BuildOption) error {
// Sync the assets
if err = tmpl.SyncAssets(option); err != nil {
- return err
+ return warnings, err
}
// Build all pages
ctx := core.NewGlobalBuildContext()
pages, err := tmpl.Pages()
if err != nil {
- return err
+ return warnings, err
}
// loaed pages
@@ -68,20 +69,25 @@ func (tmpl *Template) Build(option *core.BuildOption) error {
for _, page := range pages {
err := page.Load()
if err != nil {
- return err
+ return warnings, err
}
- err = page.Build(ctx, option)
+ messages, err := page.Build(ctx, option)
if err != nil {
- return err
+ return warnings, err
}
+
+ if len(messages) > 0 {
+ warnings = append(warnings, messages...)
+ }
+
tmpl.loaded[page.Get().Route] = page
}
// Build jit components for the global -> .sui.lib
jitComponents, err := tmpl.GlobRoutes(ctx.GetJitComponents(), true)
if err != nil {
- return err
+ return warnings, err
}
for _, route := range jitComponents {
@@ -90,14 +96,18 @@ func (tmpl *Template) Build(option *core.BuildOption) error {
err = multierror.Append(fmt.Errorf("The page %s is not loaded", route))
continue
}
- err = page.BuildAsComponent(ctx, option)
+
+ messages, err := page.BuildAsComponent(ctx, option)
if err != nil {
err = multierror.Append(err)
}
+ if len(messages) > 0 {
+ warnings = append(warnings, messages...)
+ }
}
if err != nil {
- return err
+ return warnings, err
}
// Execute the build after hook
@@ -110,11 +120,11 @@ func (tmpl *Template) Build(option *core.BuildOption) error {
}
}
if len(scriptsErrorMessages) > 0 {
- return fmt.Errorf("Build scripts error: %s", strings.Join(scriptsErrorMessages, ";\n"))
+ return warnings, fmt.Errorf("Build scripts error: %s", strings.Join(scriptsErrorMessages, ";\n"))
}
}
- return err
+ return warnings, err
}
// SyncAssetFile sync the assets
@@ -171,7 +181,7 @@ func (tmpl *Template) SyncAssets(option *core.BuildOption) error {
}
// Build is the struct for the public
-func (page *Page) Build(globalCtx *core.GlobalBuildContext, option *core.BuildOption) error {
+func (page *Page) Build(globalCtx *core.GlobalBuildContext, option *core.BuildOption) ([]string, error) {
ctx := core.NewBuildContext(globalCtx)
if option.AssetRoot == "" {
@@ -183,28 +193,28 @@ func (page *Page) Build(globalCtx *core.GlobalBuildContext, option *core.BuildOp
option.AssetRoot = filepath.Join(root, "assets")
}
- html, err := page.Page.Compile(ctx, option)
+ html, warnings, err := page.Page.Compile(ctx, option)
if err != nil {
- return err
+ return warnings, err
}
// Save the html
err = page.writeHTML([]byte(html), option.Data)
if err != nil {
- return err
+ return warnings, err
}
// Save the locale files
err = page.writeLocaleFiles(option.Data)
if err != nil {
- return err
+ return warnings, err
}
// Jit Components
if globalCtx == nil {
jitComponents, err := page.tmpl.GlobRoutes(ctx.GetJitComponents(), true)
if err != nil {
- return err
+ return warnings, err
}
for _, route := range jitComponents {
@@ -218,20 +228,24 @@ func (page *Page) Build(globalCtx *core.GlobalBuildContext, option *core.BuildOp
}
}
- err = p.BuildAsComponent(globalCtx, option)
+ messages, err := p.BuildAsComponent(globalCtx, option)
if err != nil {
err = multierror.Append(err)
}
+ if len(messages) > 0 {
+ warnings = append(warnings, messages...)
+ }
}
}
- return err
+ return warnings, err
}
// BuildAsComponent build the page as component
-func (page *Page) BuildAsComponent(globalCtx *core.GlobalBuildContext, option *core.BuildOption) error {
+func (page *Page) BuildAsComponent(globalCtx *core.GlobalBuildContext, option *core.BuildOption) ([]string, error) {
+ warnings := []string{}
ctx := core.NewBuildContext(globalCtx)
if option.AssetRoot == "" {
root, err := page.tmpl.local.DSL.PublicRoot(option.Data)
@@ -242,28 +256,32 @@ func (page *Page) BuildAsComponent(globalCtx *core.GlobalBuildContext, option *c
option.AssetRoot = filepath.Join(root, "assets")
}
- html, err := page.Page.CompileAsComponent(ctx, option)
+ html, messages, err := page.Page.CompileAsComponent(ctx, option)
if err != nil {
- return err
+ return warnings, err
+ }
+
+ if len(messages) > 0 {
+ warnings = append(warnings, messages...)
}
// Save the html
err = page.writeJitHTML([]byte(html), option.Data)
if err != nil {
- return err
+ return warnings, err
}
// Save the locale files
err = page.writeLocaleFiles(option.Data)
if err != nil {
- return err
+ return warnings, err
}
// Jit Components
if globalCtx == nil {
jitComponents, err := page.tmpl.GlobRoutes(ctx.GetJitComponents(), true)
if err != nil {
- return err
+ return warnings, err
}
for _, route := range jitComponents {
@@ -277,14 +295,18 @@ func (page *Page) BuildAsComponent(globalCtx *core.GlobalBuildContext, option *c
}
}
- err = p.BuildAsComponent(globalCtx, option)
+ messages, err := p.BuildAsComponent(globalCtx, option)
if err != nil {
err = multierror.Append(err)
}
+
+ if len(messages) > 0 {
+ warnings = append(warnings, messages...)
+ }
}
}
- return err
+ return warnings, 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 c2d939f3..31f7a0ac 100644
--- a/sui/storages/local/build_test.go
+++ b/sui/storages/local/build_test.go
@@ -29,7 +29,7 @@ func TestTemplateBuild(t *testing.T) {
t.Fatalf("RemoveAll error: %v", err)
}
- err = tmpl.Build(&core.BuildOption{SSR: true, ExecScripts: true})
+ warnings, err := tmpl.Build(&core.BuildOption{SSR: true, ExecScripts: true})
if err != nil {
t.Fatalf("Components error: %v", err)
}
@@ -48,6 +48,7 @@ func TestTemplateBuild(t *testing.T) {
assert.Contains(t, string(content), `