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/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 6673c393..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,178 +15,10 @@ 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))
}
-// 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..469c3dc0 100644
--- a/sui/storages/local/template_test.go
+++ b/sui/storages/local/template_test.go
@@ -1,138 +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")
-}
-
-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
}