From 42fa2e140a2dcf98dd1816c760f03b55c046bc12 Mon Sep 17 00:00:00 2001 From: Max Date: Mon, 25 Sep 2023 14:05:58 +0800 Subject: [PATCH 1/2] [add] Page Builer Component (30%) --- sui/core/component.go | 58 ++++++++++++ sui/core/types.go | 6 +- sui/storages/local/block.go | 94 +++++++++++++++++++ sui/storages/local/block_test.go | 83 +++++++++++++++++ sui/storages/local/component.go | 134 +++++++++++++++++++++++++-- sui/storages/local/component_test.go | 83 +++++++++++++++++ sui/storages/local/template.go | 100 -------------------- sui/storages/local/template_test.go | 76 --------------- sui/storages/local/types.go | 1 + 9 files changed, 449 insertions(+), 186 deletions(-) create mode 100644 sui/core/component.go create mode 100644 sui/storages/local/block_test.go create mode 100644 sui/storages/local/component_test.go diff --git a/sui/core/component.go b/sui/core/component.go new file mode 100644 index 00000000..4f04f93d --- /dev/null +++ b/sui/core/component.go @@ -0,0 +1,58 @@ +package core + +import ( + "fmt" + "strings" + + "github.com/evanw/esbuild/pkg/api" + "github.com/yaoapp/gou/runtime/transform" +) + +// Compile compile the component +func (component *Component) Compile() (string, error) { + + // Typescript is the default language + // Typescript + if component.Codes.TS.Code != "" { + varName := strings.Replace(component.ID, "-", "_", -1) + ts := strings.Replace(component.Codes.TS.Code, "export default", fmt.Sprintf("window.component__%s =", varName), 1) + if component.Codes.HTML.Code != "" && !strings.Contains(component.Codes.TS.Code, "content:") { + html := strings.ReplaceAll(component.Codes.HTML.Code, "`", "\\`") + ts = strings.Replace(ts, "defaults: {", "defaults: {\n components: `"+html+"`,", 1) + + } + + js, err := transform.TypeScript(ts, api.TransformOptions{ + Target: api.ESNext, + MinifyWhitespace: true, + MinifyIdentifiers: true, + MinifySyntax: true, + }) + + if err != nil { + return "", err + } + component.Compiled = js + return js, nil + } + + // Javascript + if component.Codes.JS.Code == "" { + return "", fmt.Errorf("Block %s has no JS code", component.ID) + } + + varName := strings.Replace(component.ID, "-", "_", -1) + js := strings.Replace(component.Codes.JS.Code, "export default", fmt.Sprintf("window.component__%s =", varName), 1) + if component.Codes.HTML.Code != "" && !strings.Contains(component.Codes.JS.Code, "content:") { + html := strings.ReplaceAll(component.Codes.HTML.Code, "`", "\\`") + js = strings.Replace(js, "defaults: {", "defaults: {\n components: `"+html+"`,", 1) + } + + minified, err := transform.MinifyJS(js) + if err != nil { + return "", err + } + + component.Compiled = minified + return minified, nil +} diff --git a/sui/core/types.go b/sui/core/types.go index b5993cc6..3313fcb3 100644 --- a/sui/core/types.go +++ b/sui/core/types.go @@ -25,8 +25,10 @@ type Page struct { // Component is the struct for the component type Component struct { - templage *Template - name string + ID string `json:"id"` + Name string `json:"name,omitempty"` + Compiled string `json:"-"` + Codes SourceCodes `json:"-"` } // Block is the struct for the block diff --git a/sui/storages/local/block.go b/sui/storages/local/block.go index 635ca9d7..9b87410f 100644 --- a/sui/storages/local/block.go +++ b/sui/storages/local/block.go @@ -1,9 +1,69 @@ package local import ( + "fmt" "path/filepath" + + "github.com/yaoapp/kun/log" + "github.com/yaoapp/yao/sui/core" ) +// Blocks get the blocks +func (tmpl *Template) Blocks() ([]core.IBlock, error) { + path := filepath.Join(tmpl.Root, "__blocks") + + blocks := []core.IBlock{} + if exist, _ := tmpl.local.fs.Exists(path); !exist { + return blocks, nil + } + + dirs, err := tmpl.local.fs.ReadDir(path, false) + if err != nil { + return nil, err + } + + for _, dir := range dirs { + if !tmpl.local.fs.IsDir(dir) { + continue + } + + block, err := tmpl.getBlockFrom(dir) + if err != nil { + log.Error("Get block error: %v", err) + continue + } + + blocks = append(blocks, block) + } + + return blocks, nil +} + +// Block get the block +func (tmpl *Template) Block(id string) (core.IBlock, error) { + path := filepath.Join(tmpl.Root, "__blocks", id) + if exist, _ := tmpl.local.fs.Exists(path); !exist { + return nil, fmt.Errorf("Block %s not found", id) + } + + block, err := tmpl.getBlockFrom(path) + if err != nil { + return nil, err + } + + err = block.Load() + if err != nil { + return nil, err + } + + _, err = block.Compile() + if err != nil { + return nil, err + } + + return block, nil +} + // Load get the block from the storage func (block *Block) Load() error { @@ -38,3 +98,37 @@ func (block *Block) Load() error { return nil } + +func (tmpl *Template) getBlockFrom(path string) (core.IBlock, error) { + id := tmpl.getBlockID(path) + return tmpl.getBlock(id) +} + +func (tmpl *Template) getBlock(id string) (core.IBlock, error) { + + path := filepath.Join(tmpl.Root, "__blocks", id) + if !tmpl.local.fs.IsDir(path) { + return nil, fmt.Errorf("Block %s not found", id) + } + + jsFile := filepath.Join("/", id, fmt.Sprintf("%s.js", id)) + tsFile := filepath.Join("/", id, fmt.Sprintf("%s.ts", id)) + htmlFile := filepath.Join("/", id, fmt.Sprintf("%s.html", id)) + block := &Block{ + tmpl: tmpl, + Block: &core.Block{ + ID: id, + Codes: core.SourceCodes{ + HTML: core.Source{File: htmlFile}, + JS: core.Source{File: jsFile}, + TS: core.Source{File: tsFile}, + }, + }, + } + + return block, nil +} + +func (tmpl *Template) getBlockID(path string) string { + return filepath.Base(path) +} diff --git a/sui/storages/local/block_test.go b/sui/storages/local/block_test.go new file mode 100644 index 00000000..ea3027fd --- /dev/null +++ b/sui/storages/local/block_test.go @@ -0,0 +1,83 @@ +package local + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestTemplateBlocks(t *testing.T) { + tests := prepare(t) + defer clean() + + tmpl, err := tests.Demo.GetTemplate("tech-blue") + if err != nil { + t.Fatalf("GetTemplate error: %v", err) + } + + blocks, err := tmpl.Blocks() + if err != nil { + t.Fatalf("Blocks error: %v", err) + } + + if len(blocks) < 3 { + t.Fatalf("Blocks error: %v", len(blocks)) + } + + assert.Equal(t, "ColumnsTwo", blocks[0].(*Block).ID) + assert.Equal(t, "/ColumnsTwo/ColumnsTwo.html", blocks[0].(*Block).Codes.HTML.File) + assert.Equal(t, "/ColumnsTwo/ColumnsTwo.js", blocks[0].(*Block).Codes.JS.File) + assert.Equal(t, "/ColumnsTwo/ColumnsTwo.ts", blocks[0].(*Block).Codes.TS.File) + + assert.Equal(t, "Hero", blocks[1].(*Block).ID) + assert.Equal(t, "/Hero/Hero.html", blocks[1].(*Block).Codes.HTML.File) + assert.Equal(t, "/Hero/Hero.js", blocks[1].(*Block).Codes.JS.File) + assert.Equal(t, "/Hero/Hero.ts", blocks[1].(*Block).Codes.TS.File) + + assert.Equal(t, "Section", blocks[2].(*Block).ID) + assert.Equal(t, "/Section/Section.html", blocks[2].(*Block).Codes.HTML.File) + assert.Equal(t, "/Section/Section.js", blocks[2].(*Block).Codes.JS.File) + assert.Equal(t, "/Section/Section.ts", blocks[2].(*Block).Codes.TS.File) +} + +func TestTemplateBlockJS(t *testing.T) { + tests := prepare(t) + defer clean() + + tmpl, err := tests.Demo.GetTemplate("tech-blue") + if err != nil { + t.Fatalf("GetTemplate error: %v", err) + } + + block, err := tmpl.Block("ColumnsTwo") + if err != nil { + t.Fatalf("Blocks error: %v", err) + } + + assert.Equal(t, "ColumnsTwo", block.(*Block).ID) + assert.NotEmpty(t, block.(*Block).Codes.HTML.Code) + assert.NotEmpty(t, block.(*Block).Codes.JS.Code) + assert.Contains(t, block.(*Block).Compiled, "window.block__ColumnsTwo") + assert.Contains(t, block.(*Block).Compiled, `
`) +} diff --git a/sui/storages/local/component.go b/sui/storages/local/component.go index f74fd61a..e55e5b3f 100644 --- a/sui/storages/local/component.go +++ b/sui/storages/local/component.go @@ -1,16 +1,134 @@ package local -// NewComponent create a new local component -func NewComponent(file string) (*Component, error) { - return nil, nil +import ( + "fmt" + "path/filepath" + + "github.com/yaoapp/kun/log" + "github.com/yaoapp/yao/sui/core" +) + +// Components get the components +func (tmpl *Template) Components() ([]core.IComponent, error) { + + path := filepath.Join(tmpl.Root, "__components") + components := []core.IComponent{} + if exist, _ := tmpl.local.fs.Exists(path); !exist { + return components, nil + } + + dirs, err := tmpl.local.fs.ReadDir(path, false) + if err != nil { + return nil, err + } + + for _, dir := range dirs { + if !tmpl.local.fs.IsDir(dir) { + continue + } + + block, err := tmpl.getComponentFrom(dir) + if err != nil { + log.Error("Get block error: %v", err) + continue + } + + components = append(components, block) + } + + return components, nil } -// Get get the component -func (comp *Component) Get() error { +// Component get the component +func (tmpl *Template) Component(id string) (core.IComponent, error) { + + path := filepath.Join(tmpl.Root, "__components", id) + if exist, _ := tmpl.local.fs.Exists(path); !exist { + return nil, fmt.Errorf("Block %s not found", id) + } + + component, err := tmpl.getComponentFrom(path) + if err != nil { + return nil, err + } + + err = component.Load() + if err != nil { + return nil, err + } + + _, err = component.Compile() + if err != nil { + return nil, err + } + + return component, nil +} + +// Load get the component from the storage +func (component *Component) Load() error { + + root := filepath.Join(component.tmpl.Root, "__components") + + // Type script is the default language + tsFile := filepath.Join(root, component.Codes.TS.File) + if exist, _ := component.tmpl.local.fs.Exists(tsFile); exist { + tsCode, err := component.tmpl.local.fs.ReadFile(tsFile) + if err != nil { + return err + } + component.Codes.TS.Code = string(tsCode) + + } else { + jsFile := filepath.Join(root, component.Codes.JS.File) + jsCode, err := component.tmpl.local.fs.ReadFile(jsFile) + if err != nil { + return err + } + component.Codes.JS.Code = string(jsCode) + } + + htmlFile := filepath.Join(root, component.Codes.HTML.File) + if exist, _ := component.tmpl.local.fs.Exists(htmlFile); exist { + htmlCode, err := component.tmpl.local.fs.ReadFile(htmlFile) + if err != nil { + return err + } + component.Codes.HTML.Code = string(htmlCode) + } + return nil } -// Save save the component -func (comp *Component) Save() error { - return nil +func (tmpl *Template) getComponentFrom(path string) (core.IComponent, error) { + id := tmpl.getComponentID(path) + return tmpl.getComponent(id) +} + +func (tmpl *Template) getComponent(id string) (core.IComponent, error) { + + path := filepath.Join(tmpl.Root, "__components", id) + if !tmpl.local.fs.IsDir(path) { + return nil, fmt.Errorf("Component %s not found", id) + } + + jsFile := filepath.Join("/", id, fmt.Sprintf("%s.js", id)) + tsFile := filepath.Join("/", id, fmt.Sprintf("%s.ts", id)) + htmlFile := filepath.Join("/", id, fmt.Sprintf("%s.html", id)) + component := &Component{ + tmpl: tmpl, + Component: &core.Component{ + ID: id, + Codes: core.SourceCodes{ + HTML: core.Source{File: htmlFile}, + JS: core.Source{File: jsFile}, + TS: core.Source{File: tsFile}, + }, + }, + } + return component, nil +} + +func (tmpl *Template) getComponentID(path string) string { + return filepath.Base(path) } diff --git a/sui/storages/local/component_test.go b/sui/storages/local/component_test.go new file mode 100644 index 00000000..0e7a626d --- /dev/null +++ b/sui/storages/local/component_test.go @@ -0,0 +1,83 @@ +package local + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestTemplateComponents(t *testing.T) { + tests := prepare(t) + defer clean() + + tmpl, err := tests.Demo.GetTemplate("tech-blue") + if err != nil { + t.Fatalf("GetTemplate error: %v", err) + } + + components, err := tmpl.Components() + if err != nil { + t.Fatalf("Components error: %v", err) + } + + if len(components) < 2 { + t.Fatalf("Components error: %v", len(components)) + } + assert.Equal(t, "Box", components[0].(*Component).ID) + assert.Equal(t, "/Box/Box.html", components[0].(*Component).Codes.HTML.File) + assert.Equal(t, "/Box/Box.js", components[0].(*Component).Codes.JS.File) + assert.Equal(t, "/Box/Box.ts", components[0].(*Component).Codes.TS.File) + + assert.Equal(t, "Card", components[1].(*Component).ID) + assert.Equal(t, "/Card/Card.html", components[1].(*Component).Codes.HTML.File) + assert.Equal(t, "/Card/Card.js", components[1].(*Component).Codes.JS.File) + assert.Equal(t, "/Card/Card.ts", components[1].(*Component).Codes.TS.File) + + assert.Equal(t, "Nav", components[2].(*Component).ID) + assert.Equal(t, "/Nav/Nav.html", components[2].(*Component).Codes.HTML.File) + assert.Equal(t, "/Nav/Nav.js", components[2].(*Component).Codes.JS.File) + assert.Equal(t, "/Nav/Nav.ts", components[2].(*Component).Codes.TS.File) + +} + +func TestTemplateComponentJS(t *testing.T) { + tests := prepare(t) + defer clean() + + tmpl, err := tests.Demo.GetTemplate("tech-blue") + if err != nil { + t.Fatalf("GetTemplate error: %v", err) + } + + component, err := tmpl.Component("Card") + if err != nil { + t.Fatalf("Components error: %v", err) + } + + assert.Equal(t, "Card", component.(*Component).ID) + assert.NotEmpty(t, component.(*Component).Codes.HTML.Code) + assert.NotEmpty(t, component.(*Component).Codes.JS.Code) + assert.Contains(t, component.(*Component).Compiled, "window.component__Card") + assert.Contains(t, component.(*Component).Compiled, `

Card

`) +} + +func TestTemplateComponentTS(t *testing.T) { + tests := prepare(t) + defer clean() + + tmpl, err := tests.Demo.GetTemplate("tech-blue") + if err != nil { + t.Fatalf("GetTemplate error: %v", err) + } + + component, err := tmpl.Component("Box") + if err != nil { + t.Fatalf("Components error: %v", err) + } + + assert.Equal(t, "Box", component.(*Component).ID) + assert.NotEmpty(t, component.(*Component).Codes.HTML.Code) + assert.NotEmpty(t, component.(*Component).Codes.TS.Code) + assert.Contains(t, component.(*Component).Compiled, "window.component__Box") + assert.Contains(t, component.(*Component).Compiled, `
Box
`) +} diff --git a/sui/storages/local/template.go b/sui/storages/local/template.go index 6673c393..f819d238 100644 --- a/sui/storages/local/template.go +++ b/sui/storages/local/template.go @@ -91,106 +91,6 @@ func (tmpl *Template) getPageRoute(path string) string { return strings.TrimSuffix(path[len(tmpl.Root):], filepath.Ext(path)) } -// Blocks get the blocks -func (tmpl *Template) Blocks() ([]core.IBlock, error) { - path := filepath.Join(tmpl.Root, "__blocks") - - blocks := []core.IBlock{} - if exist, _ := tmpl.local.fs.Exists(path); !exist { - return blocks, nil - } - - dirs, err := tmpl.local.fs.ReadDir(path, false) - if err != nil { - return nil, err - } - - for _, dir := range dirs { - if !tmpl.local.fs.IsDir(dir) { - continue - } - - block, err := tmpl.getBlockFrom(dir) - if err != nil { - log.Error("Get block error: %v", err) - continue - } - - blocks = append(blocks, block) - } - - return blocks, nil -} - -// Block get the block -func (tmpl *Template) Block(id string) (core.IBlock, error) { - path := filepath.Join(tmpl.Root, "__blocks", id) - if exist, _ := tmpl.local.fs.Exists(path); !exist { - return nil, fmt.Errorf("Block %s not found", id) - } - - block, err := tmpl.getBlockFrom(path) - if err != nil { - return nil, err - } - - err = block.Load() - if err != nil { - return nil, err - } - - _, err = block.Compile() - if err != nil { - return nil, err - } - - return block, nil -} - -func (tmpl *Template) getBlockFrom(path string) (core.IBlock, error) { - id := tmpl.getBlockID(path) - return tmpl.getBlock(id) -} - -func (tmpl *Template) getBlock(id string) (core.IBlock, error) { - - path := filepath.Join(tmpl.Root, "__blocks", id) - if !tmpl.local.fs.IsDir(path) { - return nil, fmt.Errorf("Block %s not found", id) - } - - jsFile := filepath.Join("/", id, "main.js") - tsFile := filepath.Join("/", id, "main.ts") - htmlFile := filepath.Join("/", id, "main.html") - block := &Block{ - tmpl: tmpl, - Block: &core.Block{ - ID: id, - Codes: core.SourceCodes{ - HTML: core.Source{File: htmlFile}, - JS: core.Source{File: jsFile}, - TS: core.Source{File: tsFile}, - }, - }, - } - - return block, nil -} - -func (tmpl *Template) getBlockID(path string) string { - return filepath.Base(path) -} - -// Components get the components -func (tmpl *Template) Components() ([]core.IComponent, error) { - return nil, nil -} - -// Component get the component -func (tmpl *Template) Component(name string) (core.IComponent, error) { - return nil, nil -} - // Styles get the global styles func (tmpl *Template) Styles() []string { return nil diff --git a/sui/storages/local/template_test.go b/sui/storages/local/template_test.go index f82daa45..7666d884 100644 --- a/sui/storages/local/template_test.go +++ b/sui/storages/local/template_test.go @@ -60,79 +60,3 @@ func TestTemplatePage(t *testing.T) { _, err = tmpl.Page("/the/page/could/not/be/found") assert.Contains(t, err.Error(), "Page /the/page/could/not/be/found not found") } - -func TestTemplateBlocks(t *testing.T) { - tests := prepare(t) - defer clean() - - tmpl, err := tests.Demo.GetTemplate("tech-blue") - if err != nil { - t.Fatalf("GetTemplate error: %v", err) - } - - blocks, err := tmpl.Blocks() - if err != nil { - t.Fatalf("Blocks error: %v", err) - } - - if len(blocks) < 3 { - t.Fatalf("Blocks error: %v", len(blocks)) - } - - assert.Equal(t, "columns-two", blocks[0].(*Block).ID) - assert.Equal(t, "/columns-two/main.html", blocks[0].(*Block).Codes.HTML.File) - assert.Equal(t, "/columns-two/main.js", blocks[0].(*Block).Codes.JS.File) - assert.Equal(t, "/columns-two/main.ts", blocks[0].(*Block).Codes.TS.File) - - assert.Equal(t, "hero", blocks[1].(*Block).ID) - assert.Equal(t, "/hero/main.html", blocks[1].(*Block).Codes.HTML.File) - assert.Equal(t, "/hero/main.js", blocks[1].(*Block).Codes.JS.File) - assert.Equal(t, "/hero/main.ts", blocks[1].(*Block).Codes.TS.File) - - assert.Equal(t, "section", blocks[2].(*Block).ID) - assert.Equal(t, "/section/main.html", blocks[2].(*Block).Codes.HTML.File) - assert.Equal(t, "/section/main.js", blocks[2].(*Block).Codes.JS.File) - assert.Equal(t, "/section/main.ts", blocks[2].(*Block).Codes.TS.File) -} - -func TestTemplateBlockJS(t *testing.T) { - tests := prepare(t) - defer clean() - - tmpl, err := tests.Demo.GetTemplate("tech-blue") - if err != nil { - t.Fatalf("GetTemplate error: %v", err) - } - - block, err := tmpl.Block("columns-two") - if err != nil { - t.Fatalf("Blocks error: %v", err) - } - - assert.Equal(t, "columns-two", block.(*Block).ID) - assert.NotEmpty(t, block.(*Block).Codes.HTML.Code) - assert.NotEmpty(t, block.(*Block).Codes.JS.Code) - assert.Contains(t, block.(*Block).Compiled, "window.block__columns_two") - assert.Contains(t, block.(*Block).Compiled, `
`) -} diff --git a/sui/storages/local/types.go b/sui/storages/local/types.go index 7b8c07c0..794e2387 100644 --- a/sui/storages/local/types.go +++ b/sui/storages/local/types.go @@ -33,5 +33,6 @@ type Block struct { // Component is the struct for the local sui component type Component struct { + tmpl *Template *core.Component } From 5d6c7d32d6e4f17c496a07ba0eb809d4f7179937 Mon Sep 17 00:00:00 2001 From: Max Date: Mon, 25 Sep 2023 14:56:02 +0800 Subject: [PATCH 2/2] [add] page soruce structure --- sui/storages/local/local_test.go | 14 ++++-- sui/storages/local/page.go | 77 +++++++++++++++++++++++++++++ sui/storages/local/page_test.go | 62 +++++++++++++++++++++++ sui/storages/local/template.go | 72 --------------------------- sui/storages/local/template_test.go | 61 ----------------------- 5 files changed, 149 insertions(+), 137 deletions(-) create mode 100644 sui/storages/local/page_test.go diff --git a/sui/storages/local/local_test.go b/sui/storages/local/local_test.go index b641f258..fd166db5 100644 --- a/sui/storages/local/local_test.go +++ b/sui/storages/local/local_test.go @@ -18,15 +18,15 @@ func TestGetTemplates(t *testing.T) { t.Fatalf("GetTemplates error: %v", err) } - if len(dempTmpls) < 2 { + if len(dempTmpls) < 3 { t.Fatalf("The demo templates less than %v", len(dempTmpls)) } assert.Equal(t, "tech-blue", dempTmpls[0].(*Template).ID) - assert.Equal(t, "TECH-BLUE", dempTmpls[0].(*Template).Name) - assert.Equal(t, []string{}, dempTmpls[0].(*Template).Screenshots) + assert.Equal(t, "Tech Blue DEMO", dempTmpls[0].(*Template).Name) + assert.Equal(t, true, len(dempTmpls[1].(*Template).Screenshots) > 0) assert.Equal(t, 1, dempTmpls[0].(*Template).Version) - assert.Equal(t, "", dempTmpls[0].(*Template).Descrption) + assert.Equal(t, "Tech Blue DEMO", dempTmpls[0].(*Template).Descrption) assert.Equal(t, "website-ai", dempTmpls[1].(*Template).ID) assert.Equal(t, "Website DEMO", dempTmpls[1].(*Template).Name) @@ -34,6 +34,12 @@ func TestGetTemplates(t *testing.T) { assert.Equal(t, 2, dempTmpls[1].(*Template).Version) assert.Equal(t, "AI Website DEMO", dempTmpls[1].(*Template).Descrption) + assert.Equal(t, "wechat-web", dempTmpls[2].(*Template).ID) + assert.Equal(t, "WECHAT-WEB", dempTmpls[2].(*Template).Name) + assert.Equal(t, []string{}, dempTmpls[2].(*Template).Screenshots) + assert.Equal(t, 1, dempTmpls[2].(*Template).Version) + assert.Equal(t, "", dempTmpls[2].(*Template).Descrption) + } func TestGetTemplate(t *testing.T) { diff --git a/sui/storages/local/page.go b/sui/storages/local/page.go index 0c5772a6..023cc8ad 100644 --- a/sui/storages/local/page.go +++ b/sui/storages/local/page.go @@ -1,5 +1,82 @@ package local +import ( + "fmt" + "path/filepath" + "strings" + + "github.com/yaoapp/kun/log" + "github.com/yaoapp/yao/sui/core" +) + +// Pages get the pages +func (tmpl *Template) Pages() ([]core.IPage, error) { + + exts := []string{"*.sui", "*.html", "*.htm", "*.page"} + pages := []core.IPage{} + tmpl.local.fs.Walk(tmpl.Root, func(root, file string, isdir bool) error { + name := filepath.Base(file) + if isdir { + if strings.HasPrefix(name, "__") { + return filepath.SkipDir + } + return nil + } + + if strings.HasPrefix(name, "__") { + return nil + } + + page, err := tmpl.getPageFrom(file) + if err != nil { + log.Error("Get page error: %v", err) + return nil + } + + pages = append(pages, page) + return nil + }, exts...) + + return pages, nil +} + +// Page get the page +func (tmpl *Template) Page(route string) (core.IPage, error) { + path := filepath.Join(tmpl.Root, route) + exts := []string{".sui", ".html", ".htm", ".page"} + for _, ext := range exts { + file := fmt.Sprintf("%s%s", path, ext) + if exist, _ := tmpl.local.fs.Exists(file); exist { + return tmpl.getPageFrom(file) + } + } + return nil, fmt.Errorf("Page %s not found", route) +} + +func (tmpl *Template) getPageFrom(path string) (core.IPage, error) { + route := tmpl.getPageRoute(path) + return tmpl.getPage(route, path) +} + +func (tmpl *Template) getPage(route, file string) (core.IPage, error) { + root := filepath.Dir(file) + return &Page{ + tmpl: tmpl, + Page: &core.Page{ + Route: route, + Root: root, + Codes: core.SourceCodes{ + HTML: core.Source{File: fmt.Sprintf("%s%s", route, filepath.Ext(file))}, + CSS: core.Source{File: fmt.Sprintf("%s.css", route)}, + JS: core.Source{File: fmt.Sprintf("%s.js", route)}, + DATA: core.Source{File: fmt.Sprintf("%s.json", route)}, + TS: core.Source{File: fmt.Sprintf("%s.ts", route)}, + LESS: core.Source{File: fmt.Sprintf("%s.less", route)}, + }, + }, + }, nil +} + // Get get the page func (page *Page) Get() error { return nil diff --git a/sui/storages/local/page_test.go b/sui/storages/local/page_test.go new file mode 100644 index 00000000..7666d884 --- /dev/null +++ b/sui/storages/local/page_test.go @@ -0,0 +1,62 @@ +package local + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestTemplatePages(t *testing.T) { + tests := prepare(t) + defer clean() + + tmpl, err := tests.Demo.GetTemplate("website-ai") + if err != nil { + t.Fatalf("GetTemplate error: %v", err) + } + + pages, err := tmpl.Pages() + if err != nil { + t.Fatalf("Pages error: %v", err) + } + + if len(pages) < 1 { + t.Fatalf("Pages error: %v", len(pages)) + } + + assert.Equal(t, "/index", pages[0].(*Page).Route) + assert.Equal(t, "/templates/website-ai", pages[0].(*Page).Root) + assert.Equal(t, "/index.css", pages[0].(*Page).Codes.CSS.File) + assert.Equal(t, "/index.html", pages[0].(*Page).Codes.HTML.File) + assert.Equal(t, "/index.js", pages[0].(*Page).Codes.JS.File) + assert.Equal(t, "/index.less", pages[0].(*Page).Codes.LESS.File) + assert.Equal(t, "/index.ts", pages[0].(*Page).Codes.TS.File) + assert.Equal(t, "/index.json", pages[0].(*Page).Codes.DATA.File) +} + +func TestTemplatePage(t *testing.T) { + + tests := prepare(t) + defer clean() + + tmpl, err := tests.Demo.GetTemplate("website-ai") + if err != nil { + t.Fatalf("GetTemplate error: %v", err) + } + + page, err := tmpl.Page("/index") + if err != nil { + t.Fatalf("Page error: %v", err) + } + assert.Equal(t, "/index", page.(*Page).Route) + assert.Equal(t, "/templates/website-ai", page.(*Page).Root) + assert.Equal(t, "/index.css", page.(*Page).Codes.CSS.File) + assert.Equal(t, "/index.html", page.(*Page).Codes.HTML.File) + assert.Equal(t, "/index.js", page.(*Page).Codes.JS.File) + assert.Equal(t, "/index.less", page.(*Page).Codes.LESS.File) + assert.Equal(t, "/index.ts", page.(*Page).Codes.TS.File) + assert.Equal(t, "/index.json", page.(*Page).Codes.DATA.File) + + _, err = tmpl.Page("/the/page/could/not/be/found") + assert.Contains(t, err.Error(), "Page /the/page/could/not/be/found not found") +} diff --git a/sui/storages/local/template.go b/sui/storages/local/template.go index f819d238..e29dbfc1 100644 --- a/sui/storages/local/template.go +++ b/sui/storages/local/template.go @@ -1,12 +1,8 @@ package local import ( - "fmt" "path/filepath" "strings" - - "github.com/yaoapp/kun/log" - "github.com/yaoapp/yao/sui/core" ) // Get get the template @@ -19,74 +15,6 @@ func (tmpl *Template) Save() error { return nil } -// Pages get the pages -func (tmpl *Template) Pages() ([]core.IPage, error) { - - exts := []string{"*.sui", "*.html", "*.htm", "*.page"} - pages := []core.IPage{} - tmpl.local.fs.Walk(tmpl.Root, func(root, file string, isdir bool) error { - name := filepath.Base(file) - if isdir { - if strings.HasPrefix(name, "__") { - return filepath.SkipDir - } - return nil - } - - if strings.HasPrefix(name, "__") { - return nil - } - - page, err := tmpl.getPageFrom(file) - if err != nil { - log.Error("Get page error: %v", err) - return nil - } - - pages = append(pages, page) - return nil - }, exts...) - - return pages, nil -} - -// Page get the page -func (tmpl *Template) Page(route string) (core.IPage, error) { - path := filepath.Join(tmpl.Root, route) - exts := []string{".sui", ".html", ".htm", ".page"} - for _, ext := range exts { - file := fmt.Sprintf("%s%s", path, ext) - if exist, _ := tmpl.local.fs.Exists(file); exist { - return tmpl.getPageFrom(file) - } - } - return nil, fmt.Errorf("Page %s not found", route) -} - -func (tmpl *Template) getPageFrom(path string) (core.IPage, error) { - route := tmpl.getPageRoute(path) - return tmpl.getPage(route, path) -} - -func (tmpl *Template) getPage(route, file string) (core.IPage, error) { - root := filepath.Dir(file) - return &Page{ - tmpl: tmpl, - Page: &core.Page{ - Route: route, - Root: root, - Codes: core.SourceCodes{ - HTML: core.Source{File: fmt.Sprintf("%s%s", route, filepath.Ext(file))}, - CSS: core.Source{File: fmt.Sprintf("%s.css", route)}, - JS: core.Source{File: fmt.Sprintf("%s.js", route)}, - DATA: core.Source{File: fmt.Sprintf("%s.json", route)}, - TS: core.Source{File: fmt.Sprintf("%s.ts", route)}, - LESS: core.Source{File: fmt.Sprintf("%s.less", route)}, - }, - }, - }, nil -} - func (tmpl *Template) getPageRoute(path string) string { return strings.TrimSuffix(path[len(tmpl.Root):], filepath.Ext(path)) } diff --git a/sui/storages/local/template_test.go b/sui/storages/local/template_test.go index 7666d884..469c3dc0 100644 --- a/sui/storages/local/template_test.go +++ b/sui/storages/local/template_test.go @@ -1,62 +1 @@ package local - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestTemplatePages(t *testing.T) { - tests := prepare(t) - defer clean() - - tmpl, err := tests.Demo.GetTemplate("website-ai") - if err != nil { - t.Fatalf("GetTemplate error: %v", err) - } - - pages, err := tmpl.Pages() - if err != nil { - t.Fatalf("Pages error: %v", err) - } - - if len(pages) < 1 { - t.Fatalf("Pages error: %v", len(pages)) - } - - assert.Equal(t, "/index", pages[0].(*Page).Route) - assert.Equal(t, "/templates/website-ai", pages[0].(*Page).Root) - assert.Equal(t, "/index.css", pages[0].(*Page).Codes.CSS.File) - assert.Equal(t, "/index.html", pages[0].(*Page).Codes.HTML.File) - assert.Equal(t, "/index.js", pages[0].(*Page).Codes.JS.File) - assert.Equal(t, "/index.less", pages[0].(*Page).Codes.LESS.File) - assert.Equal(t, "/index.ts", pages[0].(*Page).Codes.TS.File) - assert.Equal(t, "/index.json", pages[0].(*Page).Codes.DATA.File) -} - -func TestTemplatePage(t *testing.T) { - - tests := prepare(t) - defer clean() - - tmpl, err := tests.Demo.GetTemplate("website-ai") - if err != nil { - t.Fatalf("GetTemplate error: %v", err) - } - - page, err := tmpl.Page("/index") - if err != nil { - t.Fatalf("Page error: %v", err) - } - assert.Equal(t, "/index", page.(*Page).Route) - assert.Equal(t, "/templates/website-ai", page.(*Page).Root) - assert.Equal(t, "/index.css", page.(*Page).Codes.CSS.File) - assert.Equal(t, "/index.html", page.(*Page).Codes.HTML.File) - assert.Equal(t, "/index.js", page.(*Page).Codes.JS.File) - assert.Equal(t, "/index.less", page.(*Page).Codes.LESS.File) - assert.Equal(t, "/index.ts", page.(*Page).Codes.TS.File) - assert.Equal(t, "/index.json", page.(*Page).Codes.DATA.File) - - _, err = tmpl.Page("/the/page/could/not/be/found") - assert.Contains(t, err.Error(), "Page /the/page/could/not/be/found not found") -}